【发布时间】:2022-03-24 01:27:37
【问题描述】:
我正在尝试在我的应用程序中构建提醒模块以如下方式工作,当用户在确切时间设置警报时它会触发通知。
但是,有两种情况会失败:
1- 当我将闹钟时间设置为下一个 2 小时及以上时
2- 如果我从任务管理器中删除了应用程序(完全关闭)
不会触发任何通知,但是当我第一次打开应用程序时,我会立即收到所有丢失的通知。
我正在使用闹钟管理器将闹钟设置如下:
val manager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pendingIntent = PendingIntent.getBroadcast(context, requestCode, myIntent, 0)
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
manager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
timeOnDayCalender.timeInMillis,
pendingIntent
)
}
else -> {
manager.setExact(
AlarmManager.RTC_WAKEUP,
timeOnDayCalender.timeInMillis,
pendingIntent
)
}
}
并在广播接收器中接收我的警报管理器,如下所示:
class AlarmBroadcast : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val newIntent = Intent(context, AlarmService::class.java)
newIntent.type = intent?.type
newIntent.action = intent?.action
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context?.startForegroundService(newIntent)
} else {
context?.startService(newIntent)
}
}
}
我的AlarmService 班级是:
class AlarmService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// show foreground notification to let user there is action happening in background
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
showForegroundNotification()
else
startForeground(
1,
Notification()
)
handleAlarmRedirection(intent)
stopSelf(startId) // to destroy service after work is done & remove the fixed notification.
return START_STICKY
}
private fun showForegroundNotification() {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId)
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_MIN)
.setContentTitle("title")
.setContentText("body")
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(): String {
val chan = NotificationChannel(
"my_service",
"My Background Service",
NotificationManager.IMPORTANCE_NONE
)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return "my_service"
}
private fun handleAlarmRedirection(intent: Intent?) {
// logic for pushing the notification is here
}
override fun onDestroy() {
super.onDestroy()
stopForeground(true)
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
我也添加了 manifest 的权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
希望有人知道这个案子。
如果有人有好的教程或最佳实践建议,请告诉我,我的目标是 android 31。
【问题讨论】:
-
setExact 在打盹模式下不会触发尝试使用setExactAllowWhileIdle()
-
好的,我会试试这个,但是,这是否与应用打开后调用广播有关?
-
不!当我们需要在设备处于打盹/空闲模式时触发警报时,我们可以使用 setExactAllowWhileIdle() 在准确的时间触发警报。而 setExact 与下一个维护窗口的时间不同。
-
好的,我知道了,我试试看,你
-
好的!谢谢,我不知道。感谢您更新我的信息。
标签: android service broadcastreceiver alarmmanager