I have a GcmListenerService that I know is receiving messages every time they're sent because I log the name of an image to the SQLite database that is supposed to then be downloaded in the same onMessageRecieved handler.
It only downloads the image about 75% of the time however and I can not figure out a rhyme or reason as to why it fails when it does. I have even set up a counter and I'm trying to download the image 5 times before giving up. This same app is running on 10 different devices (some exactly the same hardware as others) and it works on some, not on others, again for no apparent reason on the failures.
my best guess is that when it fails, it's failing because the device is "asleep" or something and can still receive push notifications, but can't reach out to a web site in that state? that's a pure assumption, but I can't think of anything else that would cause this to randomly not work sometimes.
I've included a snippet of code from the GcmListenerService that is the problem.
@Override
public void onMessageReceived(String from, Bundle data) {
Gson gson = new Gson();
String message = data.getString("message");
PushNotificationMessageReceivedModel model = gson.fromJson(message, PushNotificationMessageReceivedModel.class);
if (model.messageType.equals("getimage")) {
DatabaseAdapter myDB = new DatabaseAdapter(getBaseContext());
myDB.Open();
myDB.InsertImage(model.messagePayload);
myDB.Close();
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL("http://www.mywebsite.com/UploadedImages/"+params[0]).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
}
FileOutputStream out = null;
try {
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/MyApp/"+params[0]);
mIcon11.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return Environment.getExternalStorageDirectory() + "/MyApp/"+params[0];
}
@Override
protected void onPostExecute(String path) {
try {
Bitmap noteIcon = null;
noteIcon = Utilities.ResizeBySampleSize(path, 300, 300);
//notification stuff
Notification.Builder mBuilder;
NotificationManager mNotificationManager;
Notification notification;
mBuilder = new Notification.Builder(getBaseContext())
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("something here")
.setContentText("something there")
.setOngoing(false)
.setAutoCancel(true)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setLargeIcon(noteIcon)
.setContentIntent(myPendingIntent);
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notification = mBuilder.build();
mNotificationManager.notify(notificationNumber, notification);
} catch (Exception e) {
}
}
}.execute(model.messagePayload);
}
}
one thing to note here, when it does fail, the outputstream is still creating a file on the SD card, it's just an empty file.
any ideas or suggestions here?
TIA
It can happen due to various reasons
Android Oreo has limitations on running services in background, so you may face this on O devices
Doze mode on Android Marshmallow onwards can cause this, it will stop all network operations itself
I will suggest you to use JobsSchedulers or Firebase Dispatchers for this task, as it will take care of Doze mode, background service limitations, no network scenarios etc.