当应用程序在后台运行时,本地通知不起作用

时间:2020-04-17 07:32:22

标签: java android kotlin alarmmanager android-notifications

我正在自己学习警报管理器。为此,我一直在使用警报管理器来设置警报,然后使用广播接收器来处理警报触发代码。

我的警报设置如下:

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设备上进行测试,我做错了什么,请您确认。预先感谢

0 个答案:

没有答案