【问题标题】:Android Notification Channel sounds stop working when using sound URIs that reference resource ids使用引用资源 id 的声音 URI 时,Android 通知通道声音停止工作
【发布时间】:2019-02-20 22:48:34
【问题描述】:

我们为在 Oreo 及更高版本上运行的设备创建了通知通道,这些通道使用位于我们 /res/raw 文件夹中的自定义通知声音。最近,当用户升级我们的应用程序时,通知声音刚刚停止工作,通知只是振动设备。

我们已确认卸载/重新安装或清除应用数据可解决此问题。但是,为了让通知声音再次为所有人工作而无需重新安装,我们需要从根本上删除并重新创建这些频道。

我们创建通知通道如下:

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)
        }
    }

我已验证该文件仍然存在于/res/raw 中。似乎导致这种情况的提交只是在/res 文件夹中添加/修改了一些文件。

【问题讨论】:

    标签: android android-notifications android-8.0-oreo android-9.0-pie


    【解决方案1】:

    似乎这个问题设置soundUri如下:

    val soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                        context.applicationContext.packageName + "/" + R.raw.notification)
    

    看起来R.raw.notification 的值从2131689979(声音有效的版本)更改为2131755515(声音无效的版本)。而且由于您无法使用通知通道更改通知声音,因此我几乎可以肯定该通道正在尝试使用旧资源 ID (android.resource://our.package.name/2131689979) 解析 soundUri

    我认为更好的方法是直接按名称引用文件如下:

    val soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                        context.applicationContext.packageName + "/raw/notification")
    

    我还注意到 Facebook Messenger 和 Slack 等应用程序使用公共通知文件夹,他们可能只是将文件复制到该文件夹​​并引用该确切路径。这似乎也允许用户重新选择应用程序提供的声音,因为它在文件系统中可见。

    【讨论】:

    • 就是这样!我已经看这个有一段时间了。首先,应用程序提供的声音运行良好,但通常在几周后就停止了。非常感谢。
    • 我尝试通过直接使用字符串名称以您建议的方式设置通知通道的声音,但我仍然收到 FileNotFound 异常,它试图查找旧的资源 ID。 (即MediaPlayer: Couldn't open android.resource://<appname>/2131099651: java.io.FileNotFoundException)从推送中的通道 id 到声音 uri 的实际映射是什么?
    • 事实证明,即使资源 id 发生变化,在 uri 中使用字符串确实有效,但前提是从另一个也使用基于字符串的 uri 的应用程序版本升级。因此,如果您以前的版本在 uri 中使用了资源 id,那么具有基于字符串的 uri 的较新版本将不起作用。
    • 我发现为此打开了一个 android 问题。如果您遇到此问题,请加注星标。 issuetracker.google.com/issues/131303134
    • @efeder 是的,我们必须使用基于字符串的资源将所有用户迁移到新的通知渠道。我们通过在我们的频道 ID 中添加 version 后缀来做到这一点,这样我们就可以找到/删除旧频道并创建新频道(如果它们不存在)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2012-07-01
    相关资源
    最近更新 更多