Android 开发中:应用关闭时不显示通知
Android Developing: notifications don't show when app is closed
如何在 Android Studio 中发送预定通知?
我得到了这个任务:我想每天在一天中的某个选定时间收到通知。我可以在应用程序运行时轻松获取它们,但是当它的关闭通知没有出现时。
我已经尝试过 JobScheduler、AlarmManager 和 WorkManager,其中 none 效果不佳。
我的项目至少运行 SDK 26 (Android Oreo)。目标 SDK 为 30。最后的代码版本如下所示:
AlertReceiver.java
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, NotificationService.class);
context.startService(intent);
}
}
NotificationService.java
public class NotificationService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
showNotifications();
return Service.START_STICKY;
}
private void showNotifications(){
NotificationHelper notificationHelper = new NotificationHelper(getApplicationContext());
NotificationCompat.Builder nb;
nb = notificationHelper.getChannelNotification("Title", "Description");
notificationHelper.getManager().notify(123, nb.build());
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
我这样安排提醒:
...
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
AlarmManager alarm_manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlertReceiver.class);
PendingIntent pending_intent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarm_manager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pending_intent);
```
这是我在一个项目中使用的通知(对不起Kotlin语言):
private fun createNotification() {
val notification = getServiceNotification("")
notificationManager.notify(NOTIFICATION_ID, notification.build())
}
private fun getServiceNotification(contentText: String): Notification.Builder {
var notification = Notification.Builder(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
notification = Notification.Builder(this, NOTIFICATION_SERVICE_CHANNEL_ID)
}
val openAppPendingIntent = PendingIntent.getActivity(
this,
0,
Intent(this, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
return notification
.setContentTitle("Notification Title")
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_main)
.setContentIntent(openAppPendingIntent)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
val notificationChannel = NotificationChannel(
NOTIFICATION_SERVICE_CHANNEL_ID,
NOTIFICATION_SERVICE_CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH
).apply {
lightColor = Color.GREEN
lockscreenVisibility = Notification.VISIBILITY_PRIVATE
}
notificationManager.createNotificationChannel(notificationChannel)
}
问题是fromAndroid8后台调用startService
是不允许的:
在此代码中:
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, NotificationService.class);
context.startService(intent);
}
}
您可以更改为:
context.startService(intent);
收件人:
ContextCompat.startForegroundService(getApplicationContext(), intent)
并将其放入您的清单中:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
这将至少允许您的服务在当前实施中从后台运行。
然后您有 5 秒的时间在您的 Service
和 post 中调用 startForeground()
一个 Notification
让用户知道您的服务是 运行 ning 否则将被终止。
另外对于你正在尝试做的事情,我认为你会得到更好的结果:
setExactAndAllowWhileIdle
或
setAlarmClock
setExact
并不像名字暗示的那样起作用。所有 AlarmManager 文档都需要仔细阅读,我建议在尝试任何依赖于计时的 Service
实现之前详细研究“瞌睡”。
如何在 Android Studio 中发送预定通知? 我得到了这个任务:我想每天在一天中的某个选定时间收到通知。我可以在应用程序运行时轻松获取它们,但是当它的关闭通知没有出现时。
我已经尝试过 JobScheduler、AlarmManager 和 WorkManager,其中 none 效果不佳。 我的项目至少运行 SDK 26 (Android Oreo)。目标 SDK 为 30。最后的代码版本如下所示:
AlertReceiver.java
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, NotificationService.class);
context.startService(intent);
}
}
NotificationService.java
public class NotificationService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
showNotifications();
return Service.START_STICKY;
}
private void showNotifications(){
NotificationHelper notificationHelper = new NotificationHelper(getApplicationContext());
NotificationCompat.Builder nb;
nb = notificationHelper.getChannelNotification("Title", "Description");
notificationHelper.getManager().notify(123, nb.build());
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
我这样安排提醒:
...
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
AlarmManager alarm_manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlertReceiver.class);
PendingIntent pending_intent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarm_manager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pending_intent);
```
这是我在一个项目中使用的通知(对不起Kotlin语言):
private fun createNotification() {
val notification = getServiceNotification("")
notificationManager.notify(NOTIFICATION_ID, notification.build())
}
private fun getServiceNotification(contentText: String): Notification.Builder {
var notification = Notification.Builder(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
notification = Notification.Builder(this, NOTIFICATION_SERVICE_CHANNEL_ID)
}
val openAppPendingIntent = PendingIntent.getActivity(
this,
0,
Intent(this, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
return notification
.setContentTitle("Notification Title")
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_main)
.setContentIntent(openAppPendingIntent)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
val notificationChannel = NotificationChannel(
NOTIFICATION_SERVICE_CHANNEL_ID,
NOTIFICATION_SERVICE_CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH
).apply {
lightColor = Color.GREEN
lockscreenVisibility = Notification.VISIBILITY_PRIVATE
}
notificationManager.createNotificationChannel(notificationChannel)
}
问题是fromAndroid8后台调用startService
是不允许的:
在此代码中:
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, NotificationService.class);
context.startService(intent);
}
}
您可以更改为:
context.startService(intent);
收件人:
ContextCompat.startForegroundService(getApplicationContext(), intent)
并将其放入您的清单中:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
这将至少允许您的服务在当前实施中从后台运行。
然后您有 5 秒的时间在您的 Service
和 post 中调用 startForeground()
一个 Notification
让用户知道您的服务是 运行 ning 否则将被终止。
另外对于你正在尝试做的事情,我认为你会得到更好的结果:
setExactAndAllowWhileIdle
或
setAlarmClock
setExact
并不像名字暗示的那样起作用。所有 AlarmManager 文档都需要仔细阅读,我建议在尝试任何依赖于计时的 Service
实现之前详细研究“瞌睡”。