[英]How To schedule and a send Notification even after user removes app from recent apps?
My app is simple我的应用很简单
Take Time from the user(I know how to do it)从用户那里花时间(我知道怎么做)
schedule A notification(I know how to send notification)安排通知(我知道如何发送通知)
Now I just want to know that How can I send this notification even user removes it from recent apps.现在我只想知道即使用户从最近的应用程序中删除它,我如何发送此通知。
Tried Solutions- AlarmManager, BroudcastReceiver, Service, Intent Service,尝试过的解决方案——AlarmManager、BroudcastReceiver、Service、Intent Service、
But all are work only when the app is present in RAM (recent apps list Of Mobile).但只有当应用程序存在于 RAM 中时,所有这些都有效(最近的移动应用程序列表)。
How can I do that just tell me the topic.我该怎么做就告诉我主题。 I don't need code.
我不需要代码。 I will study that.
我会研究那个。
you can use WorkManger to schedule tasks.您可以使用 WorkManger 来安排任务。
The WorkManager API makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or device restarts. WorkManager API 可以轻松安排可延迟的异步任务,即使应用程序退出或设备重新启动,这些任务也会运行。
check Google documentation here . 在此处查看 Google 文档。
for notifications, you can send a notification in your work manager class.对于通知,您可以在工作管理器 class 中发送通知。 learn more here .
在这里了解更多。
these hints should be enough.这些提示应该足够了。 let me know if you need more clarifications.
如果您需要更多说明,请告诉我。
As you have mentioned that AlarmManager and others did not work for you, I tested what you are trying to achieve with JobScheduler.正如您提到的 AlarmManager 和其他人对您不起作用,我测试了您尝试使用 JobScheduler 实现的目标。
It worked for me, and it worked even after removing the app from the recent apps list.它对我有用,即使从最近的应用程序列表中删除该应用程序后它也有效。 I tried it on Android 10 emulator.
我在 Android 10 模拟器上试过。
You have asked for topics / references to study as the answer.您已要求提供要研究的主题/参考作为答案。 So first I'll mention the references I used.
所以首先我会提到我使用的参考资料。
Here is the code lab of JobScheduler and it's really helpful: https://codelabs.developers.google.com/codelabs/android-training-job-scheduler/这是 JobScheduler 的代码实验室,它真的很有帮助: https://codelabs.developers.google.com/codelabs/android-training-job-scheduler/
Here is a good reference about creating multiple scheduled jobs: https://android-developers.googleblog.com/2017/10/working-with-multiple-jobservices.html这是有关创建多个计划作业的一个很好的参考: https://android-developers.googleblog.com/2017/10/working-with-multiple-jobservices.html
Here is what I tried.这是我尝试过的。
NotificationJobService.kt NotificationJobService.kt
private const val NOTIF_CHANNEL_ID = "primary_notification_channel"
private const val NOTIF_CHANNEL_NAME = "Job Service notification"
class NotificationJobService : JobService() {
override fun onStartJob(params: JobParameters?): Boolean {
// Get Notification Manager
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Create Notification Channel if device OS >= Android O
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel(NOTIF_CHANNEL_ID, NOTIF_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).let {
notificationManager.createNotificationChannel(it)
}
}
// Create PendingIntent with empty Intent
// So this pending intent does nothing
val pendingIntent = PendingIntent.getActivity(this, 0, Intent(), PendingIntent.FLAG_ONE_SHOT)
// Configure NotificationBuilder
val builder = NotificationCompat.Builder(this, NOTIF_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Title")
.setContentText("Message")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
// Make the Notification
notificationManager.notify(0, builder.build())
// False to let system know that the job is completed by the end of onStartJob(),
// and the system calls jobFinished() to end the job.
return false
}
override fun onStopJob(params: JobParameters?): Boolean {
// True because if the job fails, you want the job to be rescheduled instead of dropped.
return true
}
}
MainActivity.kt MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Job ID must be unique if you have multiple jobs scheduled
var jobID = 0
// Get fake user set time (a future time 1 min from current time)
val ( userSetHourOfDay, userSetMinute ) = getMockUserSetTime()
val timeToWaitBeforeExecuteJob = calculateTimeDifferenceMs(userSetHourOfDay, userSetMinute)
(getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler).run {
schedule(
JobInfo.Builder(
jobID,
ComponentName(baseContext, NotificationJobService::class.java)
)
// job execution will be delayed by this amount of time
.setMinimumLatency(timeToWaitBeforeExecuteJob)
// job will be run by this deadline
.setOverrideDeadline(timeToWaitBeforeExecuteJob)
.build()
)
}
}
// Returns a pair ( hourOfDay, minute ) that represents a future time,
// 1 minute after the current time
private fun getMockUserSetTime() : Pair<Int, Int> {
val calendar = Calendar.getInstance().apply {
// add just 1 min from current time
add(Calendar.MINUTE, 1)
}
return Pair(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE))
}
// Calculate time difference relative to current time in ms
private fun calculateTimeDifferenceMs(hourOfDay: Int, minute: Int) : Long {
val now = Calendar.getInstance()
val then = (now.clone() as Calendar).apply {
set(Calendar.HOUR_OF_DAY, hourOfDay)
set(Calendar.MINUTE, minute)
}
return then.timeInMillis - now.timeInMillis
}
}
I used setMinimumLatency(timeToWaitBeforeExecuteJob)
and setOverrideDeadline(timeToWaitBeforeExecuteJob)
constraints when scheduling the job so that, the job will be executed at exact time we want it to run.我在调度作业时使用了
setMinimumLatency(timeToWaitBeforeExecuteJob)
和setOverrideDeadline(timeToWaitBeforeExecuteJob)
约束,以便作业将在我们希望它运行的准确时间执行。
I ran the app once, go back and removed the app from recent apps list.我运行了一次应用程序 go 并从最近的应用程序列表中删除了该应用程序。 Then I suspended the device, and after 1 minute, I heard the notification sound.
然后我暂停了设备,1分钟后,我听到了提示音。 When I resumed the device and checked, the expected notification was there.
当我恢复设备并检查时,预期的通知就在那里。
You should consider Remon Shehatta's answer as well.
您也应该考虑 Remon Shehatta 的回答。 Because it seems WorkManager sits on top of JobScheduler and AlarmManager, and picks the right one based on device's API level.
因为 WorkManager 似乎位于 JobScheduler 和 AlarmManager 之上,并根据设备的 API 级别选择正确的。 So it may be better to use WorkManager if you are targeting API levels older than 21. But as you mentioned that AlarmManager did not work for you, you should experiment and choose the right one.
因此,如果您的目标是 21 岁以上的 API 级别,使用 WorkManager 可能会更好。但是正如您提到的,AlarmManager 不适合您,您应该尝试并选择正确的。
Please update us with your findings.请向我们更新您的发现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.