从 GcmListenerService 下载文件仅在某些时候有效
downloading file from GcmListenerService works only some of the time
我有一个 GcmListenerService,我知道每次发送消息时它都会接收消息,因为我将图像的名称记录到 SQLite 数据库中,然后应该在同一个 onMessageRecieved 处理程序中下载该数据库。
然而,它只有大约 75% 的时间下载图像,我无法弄清楚为什么它在下载时会失败。我什至设置了一个计数器,我试图在放弃之前下载图像 5 次。同样的应用程序 运行 在 10 种不同的设备上运行(有些设备与其他设备完全相同的硬件)并且它在某些设备上运行,但在其他设备上运行失败,再次出现故障,原因不明。
我最好的猜测是,当它失败时,它失败是因为设备是 "asleep" 或其他东西并且仍然可以接收推送通知,但无法访问处于该状态的网站?那是一个纯粹的假设,但我想不出其他什么会导致它有时随机不起作用。
我已经包含了来自 GcmListenerService 的一段代码,这就是问题所在。
@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);
}
}
这里要注意一点,当它确实失败时,outputstream 仍在 SD 卡上创建一个文件,它只是一个空文件。
有什么想法或建议吗?
TIA
它可能由于各种原因
而发生
Android Oreo has limitations 运行 服务在后台,因此您可能会在 O 设备上遇到此问题
Doze mode on Android Marshmallow 之后的版本可能会导致此问题,它会自行停止所有网络操作
- GcmListenerService 不适用于执行长运行 操作,您应该在其他工作人员服务 中执行繁重的工作,您可以对其进行更多控制
我建议您使用 JobsSchedulers or Firebase Dispatchers 来完成此任务,因为它将处理打瞌睡模式、后台服务限制、无网络情况等。
我有一个 GcmListenerService,我知道每次发送消息时它都会接收消息,因为我将图像的名称记录到 SQLite 数据库中,然后应该在同一个 onMessageRecieved 处理程序中下载该数据库。
然而,它只有大约 75% 的时间下载图像,我无法弄清楚为什么它在下载时会失败。我什至设置了一个计数器,我试图在放弃之前下载图像 5 次。同样的应用程序 运行 在 10 种不同的设备上运行(有些设备与其他设备完全相同的硬件)并且它在某些设备上运行,但在其他设备上运行失败,再次出现故障,原因不明。
我最好的猜测是,当它失败时,它失败是因为设备是 "asleep" 或其他东西并且仍然可以接收推送通知,但无法访问处于该状态的网站?那是一个纯粹的假设,但我想不出其他什么会导致它有时随机不起作用。
我已经包含了来自 GcmListenerService 的一段代码,这就是问题所在。
@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);
}
}
这里要注意一点,当它确实失败时,outputstream 仍在 SD 卡上创建一个文件,它只是一个空文件。
有什么想法或建议吗?
TIA
它可能由于各种原因
而发生Android Oreo has limitations 运行 服务在后台,因此您可能会在 O 设备上遇到此问题
Doze mode on Android Marshmallow 之后的版本可能会导致此问题,它会自行停止所有网络操作
- GcmListenerService 不适用于执行长运行 操作,您应该在其他工作人员服务 中执行繁重的工作,您可以对其进行更多控制
我建议您使用 JobsSchedulers or Firebase Dispatchers 来完成此任务,因为它将处理打瞌睡模式、后台服务限制、无网络情况等。