当应用程序关闭时,AlarmManager 不工作。这是为什么?
AlarmManager does not work when the app is closed. Why is that?
美好的一天,
我在我的 Android 应用程序中内置了一个计时器,它会在特定时间后发送一条消息。为此,我添加了一个带有未决意图的 AlarmManager。当我打开应用程序时,一切正常。它也适用于锁定屏幕。但是当我关闭应用程序时,挂起的意图不再被激活并且在给定时间没有消息出现。
这是我的警报管理器:
Intent notifyIntent = new Intent(getContext(), MyReceiver.class);
alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast
(getContext(), NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//when the alarm gets activated:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
else {
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
在IntentService-Class(声明和调用通知的地方):
Intent notifyIntent = new Intent(this, BigTextMainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);
PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
NotificationCompat.Action snoozeAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_alarm_white_48dp,
"Snooze",
snoozePendingIntent)
.build();
Intent dismissIntent = new Intent(this, BigTextIntentService.class);
dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);
PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
NotificationCompat.Action dismissAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_cancel_white_48dp,
"Dismiss",
dismissPendingIntent)
.build();
NotificationCompat.Builder notificationCompatBuilder =
new NotificationCompat.Builder(
getApplicationContext(), notificationChannelId);
GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);
Notification notification = notificationCompatBuilder
.setStyle(bigTextStyle)
.setContentTitle(bigTextStyleReminderAppData.getContentTitle())
.setContentText(bigTextStyleReminderAppData.getContentText())
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(),
R.drawable.ic_alarm_white_48dp))
.setContentIntent(notifyPendingIntent)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setCategory(Notification.CATEGORY_REMINDER)
.setPriority(bigTextStyleReminderAppData.getPriority())
.setVisibility(bigTextStyleReminderAppData.getChannelLockscreenVisibility())
.addAction(snoozeAction)
.addAction(dismissAction)
.build();
//I am not quite shure, if I declared the foregroundservice for the notification at the right place
startForeground(NOTIFICATION_ID, notification);
mNotificationManagerCompat.notify(NOTIFICATION_ID, notification);
Vibrator vibrator = (Vibrator) getApplication().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2 * 1000);
这些是我的权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
感谢您的帮助!
(顺便说一句,如果这个问题很愚蠢或者是因为我没有真正处理这个话题,只是想快速为我的应用程序发出警报,提前抱歉)
根据您的评论,警报似乎正常触发,但您的 BroadcastReceiver
在尝试启动 Service
时失败了。最可能的原因是您的设备对后台处理有额外的限制。一些设备,主要是低端设备和中国制造的设备,对允许 运行“在后台”运行的应用程序有限制。如果您的应用不在允许应用的“白名单”中,Android 将不允许应用的组件在后台启动。
请参阅 https://developer.android.com/about/versions/oreo/background to read about background Service
limitations and see 作为我讨论某些制造商限制后台处理的问题的答案示例。
注意:
由于您无法在 Android 8 及更高版本上启动背景 Service
(由于限制),您可以将 Service
作为前景 Service
启动,如下所示:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
美好的一天, 我在我的 Android 应用程序中内置了一个计时器,它会在特定时间后发送一条消息。为此,我添加了一个带有未决意图的 AlarmManager。当我打开应用程序时,一切正常。它也适用于锁定屏幕。但是当我关闭应用程序时,挂起的意图不再被激活并且在给定时间没有消息出现。 这是我的警报管理器:
Intent notifyIntent = new Intent(getContext(), MyReceiver.class);
alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast
(getContext(), NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//when the alarm gets activated:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
else {
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
在IntentService-Class(声明和调用通知的地方):
Intent notifyIntent = new Intent(this, BigTextMainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);
PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
NotificationCompat.Action snoozeAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_alarm_white_48dp,
"Snooze",
snoozePendingIntent)
.build();
Intent dismissIntent = new Intent(this, BigTextIntentService.class);
dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);
PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
NotificationCompat.Action dismissAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_cancel_white_48dp,
"Dismiss",
dismissPendingIntent)
.build();
NotificationCompat.Builder notificationCompatBuilder =
new NotificationCompat.Builder(
getApplicationContext(), notificationChannelId);
GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);
Notification notification = notificationCompatBuilder
.setStyle(bigTextStyle)
.setContentTitle(bigTextStyleReminderAppData.getContentTitle())
.setContentText(bigTextStyleReminderAppData.getContentText())
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(),
R.drawable.ic_alarm_white_48dp))
.setContentIntent(notifyPendingIntent)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setCategory(Notification.CATEGORY_REMINDER)
.setPriority(bigTextStyleReminderAppData.getPriority())
.setVisibility(bigTextStyleReminderAppData.getChannelLockscreenVisibility())
.addAction(snoozeAction)
.addAction(dismissAction)
.build();
//I am not quite shure, if I declared the foregroundservice for the notification at the right place
startForeground(NOTIFICATION_ID, notification);
mNotificationManagerCompat.notify(NOTIFICATION_ID, notification);
Vibrator vibrator = (Vibrator) getApplication().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2 * 1000);
这些是我的权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
感谢您的帮助! (顺便说一句,如果这个问题很愚蠢或者是因为我没有真正处理这个话题,只是想快速为我的应用程序发出警报,提前抱歉)
根据您的评论,警报似乎正常触发,但您的 BroadcastReceiver
在尝试启动 Service
时失败了。最可能的原因是您的设备对后台处理有额外的限制。一些设备,主要是低端设备和中国制造的设备,对允许 运行“在后台”运行的应用程序有限制。如果您的应用不在允许应用的“白名单”中,Android 将不允许应用的组件在后台启动。
请参阅 https://developer.android.com/about/versions/oreo/background to read about background Service
limitations and see
注意:
由于您无法在 Android 8 及更高版本上启动背景 Service
(由于限制),您可以将 Service
作为前景 Service
启动,如下所示:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}