We have created notification channels for devices running on Oreo and above, that use a custom notification sound that is located in our /res/raw
folder. Recently, when users upgraded our app, the notification sound just stopped working and the notification only vibrates the device.
We have confirmed that uninstall/reinstall or clearing app data resolves the issue. However, in order to get notification sounds to work for everyone again without having to reinstall, we need to essentially delete and recreate these channels.
We create the notification channel as follows:
fun initNotificationChannel(channel: PSSNotificationChannel) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val id = channel.id
val name = context.getString(channel.nameResId)
val importance = channel.importance
val channel = NotificationChannel(id, name, importance)
...
// Default sound
val soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
context.applicationContext.packageName + "/" + R.raw.notification)
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build()
channel.setSound(soundUri, audioAttributes)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
notificationManager?.createNotificationChannel(channel)
}
}
I have verified that the file still exists in /res/raw
. And the commit that seemed to cause this was just some added/modified files to the /res
folder.
It seems like this issue setting the soundUri
as follows:
val soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
context.applicationContext.packageName + "/" + R.raw.notification)
It looks like the value of R.raw.notification
changed from 2131689979
(version where sound works) to 2131755515
(version where sound doesn't work). And since you can't change your notification sound with Notification Channels, I am almost certain that the channel is trying to resolve the soundUri
with the old resource id (android.resource://our.package.name/2131689979
).
I think the better approach is to reference the file directly by name as follows:
val soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
context.applicationContext.packageName + "/raw/notification")
I also notice apps like Facebook Messenger and Slack use a public Notifications folder where they probably just copy the file over and reference that exact path. This also seems to allow the user to re-select the app-provided sound because it is visible in the filesystem.