【问题标题】:Canceling running coroutineWorker doesn't fire failure in a certain pattern取消正在运行的 coroutineWorker 不会以某种模式引发故障
【发布时间】:2023-02-08 22:22:04
【问题描述】:

我正在尝试通过通知按钮停止运行 coroutineWorker。我尝试了 3 种方法,其中 2 种调用“Result.failure()”并且工作正常。但是另一个没有。

CoroutineWorker 下方显示了 foregroundInfo 和 Starts 铃声。

class RingWork(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

    
    companion object {
        val ALARM_CHANNEL_ID = "alarm_channel6"
    }

    lateinit var ringtoneSound: Ringtone

    val context = applicationContext
    
    @RequiresApi(Build.VERSION_CODES.Q)
    override suspend fun doWork(): Result {


        return try {

            val alarmId = inputData.getInt("alarmId", 0)

            val notificationMgr =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

            //CHANNEL
            val alarmChannel = NotificationChannel(
                ALARM_CHANNEL_ID, "alarm" ,NotificationManager.IMPORTANCE_HIGH
            )
            alarmChannel.setSound(null, null)
            alarmChannel.enableVibration(false)
            alarmChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            notificationMgr.createNotificationChannel(alarmChannel)



            val fullScreenIntent = Intent(context, LockscreenActivity::class.java).putExtra("alarmId", alarmId)
            //This calls "failure" properly 
            val fullScreenPendingIntent = PendingIntent.getActivity(context, 0, fullScreenIntent,
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)

            //This calls "failure" properly 
            val stop1PendingIntent =
                WorkManager.getInstance(context).createCancelPendingIntent(getId())


            val s2Intent = Intent(context, StopAlarmReceiver::class.java).putExtra("alarmId", alarmId)
            //This is not.
            val stop2PendingIntent = PendingIntent.getBroadcast(context, 1, s2Intent,
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)


           
            val builder = NotificationCompat.Builder(context, ALARM_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle("title")
                .setFullScreenIntent(fullScreenPendingIntent, true)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_ALARM)
                .setAutoCancel(true)
                .setSound(null)
                .setVibrate(null)
                .addAction(R.drawable.ic_stat_name, "Stop1", stop1PendingIntent)
                .addAction(R.drawable.ic_stat_name, "Stop2", stop2PendingIntent)

            setForeground(
                ForegroundInfo(1999999, builder.build(), FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
            )


            ringtoneSound =
                RingtoneManager.getRingtone(context, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))


            ringtoneSound.play()


            delay(30000L)
            ringtoneSound.stop()


            Result.success()

        } catch (e: Exception) {

            Result.failure()

        } finally {

            cleanup()
        }


    }


   fun cleanup(){

       ringtoneSound.stop()
   }
}

在 LockScreenActivity 中,有一个停止铃声的按钮。

binding.stoppingbutton.setOnClickListener {
   val workMgr = WorkManager.getInstance(applicationContext)
   workMgr.cancelUniqueWork("RingWork-$alarmId")
   finish()
}

这将调用“result.failure”和“finally”,然后铃声将停止,通知将消失。工作正常。

但是,如果我按通知上的“Stop2”按钮。

class StopAlarmReceiver: BroadcastReceiver() {
    
    override fun onReceive(context: Context, intent: Intent) {

        val alarmId = intent.getIntExtra("alarmId", 0)
        val workMgr = WorkManager.getInstance(context)
        workMgr.cancelUniqueWork("RingWork-$alarmId")
    }
}

它取消了 worker,但它不会调用“result.failure”和“finally”,所以铃声不会停止。通知也不会消失。

fullScreenPendingIntent 和 stop2PendingIntent 做同样的事情,但为什么它的行为不一样?

【问题讨论】:

    标签: android coroutine android-workmanager


    【解决方案1】:

    您可以编辑您的待定意向像这样,它会触发 onReceive:

    val stop2PendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                PendingIntent.getBroadcast(context, downloadFile.productId, cancelIntent, PendingIntent.FLAG_IMMUTABLE)
            else
                PendingIntent.getBroadcast(context, downloadFile.productId, cancelIntent, 0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-29
      • 2021-01-30
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多