Search code examples
androidflutterkotlinpush-notificationfirebase-cloud-messaging

Android notification sound is only updated after clean install


The notification sound on my flutter android app is not updated by installing new version of the app and only will update after I uninstall and reinstall it.

This is my MainActivity.kt:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.media.AudioAttributes
import android.net.Uri
import android.os.Build
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import android.util.Log

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        createNotificationChannel()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            val channelId = "channel_id"
            val channelName = "Channel Name"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel(channelId, channelName, importance)

            val soundUri = Uri.parse("android.resource://" + packageName + "/" + R.raw.alert)
            val audioAttributes = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build()

            channel.setSound(soundUri, audioAttributes)

            val notificationManager = getSystemService(NotificationManager::class.java)

            notificationManager?.deleteNotificationChannel(channelId)

            notificationManager.createNotificationChannel(channel)
        }
    }
}

I thought it was because the existing channel id so I tried to delete it first by using:

 notificationManager?.deleteNotificationChannel(channelId)

I was expecting the notification sound to be updated once I install the new version of the app and not having to uninstall it first.


Solution

  • Why updating a notification sound in Android requires creating a new notification channel ID.

    Notifications: Types and Use:

    • These on scheduling were introduced in Android 8. 0 (Oreo), Notification channels are used as a mechanism for the app to let the user control the way notifications are conducted.
    • Clearly, each channel is assigned a particular ID, and can be set to possess specific parameters such as the priority level (high, low, etc. ), strident buzz, or resonant sound.
    • Any time your app creates a notification it attaches it to a particular channel ID. The system then uses at the setting of the channel which will dictate how it is presented to the particular user.

    Why Updating Sound Requires a New Channel:

    • The most profound idea is around which the system determines the notification channels. In particular, the system only uses the channel ID to distinguish channels originating from your app.
    • If you replace the sound used to represent one channel ID with another, the system is still going to regard it as the same channel since the ID does not change.
    • Consequently, the new sound would not be set on the notifications that uses such a channel ID. This is because the system always know about the channel (including the old sound) if it has known the channel ID.

    New Channel ID :

    • You need to create a new channel ID but with the required sound settings.
    • Now ID are different, the system identifies it as the channel for your app, but also gets the new sound data corresponding to the new channel.
    • This in effect causes the system to update the channel in its memory and apply the new sound settings. Which makes it work.

    Delete Old Channel :

    fun deleteOldChannel(context: Context, oldChannelId: String) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationManager = context.getSystemService(NotificationManager::class.java)
        notificationManager?.deleteNotificationChannel(oldChannelId)
      }
    }
    

    Create New Notification Channel:

    fun createNotificationChannel(context: Context, channelId: String, channelName: String, channelDescription: String) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_ CODES.O) {
        val notificationManager = context.getSystemService(NotificationManager::class.java)
        val importance = NotificationManager.IMPORTANCE_HIGH
        val channel = NotificationChannel(channelId, channelName, importance)
        channel.description = channelDescription
    
        // Configure the sound
        val soundUri = getSoundUri(context) // Get sound URI from helper function (see below)
        val audioAttributes = AudioAttributes.Builder()
          .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
          .setUsage(AudioAttributes.USAGE_NOTIFICATION)
          .build()
        channel.setSound(soundUri, audioAttributes)
    
        notificationManager?.createNotificationChannel(channel)
      }
    }
    
    // Helper function to get sound URI (replace with your sound file)
    private fun getSoundUri(context: Context): Uri {
      return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
      // OR: You can use a custom sound from raw resources
      // return Uri.parse("android.resource://" + context.packageName + "/" + R.raw.your_sound_file)
    }
    

    Advantages Accrued by Using the Same ID:

    • That means, users won’t be able to find a note and immediately switch to a news channel on the assumption that they have been reset. Their notification settings (e. g. Existing objects (Processor, FAQ, importance, vibration) related to the old channel ID will remain intact.
    • It prevents issues that might arise in case the selected name has already been used by a different channel and has specific configuration options set by the user.

    Notes:

    • Yes, to clarify, deleting the old channel / creating a new one with the correct sound actually does the trick, but that is rarely a good way to solve issues. Deleting a channel / erases all user developed settings which can prove to be even more inconvenience.
    • This is the reason why it’s crucial to address what can be situations where the user has possibly uninstalled or disabled the app prior to the update. To do this, you may need to create the channel again during app launch to use this primary sound only. This way, android app developer can handle the notification channels, the channel ID, and the notification sounds to ensure that their users are always provided with an effective experience in spite of changes in the sound notification for the app.

    More stuffs to read :

    https://developer.android.com/develop/ui/views/notifications/channels

    https://medium.com/android-news/android-notifications-an-elegant-way-to-build-and-display-7771d65ba3a2