Android 8.0(Oreo)自定义通知音效不生效问题求助
Android 8.0+自定义通知音效不生效问题排查与解决
您好,我在项目中使用以下代码实现通知功能,通知可正常运行,但为适配Android 8.0添加的自定义音效无法生效,仍使用手机默认通知音效。
代码如下:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Uri mysound = null; if(sound.equalsIgnoreCase("visitor_long")) { mysound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator + getPackageName()+ "/res" + "/raw/" + sound + ".wav"); } else{ mysound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + this.getPackageName() + "/raw/" + sound); } AudioAttributes attributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build(); NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, contentTitle, NotificationManager.IMPORTANCE_HIGH); // Configure the notification channel. mChannel.setDescription(message); mChannel.enableLights(true); mChannel.enableVibration(true); mChannel.setSound(mysound, attributes); // This is IMPORTANT if (notificationManager != null) notificationManager.createNotificationChannel(mChannel); } if(notificationManager != null ) { if(message != null) { int messageHash = message.hashCode(); notificationManager.notify(messageHash, notificationBuilder.build()); } } 我已参考相关内容但问题仍未解决
我帮你排查了下代码里的几个关键点,大概率是这几个问题导致的:
URI构造错误:你在
visitor_long分支里的URI写法有问题,误用了File.pathSeparator(这是系统的路径分隔符,比如Windows是;,Linux是:),正确的Android资源URI格式应该是android.resource://包名/资源类型/资源名。而且raw目录下的资源不需要加后缀,系统会自动识别,所以这个分支的URI应该改成和else分支一致的写法,或者直接统一用下面的构造方式:Uri mysound = Uri.parse("android.resource://" + getPackageName() + "/raw/" + sound);通知通道创建后无法修改:Android 8.0+的通知通道是一旦创建就无法通过代码修改配置的!如果之前你已经用这个
CHANNEL_ID创建过通道,哪怕现在改了音效代码,手机里留存的旧通道配置还是会生效,自然用的是默认音效。解决办法很简单:要么卸载重装App清除旧通道,要么临时修改CHANNEL_ID的值来测试新配置,确认生效后再考虑正式版本的处理(比如版本更新需要改音效的话,可以创建新通道,或者引导用户去系统设置里手动修改旧通道)。额外检查项:
- 确保
raw目录下确实存在对应的音效文件,文件名要完全匹配(注意Android资源文件名是区分大小写的); - 检查你的
notificationBuilder有没有额外设置音效,虽然O+是通道管音效,但如果Builder里设置了默认音效可能会有冲突; - 可以给
AudioAttributes加上setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION),明确是通知类音效,兼容性更好。
- 确保
下面是修正后的示例代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 统一正确的URI构造方式 Uri mysound = Uri.parse("android.resource://" + getPackageName() + "/raw/" + sound); AudioAttributes attributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_NOTIFICATION) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) // 明确音效类型 .build(); NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, contentTitle, NotificationManager.IMPORTANCE_HIGH); mChannel.setDescription(message); mChannel.enableLights(true); mChannel.enableVibration(true); mChannel.setSound(mysound, attributes); if (notificationManager != null) { // 注意:通道已存在时修改不生效,测试时先卸载App或换CHANNEL_ID notificationManager.createNotificationChannel(mChannel); } } // 构建通知时确保关联正确的通道,且不要额外设置音效 NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) // 其他必要配置(比如小图标、标题、内容等) .setPriority(NotificationCompat.PRIORITY_HIGH); // 和通道的IMPORTANCE_HIGH对应 if(notificationManager != null && message != null) { int messageHash = message.hashCode(); notificationManager.notify(messageHash, notificationBuilder.build()); }
内容的提问来源于stack exchange,提问作者Arrie
相关产品推荐
相关产品推荐

