Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过在Android上使用Switch小部件,JobService将发出通知_Android_Kotlin_Push Notification_Kotlin Coroutines_Jobservice - Fatal编程技术网

通过在Android上使用Switch小部件,JobService将发出通知

通过在Android上使用Switch小部件,JobService将发出通知,android,kotlin,push-notification,kotlin-coroutines,jobservice,Android,Kotlin,Push Notification,Kotlin Coroutines,Jobservice,我有一个带有开关的应用程序,它必须启动我的作业服务。我在开关的setOnCheckedChangeListener中调用了两个方法,一个用于注册,另一个用于取消注册作业。 它似乎可以工作,就像调试显示一样,但是后台可以在onStartJob中工作。我错过了什么 memnotificationservice.kt class MemoNotificationService : JobService() { companion object { const val TAG

我有一个带有
开关的应用程序
,它必须启动我的
作业服务
。我在开关的
setOnCheckedChangeListener
中调用了两个方法,一个用于注册,另一个用于取消注册作业。 它似乎可以工作,就像调试显示一样,但是后台可以在
onStartJob
中工作。我错过了什么

memnotificationservice.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())
    }


}
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}")
    }
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>")
}
AndroidManifest.xml

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<service

    android:name=".MemoNotificationService"
    android:permission="android.permission.BIND_JOB_SERVICE" />
实际上,我需要使用离线服务(整个应用程序中没有Internet)发送推送通知,例如,每天发送一次相同的通知,或者发送一个。。。
这是实现这一目标的正确方法吗?

文档中说,调度程序的最短时间是15分钟,因此这可能是问题所在。 将代码更改为:

设置片段.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())
    }


}
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}")
    }
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>")
}
private fun registerNotification(){
val componentService=ComponentName(requireContext(),MemonNotificationService::class.java)
val info=JobInfo.Builder(MemonNotificationService.serviceId,componentService)
.setPersisted(true)
if(android.os.Build.VERSION.SDK\u INT>=android.os.Build.VERSION\u code.N){
//信息设置周期(24*60*60*1000,12*60*60*1000)
info.setPeriodic(30*60*1000,15*60*1000)//用于测试目的
}
否则{
//信息设置周期(24*60*60*1000)
info.setPeriodic(15*60*1000)//用于测试目的
}
val scheduler=requireContext().getSystemService(Context.JOB\u scheduler\u SERVICE)作为作业调度器
val resultCode=scheduler.schedule(info.build())
if(resultCode==JobScheduler.RESULT\u SUCCESS)
Log.d(memonNotificationService.TAG,“”)
其他的
Log.d(memonNotificationService.TAG,“”)
}
我想它很有魅力

无论如何,对于进一步的解决方案,最好使用基于
AlarmManager
(API<21)和
JobScheduler
(API>=21)的
WorkManager
。 官方代码实验室: