终止应用程序后未触发 AlarmManager 通知
AlarmManager notification not triggering after killing application
需要在特定日期和时间将通知显示为剩余。要设置余数,我使用 AlarmManger 设置任务并使用广播接收器显示通知。但是在终止应用程序通知后,剩余部分不会触发。
要使用此代码设置日期和时间
Intent notificationIntent = new Intent(this, AddAppointmentAlarmReceiver.class);
notificationIntent.putExtra(NOTIFICATION,addAppointDataBinding.edTitle.getText().toString());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(date);
calendar.set(Calendar.HOUR,7);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
服务class
public class AlarmIntentService extends Service {
private static final int NOTIFICATION_ID = 3;
Context context;
public AlarmIntentService(Context applicationContext) {
super();
this.context = applicationContext;
}
public AlarmIntentService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
NotificationChannel channel = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = new NotificationChannel(Constants.NOTIFICATION_ID,intent.getStringExtra(NOTIFICATION), NotificationManager.IMPORTANCE_HIGH);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
managerCompat.createNotificationChannel(channel);
}
Intent notifyIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle(NOTIFICATION_TITLE);
builder.setContentText(intent.getStringExtra(NOTIFICATION));
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentIntent(pendingIntent);
builder.setSound(alarmSound);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(Constants.NOTIFICATION_ID);
}
Notification notificationCompat = builder.build();
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
广播接收器class
public class AddAppointmentAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
AlarmWakeLock.acquire(context);
Intent intent1 = new Intent(context, AlarmIntentService.class);
intent1.putExtra(NOTIFICATION,intent.getStringExtra(NOTIFICATION));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent1);
}else {
context.startService(intent1);
}
}
}
我记得与警报有类似的问题,以及它在触发时的工作方式。请尝试下面的一段代码,看看是否有任何结果。
// Depending on the version of Android use different function for setting an Alarm.
// setAlarmClock() => Android < Marshmallow
// setExactAndAllowWhileIdle() => Android >= Marshmallow
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(alarmTimeAtUTC, pendingIntent),
pendingIntent
)
} else {
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
alarmTimeAtUTC,
pendingIntent
)
}
第 1 步:尝试不使用 AlarmIntentService:
在您的 setAlarm
函数中执行以下操作:
...
Intent notificationIntent = new Intent(this, AddAppointmentAlarmReceiver.class);
notificationIntent.setAction = "AppointmentBroadcastReceiverAction"
...
然后,在您的广播接收器中:
public class AddAppointmentAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.action == "AppointmentBroadcastReceiverAction") {
sendNotification()
}
}
}
第 2 步:构建最大优先级通知:[Kotlin 中的示例代码;适应Java]
private fun sendInternetDaysLeftNotification(context: Context) {
val channelId: String = context.resources.getString(R.string.internetDaysLeftNotificationsChannelId)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(%YOUR TITLE%)
.setContentText(%YOUR TEXT%)
.setAutoCancel(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_MAX)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, DEFAULT_NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
// Random.nextInt() can be replaced with any Integer.
notificationManager.notify(Random.nextInt(0, 100), notificationBuilder.build())
}
需要在特定日期和时间将通知显示为剩余。要设置余数,我使用 AlarmManger 设置任务并使用广播接收器显示通知。但是在终止应用程序通知后,剩余部分不会触发。
要使用此代码设置日期和时间
Intent notificationIntent = new Intent(this, AddAppointmentAlarmReceiver.class);
notificationIntent.putExtra(NOTIFICATION,addAppointDataBinding.edTitle.getText().toString());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(date);
calendar.set(Calendar.HOUR,7);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
服务class
public class AlarmIntentService extends Service {
private static final int NOTIFICATION_ID = 3;
Context context;
public AlarmIntentService(Context applicationContext) {
super();
this.context = applicationContext;
}
public AlarmIntentService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
NotificationChannel channel = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = new NotificationChannel(Constants.NOTIFICATION_ID,intent.getStringExtra(NOTIFICATION), NotificationManager.IMPORTANCE_HIGH);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
managerCompat.createNotificationChannel(channel);
}
Intent notifyIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle(NOTIFICATION_TITLE);
builder.setContentText(intent.getStringExtra(NOTIFICATION));
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentIntent(pendingIntent);
builder.setSound(alarmSound);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(Constants.NOTIFICATION_ID);
}
Notification notificationCompat = builder.build();
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
广播接收器class
public class AddAppointmentAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
AlarmWakeLock.acquire(context);
Intent intent1 = new Intent(context, AlarmIntentService.class);
intent1.putExtra(NOTIFICATION,intent.getStringExtra(NOTIFICATION));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent1);
}else {
context.startService(intent1);
}
}
}
我记得与警报有类似的问题,以及它在触发时的工作方式。请尝试下面的一段代码,看看是否有任何结果。
// Depending on the version of Android use different function for setting an Alarm.
// setAlarmClock() => Android < Marshmallow
// setExactAndAllowWhileIdle() => Android >= Marshmallow
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(alarmTimeAtUTC, pendingIntent),
pendingIntent
)
} else {
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
alarmTimeAtUTC,
pendingIntent
)
}
第 1 步:尝试不使用 AlarmIntentService:
在您的 setAlarm
函数中执行以下操作:
...
Intent notificationIntent = new Intent(this, AddAppointmentAlarmReceiver.class);
notificationIntent.setAction = "AppointmentBroadcastReceiverAction"
...
然后,在您的广播接收器中:
public class AddAppointmentAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.action == "AppointmentBroadcastReceiverAction") {
sendNotification()
}
}
}
第 2 步:构建最大优先级通知:[Kotlin 中的示例代码;适应Java]
private fun sendInternetDaysLeftNotification(context: Context) {
val channelId: String = context.resources.getString(R.string.internetDaysLeftNotificationsChannelId)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(%YOUR TITLE%)
.setContentText(%YOUR TEXT%)
.setAutoCancel(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_MAX)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, DEFAULT_NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
// Random.nextInt() can be replaced with any Integer.
notificationManager.notify(Random.nextInt(0, 100), notificationBuilder.build())
}