Я изучаю диспетчер сигнализации самостоятельно. Для этого я использовал свой диспетчер тревог для настройки тревоги, а затем использовал широковещательный приемник для обработки кода триггера тревоги.
Моя настройка тревоги следующая:
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, что я делаю неправильно, может кто-нибудь, пожалуйста, идентифицировать. Заранее спасибо