Notification not showing on Android 10 and above when the app is closed, but works on lower versions

78 Views Asked by At

I'm trying to display a notification using the AlarmManager at a specific date, but I'm encountering issues on Android 10 and above. The notification only appears when the app is running. However, when the app is closed, the notification doesn't show up. Can you help me identify the potential problems in the provided code?

For Broadcast Reciever

class MyNotificationReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        val taskId = intent?.getIntExtra("taskId", -1)

        if (taskId != null && taskId != -1) {
            val serviceIntent = Intent(context, MyForegroundService::class.java).apply {
                putExtra("taskId", taskId)
            }
            ContextCompat.startForegroundService(context!!, serviceIntent)
        }

In manifest

<activity
    android:name=".MyNotificationActivity"
    android:showWhenLocked="true"
    android:turnScreenOn="true"
    android:exported="false" />

<service
    android:name=".utils.MyForegroundService"
    android:enabled="true"
    android:exported="false"
    android:foregroundServiceType="location"
    >
</service>
class MyForegroundService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val taskId = intent?.getIntExtra("taskId", -1)

        if (taskId != null && taskId != -1) {
            // Load the task from the database using a coroutine
            val myTaskDao = AppDatabase.getDatabase(this).myTaskDao()
            GlobalScope.launch {
                val myTask = myTaskDao.getMyTaskById(taskId)

                // Create the notification channel
                createNotificationChannel()

                // Create the notification intent
                val notificationIntent =
                    Intent(this@MyForegroundService, MyNotificationActivity::class.java).apply {
                        putExtra("taskId", taskId)
                    }
                val pendingIntent = PendingIntent.getActivity(
                    this@MyForegroundService,
                    taskId,
                    notificationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )

                val sharedPreferences = getSharedPreferences("currency_prefs", Context.MODE_PRIVATE)
                val selectedCurrency = sharedPreferences.getString("selected_currency", "USD")
                val currencySymbols = mapOf("USD" to "$", "EUR" to "€", "GBP" to "£", "JPY" to "¥")
                // Get the symbol for the selected currency
                val selectedCurrencySymbol = currencySymbols[selectedCurrency] ?: "$"

                // Create the notification
                val notification = NotificationCompat.Builder(this@MyForegroundService, CHANNEL_ID)
                    .setContentTitle("Payment for ${myTask[0].description}")
                    .setContentText("Total amount ${selectedCurrencySymbol + myTask[0].price} is due.")
                    .setSmallIcon(myTask[0].image)
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setContentIntent(pendingIntent) // Set the pending intent
                    .setAutoCancel(false) // Make the notification dismiss when clicked
                    .build()

                // Start the service in the foreground
                startForeground(NOTIFICATION_ID, notification)
            }
        }

        // Return START_STICKY to ensure the service is restarted if it gets killed by the system
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelName = "My Channel"
            val channelDescription = "Notification Channel"

            val importance = NotificationManager.IMPORTANCE_HIGH

            val channel = NotificationChannel(CHANNEL_ID, channelName, importance).apply {
                description = channelDescription
            }

            val notificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }


    override fun onTaskRemoved(rootIntent: Intent?) {
        val restartServiceIntent = Intent(applicationContext, this.javaClass)
        restartServiceIntent.setPackage(packageName)
        val restartServicePendingIntent = PendingIntent.getService(
            applicationContext, 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT
        )
        val alarmService: AlarmManager =
            applicationContext.getSystemService(ALARM_SERVICE) as AlarmManager
        alarmService.set(
            AlarmManager.ELAPSED_REALTIME,
            SystemClock.elapsedRealtime() + 1000,
            restartServicePendingIntent
        )
        super.onTaskRemoved(rootIntent)
    }


In Activity

  val alarmManager =
                            requireActivity().getSystemService(Context.ALARM_SERVICE) as AlarmManager
                        val intent = Intent(requireActivity(), MyNotificationReceiver::class.java)
                        intent.putExtra("taskId", myTaskId.toInt())
//
                        val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                            PendingIntent.getBroadcast(
                                requireContext(),
                                0,
                                intent,
                                PendingIntent.FLAG_MUTABLE // add the FLAG_MUTABLE flag here
                            )
                        } else {
                            PendingIntent.getBroadcast(requireContext(), 0, intent, 0)
                        }
// Set the alarm to start at the specified time
                        alarmManager.set(AlarmManager.RTC_WAKEUP, customTime, pendingIntent)



    private val CHANNEL_ID = "my_channel"
    private val NOTIFICATION_ID = 1
0

There are 0 best solutions below