我想在用户选择并同时每天重复播放时弹出通知。我设置了这样的通知:
NotifyActivity:
public void setAlarm() {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(NotifyActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(NotifyActivity.this, 1, alarmIntent, PendingIntent.FLAG_ONE_SHOT);
Calendar alarmStartTime = Calendar.getInstance();
alarmStartTime.set(Calendar.HOUR_OF_DAY, hour);
alarmStartTime.set(Calendar.MINUTE, minute);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmStartTime.getTimeInMillis(), pendingIntent);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Message Sent!").setCancelable(false).setNegativeButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.setTitle("TITLE");
alert.setMessage("Notification was set.");
alert.show();
}
AlarmReciever:
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "NotificationService");
wakeLock.acquire();
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
AlarmService:
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Context context = this.getApplicationContext();
notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("TITLE");
builder.setContentText("TEXT");
builder.setSmallIcon(R.drawable.logo);
builder.setSound(soundUri);
builder.setContentIntent(pendingIntent);
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "NotificationService");
wakeLock.acquire(10000);
WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyCpuLock");
wl_cpu.acquire(10000);
wakeLock.release();
//set next alarm after 24 hours
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(AlarmService.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(AlarmService.this, 1, alarmIntent,
PendingIntent.FLAG_ONE_SHOT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 86400000, pendingIntent);
}
一切都很好。我在设置时收到通知。但也可以随机获得相同的通知。如何摆脱这些随机通知?有什么想法吗?
编辑: 我更新了我的代码并将警报设置为简单而不是setRepeating。弹出旧通知时,我在服务中设置了新警报。但我仍然会随机收到通知。在我设置的时间弹出第一个通知,其他人在24小时后但在几小时,40分钟或其他随机时间后弹出。我试图设置alarmManager.setExact它只来自api 19,但我遇到了同样的问题。我的targetSdkVersion现在设置为18。
编辑2:如果我只在NotifyActivity中设置闹钟并删除最后五行AlarmService,它也会抛出多个通知。我认为它应该只扔一个。
答案 0 :(得分:0)
如果打算不唤醒手机,请忽略下面的文字(因此,我认为唤醒锁对您的应用程序非常有用)。如果您想让应用程序即使在手机睡眠时也能正常工作,那么请阅读它:
尝试使用RTC_WAKE_UP而不是RTC。当手机睡觉时,它不会以这种方式醒来。
此外,我发现你可能有问题让你的手机保持清醒状态。它可以在服务完成之前进入睡眠状态。 在onReceive()中使用WakefulBroadcastReceiver或创建WakeLock。 这将确保您的电话在服务期间处于清醒状态。
WakefulBroadcastReceiver是第二件事的最佳选择,关于唤醒锁 - 你可以在google上查看一些示例,说明如何将警报管理器与唤醒锁使用。 Ofc,你的服务可以完成它的工作,但有时睡眠可能会出现,所以我建议你实施它,即使你的测试没有显示问题,更好的是保持安全。
编辑:
选中,你可以使用PendingIntent.FLAG_ONE_SHOT而不是PendingIntent.FLAG_CANCEL_CURRENT,但不能在你设置闹钟的待处理中,但是在那里你设置你的通知。它应该工作得很好!
编辑2:
另外,我建议您更改请求编号。等待意图不会被这种方式压倒。
例如:
在AlarmService中:
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_ONE_SHOT);
在setAlarm()中:
PendingIntent pendingIntent = PendingIntent.getBroadcast(NotifyActivity.this, 1, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
我不确定这两者是如何协同工作的,有可能它们不能被覆盖,但我认为这样做更安全。 如果您希望创建更多待处理的意图以便不被覆盖,则可以使用SharedPreferences保持int number或date base int,每次创建Pending Intent时将其递增并将其作为参数放入其中。在我的应用程序中它工作正常。
答案 1 :(得分:0)
请注意,文档here表明"从API 19开始,所有重复警报都不准确。如果您的应用程序需要精确的交付时间,那么它必须使用一次性精确警报,每次重新安排如上所述。 targetSdkVersion早于API 19的旧应用程序将继续拥有所有警报,包括重复警报,视为确切的"。
也许这导致了这个问题?