问题描述
我有一个带有 Switch
的应用程序,它必须触发我的 JobService
。我在 Switch 的 setonCheckedchangelistener
中调用了两种方法,一种用于注册作业,另一种用于注销作业。
它似乎可以工作,就像调试显示一样,但是 onStartJob
中的后台工作。我错过了什么?
MemoNotificationService.kt
class MemoNotificationService : JobService() {
companion object {
const val TAG = "MemoPush"
const val serviceId = 4242
}
override fun onStartJob(params: JobParameters?): Boolean {
dobackgroundWork(params)
return true
}
private fun dobackgroundWork(params: JobParameters?) {
Coroutinescope(dispatchers.IO).launch {
Log.d(TAG,"Push sending...")
sendNotification("body push 1","title push 1","",1)
Log.d(TAG,"Push sent")
jobFinished(params,false)
}
}
override fun onStopJob(params: JobParameters?): Boolean {
Log.d(TAG,"<Job interrupt>")
return true
}
fun sendNotification(
messageBody: String,messageTitle: String,largeIconPath: String,pushId: Int
) {
val channelId = getString(R.string.consumer_notification_channel_id)
val channelName = getString(R.string.consumer_notification_channel_name)
val defaultSoundUri = ringtoneManager.getDefaultUri(ringtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this,channelId)
.setSmallIcon(R.drawable.logo_anim1)
.setColor(ContextCompat.getColor(this,R.color.colorAccent))
.setColorized(true)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setLights(Color.YELLOW,1000,1000)
val notificationmanager =
getSystemService(Context.NOTIFICATION_SERVICE) as notificationmanager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,channelName,notificationmanager.IMPORTANCE_DEFAULT
)
channel.enableLights(true)
channel.lightColor = Color.YELLOW
notificationmanager.createNotificationChannel(channel)
}
notificationmanager.notify(pushId,notificationBuilder.build())
}
}
SettingsFragment.kt
private fun registerNotification() {
//Todo("Not yet implemented")
val componentService = ComponentName(requireContext(),MemoNotificationService::class.java)
val info = JobInfo.Builder(MemoNotificationService.serviceId,componentService)
.setPersisted(true) /*persist on boot*/ /*not sure if needed*/
.setPeriodic(30 * 1000) /*once a day = 24 * 60 * 60 * 1000 */
.build()
val scheduler = requireContext().getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val resultCode = scheduler.schedule(info)
if(resultCode == JobScheduler.RESULT_SUCCESS)
Log.d(MemoNotificationService.TAG,"<Job scheduled>")
else
Log.d(MemoNotificationService.TAG,"<Job scheduling Failed>")
}
private fun unregisterNotification() {
//Todo("Not yet implemented")
val scheduler = requireContext().getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
Log.d(MemoNotificationService.TAG,"<Job scheduling cancelling> :: ${scheduler.allPendingJobs}")
scheduler.cancel(MemoNotificationService.serviceId)
Log.d(MemoNotificationService.TAG,"<Job scheduling cancelled> :: ${scheduler.allPendingJobs}")
}
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<service
android:name=".MemoNotificationService"
android:permission="android.permission.BIND_JOB_SERVICE" />
Logcat
D/MemoPush: <Job scheduled>
D/MemoPush: <Job scheduling cancelling> :: [(job:4242/com.example.testjobservice/.MemoNotificationService)]
D/MemoPush: <Job scheduling cancelled> :: []
实际上,我需要使用离线服务(整个应用程序中没有互联网)发送推送通知,例如每天一次,使用相同的通知,或... 这是实现这一目标的正确方法吗?
解决方法
文档说最小调度程序时间是 15 分钟,所以这可能是问题所在。 将代码更改为:
SettingsFragment.kt
private fun registerNotification() {
val componentService = ComponentName(requireContext(),MemoNotificationService::class.java)
val info = JobInfo.Builder(MemoNotificationService.serviceId,componentService)
.setPersisted(true)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
//info.setPeriodic(24 * 60 * 60 * 1000,12 * 60 * 60 * 1000)
info.setPeriodic(30 * 60 * 1000,15 * 60 * 1000) //for testing purpose
}
else {
//info.setPeriodic(24 * 60 * 60 * 1000)
info.setPeriodic(15 * 60 * 1000) //for testing purpose
}
val scheduler = requireContext().getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val resultCode = scheduler.schedule(info.build())
if(resultCode == JobScheduler.RESULT_SUCCESS)
Log.d(MemoNotificationService.TAG,"<Job scheduled>")
else
Log.d(MemoNotificationService.TAG,"<Job scheduling failed>")
}
我猜它就像一种魅力。
无论如何,对于进一步的解决方案,最好使用基于 WorkManager
(API AlarmManager (API >= 21) 构建的 JobScheduler
。
官方代码实验室:https://developer.android.com/codelabs/android-workmanager?index=..%2F..index#0