很长一段时间以来,我一直在努力处理复杂的本地通知。
我有一个活动列表。用户可以选择何时通知他/她:事件的同一天,事件将开始的前一天,事件将开始的前两天。他/她还可以设置他/她想要得到通知的时间。每次都有可能。他/她还只能通过不同类型的事件得到通知。
发生的事情是,它可以在除Samsung Galaxy Phones之外的所有设备上正常工作。用户告诉我,他们收到通知的时间恰好是一次(设置时),然后再也不会收到。
我几乎尝试了所有事情,但我的想法已用尽。三星似乎在通知方面存在一些问题,但适用于其他一些应用程序。那么他们的代码和我的代码有什么区别。
也许其他人知道此问题,可以为我提供帮助。这太神奇了!
这是我的代码:
public int setEventNotifications(List<Event> chosenEvents) {
SharedPreferences settings = context.getSharedPreferences(Constants.PREFS_EVENT_SETTINGS, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
ArrayList<PendingIntent> intentArray = new ArrayList<>();
// To cancel an existing pending intent you need to recreate the exact same and cancel it -__-
// So pending intents need to be stored in the database
deleteOldGarbagePendingIntents();
// get notification settings from shared prefs
int hours = 0;
int minutes = 0;
String time = settings.getString(Constants.PREFS_EVENT_TIME, "00:00");
String parts[] = time.split(":");
try {
hours = Integer.parseInt(parts[0]);
minutes = Integer.parseInt(parts[1]);
} catch (Exception e) {
Log.e(TAG, "Invalid time. Cannot be parsed: " + time);
}
String interval = settings.getString(Constants.PREFS_EVENT_INTERVAL, "");
String communeId = settings.getString(Constants.PREFS_EVENT_COMMUNE_ID, "");
String regionId = settings.getString(Constants.PREFS_EVENT_REGION_ID, "");
for (Event event : chosenEvents) {
// check if date is in the future
Intent intent = new Intent(context, AlarmGarbageReceiver.class);
intent.putExtra("request_code", Integer.parseInt(event.getId()));
intent.putExtra("event_type", event.getGarbageType().getType());
intent.putExtra("event_date", event.getPickupDateAsDate().getTime());
// calculate trigger time
long triggerTime = calculateTriggerTime(event.getPickupDateAsDate(), hours, minutes, interval);
Calendar alarmCalendar = Calendar.getInstance();
alarmCalendar.setTimeInMillis(triggerTime);
try {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, Integer.parseInt(event.getId()), intent, FLAG_UPDATE_CURRENT);
if (alarmManager != null) {
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);
} else {
Log.e(TAG, "Alarmmanager is null");
}
intentArray.add(pendingIntent);
// save intents in database
dbHelper.insertEventData(event.getId(), event.getEventType().getType(), String.valueOf(event.getPickupDateAsDate().getTime()), event.getLocation(), event.getEventType().getColor(), communeId, regionId);
} catch (SecurityException securityException) {
Log.e(TAG, "Security Exception");
securityException.printStackTrace();
} catch (Exception exception) {
Log.e(TAG, "Exception");
exception.printStackTrace();
}
}
return intentArray.size();
}
AlarmEventReceiver类:
public class AlarmEventReceiver extends BroadcastReceiver {
private static final String NOTIFICATION_CHANNEL_NAME = "xxx_events";
private static final String NOTIFICATION_CHANNEL_ID = "xxx_events_1";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getExtras() != null) {
Log.e(TAG, AlarmEventReceiver.class.getSimpleName() + " request code: " + intent.getExtras().getInt("request_code"));
}
int eventId = intent.getExtras().getInt("request_code");
String eventType = intent.getExtras().getString("event_type");
long pickupDate = intent.getExtras().getLong("event_date");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(pickupDate);
calendar.set(Calendar.HOUR, 6);
calendar.set(Calendar.MINUTE, 0);
long finalDate = calendar.getTimeInMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
Intent resultIntent = new Intent(context, EventCalendarActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(EventCalendarActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
if (notificationManager == null) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
if (notificationManager != null) {
notificationManager.createNotificationChannel(notificationChannel);
} else {
Log.e(TAG, "Notification Manager is NULL");
}
if (eventType != null) {
builder.setChannelId(NOTIFICATION_CHANNEL_ID)
.setDefaults(Notification.DEFAULT_ALL)
.setContentTitle("Erinnerung")
.setContentText(eventType)
.setWhen(finalDate)
.setContentIntent(resultPendingIntent)
.setAutoCancel(false)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
}
} else {
builder = new NotificationCompat.Builder(context);
builder.setContentTitle("Erinnerung")
.setDefaults(Notification.DEFAULT_ALL)
.setContentText(eventType)
.setWhen(finalDate)
.setContentIntent(resultPendingIntent)
.setAutoCancel(false)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
.setPriority(Notification.PRIORITY_DEFAULT);
}
Notification notification = builder.build();
if (notificationManager != null) {
notificationManager.notify(eventId, notification);
} else {
Log.e(TAG, "notificationManager is NULL");
}
}
}
我曾经有机会在三星手机上运行它,我想我还记得因为手机无法更新通知而引发了某种SecurityException。只能容纳500条通知,如果尝试对其进行更新,则不会删除旧的通知,而会创建新的通知。因此,您很快就会收到500个通知,这就是抛出SecurityException的时候。但是我再也找不到源了...
答案 0 :(得分:1)
我过去浏览过一个相关的问题,它发生在Galaxy Note上,尽管我不确定它是否会帮助。
mNotificationManager.cancel(notificationId);
mNotificationManager.notify(++notificationId, notification);
每次必须创建一个新通知时,请手动取消前一个通知,并每次都更新notificationID。
答案 1 :(得分:0)
它工作正常,已在Samsung Galaxy s7 edge
上进行了测试
fun showDownloadNotification() {
try {
// val selectedUri = Uri.parse(Environment.getExternalStorageState())
val notiIntent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)
notiIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
// startActivity(intent);
val pendingIntent: PendingIntent = PendingIntent.getActivity(baseActivity, 0, notiIntent, PendingIntent.FLAG_CANCEL_CURRENT)
val builder = NotificationCompat.Builder(baseActivity, "")
.setSmallIcon(notificationIcon)
.setContentTitle("Subject Topic downloaded")
.setContentText(fileName)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
val notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(baseActivity)
// notificationId is a unique int for each notification that you must define
notificationManager.notify(1, builder.build())
} catch (e: Exception) {
// Log.e(FragmentActivity.TAG, "Notification $e")
}
}
可能会有所帮助!
答案 2 :(得分:0)
我在三星设备上也遇到了类似的问题,这就是我所做的:
考虑这一点:
builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
在上面的行中,我们通过了NOTIFICATION_CHANNEL_ID
。
现在在代码的后面还会添加:
builder.setChannelId(NOTIFICATION_CHANNEL_ID) // don't call this method
我们已经通过构造函数将通道ID提供给了构建器,我们无需再次传递它。删除builder.setChannelId(NOTIFICATION_CHANNEL_ID)
。它也将在三星设备上工作。