Локальное уведомление не работает, когда приложение в фоновом режиме - PullRequest
0 голосов
/ 17 апреля 2020

Я изучаю диспетчер сигнализации самостоятельно. Для этого я использовал свой диспетчер тревог для настройки тревоги, а затем использовал широковещательный приемник для обработки кода триггера тревоги.

Моя настройка тревоги следующая:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        //set the alarm while in the doze mode
        //when the device is not in use by the user
        //the device when goes in idle/doze mode
        alarmMgr.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            calSet.timeInMillis,
            getPendingIntentForPrayersAlarm(context, alarmId)
        )
}

, тогда как Метод намерения:

fun getPendingIntentForPrayersAlarm(context: Context, id: Int): PendingIntent {
    val alarmIntent = Intent(context, MultipleAlarmsReciever::class.java)
    alarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
    alarmIntent.putExtra("notificationId", id)
    return PendingIntent.getBroadcast(context, id, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}

, класс приемника вещания:

class MultipleAlarmsReciever : BroadcastReceiver() {

    private val alarmManagerId = "alarmManagerTest1289Id"
    private var nameOfAlarm = 0

    override fun onReceive(context: Context?, intent: Intent?) {
        Log.e("timeX", "Broadcast receives")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
           val serviceIntent = Intent(context, MultipleAlarmsManagerService::class.java)
           serviceIntent.putExtra("alarmName", alarmName)
           ContextCompat.startForegroundService(context, serviceIntent)
        } else {
           val serviceIntent = Intent(context, MultipleAlarmsManagerService::class.java)
           context.stopService(serviceIntent)
           serviceIntent.putExtra("alarmName", alarmName)
           context.startService(serviceIntent)
        }
    }//onReceive ends
}

, класс обслуживания:

, класс MultipleAlarmsManagerService: Service () {

// Binder given to clients
private val binder = LocalBinder()
private val alarmManagerId = "alarmManagerTest1226Id"
private var alarmName = ""
private var mediaPlayer: MediaPlayer? = null

override fun onCreate() {
    super.onCreate()
}//onCreate ends

private fun playCallingRingTone(context: Context) {
    try {
        mediaPlayer = MediaPlayer.create(context,
            R.raw.ringtone
        )
        if (mediaPlayer != null) {
            mediaPlayer!!.isLooping = false
            mediaPlayer!!.start()
        }
    } catch (exp: Exception) {
        Log.e("timeX", "error:Play:Ringtone:".plus(exp.toString()))
    }
}//playRingTone ends

private fun killMediaPlayer() {
    if (mediaPlayer != null && mediaPlayer!!.isPlaying) {
        mediaPlayer!!.stop()
    }
}//killMediaPlayer ends

override fun onBind(intent: Intent?): IBinder? {
    return binder
}//onBind ends

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    val bundle = intent!!.extras
    if (bundle != null) {
        Log.e("timeX", "bundle is not null in service")
        alarmName = bundle.getString("alarmName")!!
    }

    playCallingRingTone(this@MultipleAlarmsManagerService)

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        showOreoBasedNotification(this@MultipleAlarmsManagerService, "Alarm Ringing", alarmName)
    } else {
        showBelowOreoNotification(this@MultipleAlarmsManagerService, "Alarm Ringing", alarmName)
    }
    return START_STICKY
}//onStartCommand ends

/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
inner class LocalBinder : Binder() {
    // Return this instance of LocalService so clients can call public methods
    fun getService(): MultipleAlarmsManagerService = this@MultipleAlarmsManagerService
}//inner class ends

override fun onDestroy() {
    super.onDestroy()
    killMediaPlayer()
}//onDestroy ends

override fun onTaskRemoved(rootIntent: Intent?) {
    super.onTaskRemoved(rootIntent)
}//onTaskRemoved ends

private fun showOreoBasedNotification(
    context: Context,
    title: String,
    alarmName: String
) {
    val uniqueId = (Date().time / 1000L % Integer.MAX_VALUE)

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

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {

        val importance = NotificationManager.IMPORTANCE_HIGH
        val mChannel = NotificationChannel(
            alarmManagerId,
            "TestingAlarmManager",
            importance
        )
        mChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
        mChannel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
        mChannel.description = "TestingAlarmManagerDescription"
        mChannel.enableLights(true)
        mChannel.lightColor = Color.MAGENTA
        mChannel.enableVibration(true)
        mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
        mChannel.setShowBadge(true)
        notificationManager.createNotificationChannel(mChannel)
    }

    val intent = Intent(context, MainActivity::class.java)

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
    val pendingIntent =
        PendingIntent.getActivity(
            context,
            uniqueId.toInt(),
            intent,
            PendingIntent.FLAG_ONE_SHOT
        )
    val builder = NotificationCompat.Builder(
        context,
        alarmManagerId
    ).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
        .setSmallIcon(R.drawable.clock)
        .setColor(context.resources.getColor(android.R.color.transparent))
        .setLargeIcon(
            BitmapFactory.decodeResource(
                context.resources,
                R.drawable.clock
            )
        )
        .setContentTitle(title)
        .setContentText(alarmName)
        .setStyle(
            NotificationCompat.BigTextStyle()
                .bigText(alarmName)
        )
        .setAutoCancel(true)
        .setContentIntent(pendingIntent)

    notificationManager.notify(uniqueId.toInt(), builder.build())
}

private fun showBelowOreoNotification(
    context: Context,
    title: String,
    alarmName: String
) {
    val uniqueId = (Date().time / 1000L % Integer.MAX_VALUE)
    val intent = Intent(context, MainActivity::class.java)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
    val pendingIntent =
        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)

    val builder = NotificationCompat.Builder(context)
        .setSmallIcon(R.drawable.clock)
        .setColor(context.resources.getColor(R.color.colorPrimary))
        .setLargeIcon(
            BitmapFactory.decodeResource(
                context.resources,
                R.drawable.clock
            )
        ).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
        .setContentTitle(title)
        .setStyle(
            NotificationCompat.BigTextStyle()
                .bigText(alarmName)
        )
        .setContentText(alarmName)
        .setAutoCancel(true)
        .setContentIntent(pendingIntent)

    val notificationManager =
        context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.notify(uniqueId.toInt(), builder.build())
}

} // класс обслуживания заканчивается

Проблема, с которой я сталкиваюсь, состоит в том, что мое уведомление не появляется, и сигнал тревоги не звонит, когда приложение находится в фоновом режиме, я имею в виду, когда я устанавливаю сигнал тревоги, и если я оставляю свое приложение на какое-то время, например, на 15 минут, а затем, когда срабатывает сигнал тревоги, уведомление не генерируется!

Я тестирую на устройстве oreo, что я делаю неправильно, может кто-нибудь, пожалуйста, идентифицировать. Заранее спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...