Android推送通知正常展示但提示音播放一段时间后自动停止
问题核心原因
安卓8.0(API 26)及以上版本的通知渠道有个强规则:渠道首次创建完成后,所有配置会被系统持久化存储,后续不管你怎么改代码里的渠道配置、给Notification.Builder重复设置声音/优先级,都不会覆盖已经存在的渠道配置。
你遇到的渠道自动变静音,常见触发场景有三个:
- 之前版本的APP创建过同ID的渠道,当时没配声音、或者设置了低重要级,后续你更新代码加声音配置,系统根本不认
- 用户手动长按通知选了「静音通知」,或者部分用户在勿扰模式下改了该渠道的发声权限
- 国产定制系统的通知智能管控把这个渠道判定为低优先级营销通知,自动给改成静音模式
另外你现有代码还有个兼容问题:已经给渠道配置了声音,就没必要再给NotificationCompat.Builder调用setSound(),安卓8.0以上Builder的声音、震动、优先级配置全都会被渠道配置覆盖,重复设置反而可能在部分厂商机型上触发异常。
修复代码
直接替换你原来的通知逻辑即可:
Uri soundUri1 = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.sound1); NotificationManager notificationManager = context.getSystemService(NotificationManager.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel existingChannel = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID); boolean needRecreateChannel = false; // 检查现有渠道配置是否符合预期 if (existingChannel != null) { if (existingChannel.getImportance() < NotificationManager.IMPORTANCE_HIGH || existingChannel.getSound() == null || !soundUri1.equals(existingChannel.getSound())) { // 配置不对就删了旧渠道 notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); needRecreateChannel = true; } } // 首次创建/需要重建时才初始化渠道 if (existingChannel == null || needRecreateChannel) { NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH); AudioAttributes audioAttributes = new AudioAttributes.Builder() // 警报提示音用USAGE_ALARM比USAGE_NOTIFICATION优先级更高,不容易被系统/勿扰模式静音 .setUsage(AudioAttributes.USAGE_ALARM) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .build(); channel.setSound(soundUri1, audioAttributes); channel.enableVibration(true); channel.setShowBadge(true); notificationManager.createNotificationChannel(channel); } } NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID); builder.setContentTitle(title); builder.setContentText(messageBody); builder.setAutoCancel(true); // 兼容安卓8.0以下版本的优先级配置 builder.setPriority(NotificationCompat.PRIORITY_HIGH); builder.setDefaults(NotificationCompat.DEFAULT_VIBRATE); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); builder.setContentIntent(contentIntent); notificationManager.notify(Tools.getNotificationId(context), builder.build());
补充说明
- 不要每次发通知都删渠道重建,只有检测到配置不符合预期的时候才重建,不然系统会频繁给用户弹应用通知权限相关的警告
- 如果检测到渠道被系统自动设为静音、且重建也不生效(部分国产机型的管控限制),可以弹个原生提示引导用户手动到通知设置页打开该渠道的发声权限
- 普通消息通知可以把
USAGE_ALARM改回USAGE_NOTIFICATION,避免不必要的高优先级权限占用,警报类强提醒场景再用USAGE_ALARM
内容的提问来源于stack exchange,提问作者mehrdad seyrafi
相关产品推荐
相关产品推荐

