【发布时间】:2018-05-03 09:29:04
【问题描述】:
我正在开发一个 android 应用程序,其主要用途是在设定的时间显示通知(某些特定的日历应用程序)。主要抱怨之一是用户不会(总是)收到通知,我束手无策。
我们在模拟器上针对 Android 4.4、6、7.0、7.1、8.0、8.1 对以下代码进行了内部测试,并使用了大约 10 台真实设备(6 到 8.1),所有设备都按时收到了通知。即使在重新启动后,通知也都按时收到了。
我们遇到的其中一件事情是三星设备上的 SecurityException(>500 个已注册警报),我们之前因取消不当而触发了该异常。看起来这不再是问题了。
那么,这些丢失通知的原因可能是什么?这是设备特定的设置,还是一个简单的错误?还是有其他因素在起作用?
这是我们正在使用的代码:
private void cancelAlarm(String notificationId, Class<? extends AbstractReceiver> receiverClass)
throws BroadcastException {
/*
* Create an intent that looks similar, to the one that was registered using add. Making sure the notification id in the action is the same. Now we can search for
* such an intent using the 'getService' method and cancel it.
*/
final Intent intent = new Intent(this.context, receiverClass);
intent.setAction(notificationId);
final PendingIntent pi = PendingIntent.getBroadcast(this.context, 0, intent, 0);
final AlarmManager am = getAlarmManager();
try {
am.cancel(pi);
} catch (Exception e) {
Log.e(this.getClass().getSimpleName(), e.getMessage());
throw new BroadcastException(e.getMessage());
}
}
private void addOrUpdateAlarm(...){
try {
cancelAlarm(notificationId, OurReceiver.class);
} catch (BroadcastException e) {
Log.e(AlarmHelper.class.getSimpleName(), "addOrUpdateAlarm: Can't cancel current alarm before reinserting.", e);
}
Intent intent = new Intent(this.context, receiverClass);
intent.setAction(notificationId);
// some intent.setExtra() calls.
PendingIntent sender = PendingIntent.getBroadcast(this.context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
/* Get the AlarmManager service */
final AlarmManager am = getAlarmManager();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
am.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}else{
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
}
然后在 OurReceiver 中创建一个通知通道:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotificationManager.createNotificationChannel(mChannel);
}
最后发送通知:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), intent, 0);
Notification n = new NotificationCompat.Builder(context, channel)
.setContentTitle(notificationTitle)
.setContentText(notificationSubText)
.setSmallIcon(R.drawable.logo)
.setContentIntent(pIntent)
.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
【问题讨论】:
-
检查无法接收通知的设备的注册令牌。它存在还是不存在??
-
嘿@FazalHussain,没有远程通知。都是本地的。
-
您是否在 Boot_Complete 操作清单中设置了 BroadcastReceiver?
-
addOrUpdateAlarm 方法何时被调用?
-
@AgonAvdijaj 是的。我们在自己的设备上收到通知这一事实应该支持这一点。
标签: android alarmmanager android-notifications