禁用NotificationChannel中的声音

时间:2017-08-28 12:44:43

标签: android notifications

今天我开始针对API 26,这迫使我使用通知渠道。

我的问题是,现在每次发出新通知(包括更新通知)都会播放恼人的声音。

如何禁用此声音?

我尝试用自定义的mp3声音替换这个声音,然后在其中传递一个静音的mp3,但这被忽略了。

我只是添加一个优先级非常低的通知,基本上让用户可以选择在与应用程序交互后执行某些操作。没有理由大声说话,用户会知道他可以参考通知,因为他已经对应用程序做了一些他知道会导致通知出现的事情。

用户真的会开始对这种声音感到烦恼。

17 个答案:

答案 0 :(得分:84)

如果您想保持频道的重要性,只需删除声音val source = Source.fromFile("pathtothefile") val lines = source.getLines.mkString 似乎可以完成这项工作。

修改 确保重命名频道(并删除旧频道)以将其应用于现有用户。 (可以创建频道,但不会被应用修改,只有用户可以修改。)

答案 1 :(得分:72)

(更新2019-05:Android Q越来越糟糕,我甚至在使用NotificationManager.IMPORTANCE_LOW时都会发出声音,至少在模拟器中... ...

解决方案是使用NotificationManager.IMPORTANCE_LOW并为其创建新频道。创建频道后,您无法改变重要性(嗯,您可以,但忽略新的重要性)。频道信息似乎由系统永久存储,并且只有在您卸载应用程序时才会删除创建的任何频道。 [更新:根据Ferran Negre的评论,您可以通过nm.deleteNotificationChannel(nChannel.getId());删除该频道,然后使用nm.createNotificationChannel(nChannel);重新创建该频道,但显然有{&};限制,您无法创建与已删除频道的ID相同的频道,并希望能够对未删除的频道应用不同的设置,请参阅acoder的答案]

虽然以前的Android版本在默认情况下没有播放声音,但是这已经改变了Android O,但只有当您定位API 26时,即使用通知频道。这是不一致的,实际上,这是一个错误:

这样做的原因是,当您使用NotificationManager.IMPORTANCE_DEFAULT创建频道时(默认情况下不值得),Android实际上会在某种程度上"将其注册为NotificationManager.IMPORTANCE_HIGH(默认播放声音)。

您可以通过进入通知选项(长按通知条目)来检查这一点,在那里您将看到它是NotificationManager.IMPORTANCE_HIGH类型,然后禁用通知,然后重新启用它。在这个过程中,它会降级"降级"从NotificationManager.IMPORTANCE_HIGH到不发声,实际注册NotificationManager.IMPORTANCE_DEFAULT

The bug has been submitted to the Android issue tracker, so you may want to star it(谷歌标记为"赢得&#t;修复(不可行)",因为...被宠坏了。)

BTW,https://developer.android.com/training/notify-user/channels的新文档 声称默认行为曾经是那种方式,默认在Android 8.0之前发出声音,绝对不是真的。这是他们的清单

User-visible importance level           Importance               Priority   
                                        (Android 8.0 and higher) (Android 7.1 and lower)
Urgent  Makes a sound and appears as    IMPORTANCE_HIGH          PRIORITY_HIGH
        a heads-up notification                                  or PRIORITY_MAX
High    Makes a sound                   IMPORTANCE_DEFAULT       PRIORITY_DEFAULT
Medium  No sound                        IMPORTANCE_LOW           PRIORITY_LOW
Low     No sound and does not appear    IMPORTANCE_MIN           PRIORITY_MIN
        in the status bar

你甚至可以看到能见度重要性和通知重要性之间的不匹配......我不知道他们为什么这样做。他们的代码肯定有错误。

下一行下面的所有内容都已过时,但那里提到的那个bug仍然有效。我的错误是认为NotificationManager.IMPORTANCE_MIN是来自NotificationManager.IMPORTANCE_DEFAULT的下一个较低的一个,但NotificationManager.IMPORTANCE_LOW是。

然后,当您通过长按通知和所有频道按钮进入应用的通知设置并关闭该频道的开关并再次打开时,它实际上将自己设置为NotificationManager.IMPORTANCE_DEFAULT而不是声音将被播放。我还注意到崩溃后它确实重置为NotificationManager.IMPORTANCE_HIGH

所以基本上解决方法是使用NotificationManager.IMPORTANCE_MIN。但是您必须创建一个新频道,以便此NotificationManager.IMPORTANCE_MIN生效,因为看起来一旦您创建了频道,就无法改变现有频道的重要性

更新:使用NotificationManager.IMPORTANCE_MIN解决方法有一个缺点。

当您使用该重要性级别时,您的通知不再完全显示在通知抽屉内,而是将其自身插入到默认折叠的新通知通道组中(并且每次拉下抽屉时它将再次折叠)。真可惜!

更新2:更深入地发现它就好像它正确地将其注册为NotificationManager.IMPORTANCE_DEFAULT,但不知怎的,它神奇地升级到NotificationManager.IMPORTANCE_HIGH,就像当用户明确地将设置从默认更改为高时。在关闭通知然后再打开之后,那个也会重置为默认值。

答案 2 :(得分:4)

好吧,我会添加一个完整的答案来提供帮助。如果您从 androidx 读取 NotificationCompat 代码。

   /**
     * Silences this instance of the notification, regardless of the sounds or vibrations set
     * on the notification or notification channel.
     */
    public @NonNull Builder setNotificationSilent() {
        mSilent = true;
        return this;
    }

所以你必须像这样使用如果你想消除声音和振动

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            // no sound or vibration
            .setNotificationSilent()

如果您只想去除声音。这就是方法。

 // no sound
 builder.setSound(null);

如果您只想删除病毒。

 // no vibration
 mChannel.setVibrationPattern(new long[]{ 0 });
 mChannel.enableVibration(true);

答案 3 :(得分:2)

NotificationManager.IMPORTANCE_LOW

创建通知时它没有声音,因为我的音乐应用程序中也需要同样的声音。

是的,如果您已经创建了一个通知频道,则您需要更改频道ID或直接卸载以前的应用程序并重新安装。

答案 4 :(得分:2)

对我来说,解决方案是创建群组通知

val builder = NotificationCompat.Builder(this)
        .setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
        .setGroup("My Group")
        .setGroupSummary(false)
        .setDefaults(DEFAULT_ALL)
        .setSound(null)

但是在这种情况下,如果您发送带有新ID的新通知,则它将与以前的通知分组。

答案 5 :(得分:2)

我已经测试了很多android设备,以下代码对我来说正常工作

首先,创建一个notificationBuilder,如果您的Build.Version大于26,请添加一个新频道。

  private val notificationBuilder: NotificationCompat.Builder by lazy {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) NotificationCompat.Builder(context) else {
            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val channelId = "MUSIC"
            val channelName = "音乐控制栏"
            val importance = NotificationManager.IMPORTANCE_MIN
            val channel = NotificationChannel(channelId, channelName, importance)

            manager.createNotificationChannel(channel)
            channel.enableLights(false)
            channel.vibrationPattern = longArrayOf(0L)
            channel.enableVibration(false)
            channel.setSound(null, null)
            NotificationCompat.Builder(context, channelId)
        }

    }

第二,初始化此notificationBuilder,并将声音设置为空

   notificationBuilder.setDefaults(Notification.DEFAULT_LIGHTS ).setVibrate( longArrayOf(0L)).setSound(null)

第三,如果build.version大于24,请设置其优先级。

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            notificationBuilder.priority = NotificationManager.IMPORTANCE_MIN
        }

希望对您有用。

答案 6 :(得分:1)

据我所知,自API 26(Oreo)起,通知一旦创建便无法更改。

    notificationManager.deleteNotificationChannel("channel_id"));
    NotificationChannel notificationChannel = new NotificationChannel(
        "channel_id", "channel_name",
        NotificationManager.IMPORTANCE_HIGH);
    notificationChannel.setSound(null, null);
    notificationManager.createNotificationChannel(notificationChannel);

即使在创建频道之前删除频道也没有帮助。

Google 文档说:

  

android.app.NotificationManager public void deleteNotificationChannel(String channelId)

     

删除给定的通知渠道。   如果您使用相同的ID创建一个新频道,则删除的频道将被删除,并具有与删除前相同的所有设置。

NotificationChannel#setSound()文档状态

  

仅在将频道提交给NotificationManager#createNotificationChannel(NotificationChannel)

之前可以修改

太糟糕了,notificationBuilder.setSound(defaultSoundUri)不能正常工作:

  

此方法已在API级别26中弃用。改为使用NotificationChannel#setSound(Uri,AudioAttributes)。

也无法使用支持库。因此,声音只能在应用程序中设置一次,并且用户只能在通知设置中进行更改。对我来说,Ferran Negre's评论不起作用。我不明白为什么 Google 设置了此限制。太糟糕了。

答案 7 :(得分:1)

NotificationCompat.Builder.setSilent(true)

这使您可以发布无声通知(无声音或振动),而与频道的重要性设置无关。

参考: https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder#setSilent(boolean)

答案 8 :(得分:0)

如果情况像我的一样,我被迫向后台服务显示通知,而我真的不想向任何通知显示适用于8.0的解决方案是:

.setPriority(NotificationManager.IMPORTANCE_NONE)

不仅如此,我没有每隔5分钟就听到烦人的声音,而且使通知本身的外观最小化了。

在8.1上,我没有以下声音的问题:

.setPriority(NotificationManager.IMPORTANCE_MIN)

答案 9 :(得分:0)

您可以使用2个不同的通知通道来发送通知,具体取决于用户的优先级。

如果它是高优先级通知,则通过

发送
new NotificationChannel("Channel ID", "Channel Name", NotificationManager.IMPORTANCE_HIGH);

您的用户在收到通知时会听到声音并弹出。

如果您要发送不太重要的通知,请使用此频道。

new NotificationChannel("Channel ID", "Channel Name", NotificationManager.IMPORTANCE_LOW);

您的用户将收到没有声音的通知并弹出。

从此处检查其他优先级-https://developer.android.com/reference/android/app/NotificationManager

答案 10 :(得分:0)

.banner { background: url("/assets/images/banner.jpg") no-repeat}

下面的代码是关于通知的,但是声音,振动不会在API 26上播放,所以不必担心setound或setvibrate

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(
                channelId.toString(), title,
               NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationChannel.setSound(null,null)
            notificationChannel.enableVibration(false)
            notificationChannel.description = body
            if(notificationManager.getNotificationChannel(channelId.toString())==null) {
                notificationManager.createNotificationChannel(notificationChannel)
            }
            if (data["sound"]?.equals("default", true) == true) {//if your app need contorl sound enable
                RingtoneManager.getRingtone(
                    this,
                    RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
                ).play()
            }
            if(pushShake.isTrue() ){//if your app need contorl vibarate enable
               val vbmanager=  getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
                vbmanager.vibrate(VibrationEffect.createOneShot(500,VibrationEffect.DEFAULT_AMPLITUDE))
            }
        }

答案 11 :(得分:0)

由于IMPORTANCE解决方案具有没有通知弹出窗口的副作用,所以我得到的最终解决方案是:

  1. 添加从回购库下载的无声声音资源
  2. 使用无声声音资源为频道设置声音。

https://github.com/anars/blank-audio/blob/master/1-second-of-silence.mp3

答案 12 :(得分:-1)

我在8.1中遇到了相同的问题,并进行了以下更改。将通知的优先级更改为“低”,它将禁用通知声音。

NotificationManager.IMPORTANCE_LOW

代码如下:

NotificationChannel chan1 = new NotificationChannel("default", "default", NotificationManager.IMPORTANCE_LOW);

答案 13 :(得分:-1)

NotificationManager.IMPORTANCE_LOW

这将起作用,但也会折叠您的通知。

答案 14 :(得分:-1)

无需使用.setSound(null, null)

只使用下面的代码

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,
                getString(R.string.notification_channel_id))
                .setContentTitle("Audio Recording")
                .setContentText("recording in progress")
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .setSmallIcon(R.mipmap.ic_launcher);

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    getString(R.string.notification_channel_id), "AOD+", NotificationManager.IMPORTANCE_LOW
            );
            channel.setDescription("Call Recorder is running");
            channel.setShowBadge(true);
            channel.canShowBadge();
            channel.setLightColor(Color.GREEN);
            channel.enableVibration(false);

            assert notificationManager != null;
            notificationManager.createNotificationChannel(channel);
        }

        assert notificationManager != null;
        startForeground(256/* must be greater than 0*/, notificationBuilder.build()); //I am using this for audio recording
        //notificationManager.notify(0, notificationBuilder.build());

答案 15 :(得分:-1)

首先你需要设置

importance = NotificationManager.IMPORTANCE_LOW;

然后

Notification n = builder.setPriority(Notification.DEFAULT_ALL).build();
n.defaults = 0;
n.defaults |= Notification.DEFAULT_VIBRATE;

答案 16 :(得分:-2)

NotificationManager.IMPORTANCE_LOW肯定可以工作