Вимкнути звук із NotificationChannel


80

Сьогодні я почав націлюватися на API 26, що змусило мене використовувати канали сповіщень.

Моя проблема полягає в тому, що тепер при кожному новому сповіщенні (включаючи оновлення до нього) відтворюється дратівливий звук.

Як я можу вимкнути цей звук?

Я спробував замінити цей звук на користувальницький звук mp3, щоб потім передати йому mp3 із тиші, але це ігнорується.

Я просто додаю повідомлення, яке має дуже низький пріоритет, в основному даючи користувачеві можливість виконувати деякі дії після того, як він взаємодіє з додатком. Немає жодної причини бути голосним, користувач буде знати, що він може посилатися на сповіщення, оскільки він зробив певну справу з додатком, який, як він знає, призведе до появи сповіщення.

Користувач справді почне дратуватися від цього звуку.

Відповіді:


122

Якщо ви хочете зберегти важливість свого каналу і просто видалити звук, notificationChannel.setSound(null, null);здається, це добре.

РЕДАГУВАТИ: переконайтеся, що перейменували канал (і видалили старий), щоб застосувати його до існуючих користувачів. (Канали можуть створюватися, але ніколи не змінюватися програмою, лише користувач може.)


20
Видаліть / переінсталюйте або просто перейменуйте NotificationChannel.
Bjarte Aune Olsen

канал можна видалити за допомогою API, для цього не потрібно видаляти програму
SolidSnake

1
Я думаю, що кращим рішенням є використання NotificationManager.IMPORTANCE_DEFAULT. Це відключає звук і є хорошим варіантом для важливості. Зверніть увагу, що якщо ви використовуєте NotificationManager.IMPORTANCE_HIGHодне і те ж сповіщення кілька разів, воно буде з’являтися. Використання IMPORTANCE_DEFAULTтакож запобігає повторному появі цього сповіщення, якщо ви показуєте те саме сповіщення.
Markymark

15
@Markymark НЕПРАВИЛЬНО Я використовував NotificationManager.IMPORTANCE_DEFAULTі все ще пролунав звук, коли створюється сповіщення
user924

2
NotificationManager.IMPORTANCE_LOW працює для мене у моїй музичній програмі, щоб вимкнути звук.
Akash Bisariya

96

(Оновлення 2019-05: Погіршується з Android Q, там я навіть отримую звук під час використання NotificationManager.IMPORTANCE_LOW, принаймні в емуляторі ...)


Рішення полягає у використанні NotificationManager.IMPORTANCE_LOWта створенні нового каналу для нього. Після створення каналу ви не можете змінити важливість (ну, можете, але нова важливість ігнорується). Здається, інформація про канал постійно зберігається системою, і будь-який створений канал видаляється лише при видаленні програми. [ Оновлення : Відповідно до коментаря Феррана Негре , ви можете видалити канал за допомогою nm.deleteNotificationChannel(nChannel.getId());і відтворити його за допомогою, nm.createNotificationChannel(nChannel);але, очевидно, існує обмеження, що ви не можете створити канал з однаковим ідентифікатором видаленого каналу і очікуєте, що зможете застосувати різні налаштування для відновленого каналу, див . відповідь кодера ]

Хоча попередні версії Android за замовчуванням не відтворювали жодного звуку, це змінилося з Android O, але лише тоді, коли ви націлюєтесь на API 26, тобто використовуєте канали сповіщень. Це суперечливість, ну, насправді, це помилка:

Причиною цього є те, що коли ви створюєте канал із NotificationManager.IMPORTANCE_DEFAULT(не за вартістю за замовчуванням) Android насправді "дещо" реєструє його як NotificationManager.IMPORTANCE_HIGH(за замовчуванням відтворює звук).

Ви можете перевірити це, перейшовши до опцій сповіщень (довге натискання на запис сповіщення), де ви зможете прочитати, що воно типу, NotificationManager.IMPORTANCE_HIGHа потім вимкнути сповіщення, а потім увімкнути його знову. У цьому процесі він отримує статус "пониженого рівня" NotificationManager.IMPORTANCE_HIGHдо "незвучного" , фактично зареєстрованого NotificationManager.IMPORTANCE_DEFAULT.

Помилка надіслана до засобу відстеження випусків Android, тому, можливо, ви захочете позначити її зірочкою (позначено Google як "Не вдається виправити (нездійсненно)", оскільки ... зіпсовано).


До речі, нові документи на 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

Ви навіть можете помітити невідповідність між значенням видимості високим та значенням сповіщення високим ... Я не знаю, чому вони це роблять. Вони безумовно мають помилку в коді.


Все, що знаходиться під наступним рядком, застаріло , проте ця помилка, про яку там згадується, все ще діє. Моєю помилкою було думати, що 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, як це було б, коли користувач явно змінює налаштування із типового на високий. Цей також отримує скидання за замовчуванням після вимкнення та повторного ввімкнення сповіщення.


8
Дійсно важлива частина цієї відповіді: "Після створення каналу ви не можете змінити важливість (ну, можете, але нова важливість ігнорується)". Я довго боровся, бо не зрозумів, чому будь-які зміни, які я вніс у свій NotificationChannel, не відображались у поведінці програми. Мені доводилося перейменовувати канал щоразу, коли я змінював його, щоб побачити зміни.
Bjarte Aune Olsen

новий ідентифікатор каналу або нова назва каналу, або як новий ідентифікатор каналу, так і назва каналу?
user924

1
Я встановив IMPORTANCE_DEFAULTі звук був відтворений
user924

Сумно бачити таку просту помилку, яка все ще не виправлена. Дякую, що ви записали всі подробиці, переживали той самий біль.
Кіра

1
Я думаю, якщо ви це зробите: nm.deleteNotificationChannel(nChannel.getId());і nm.createNotificationChannel(nChannel);знову. Тоді NotificationManager.IMPORTANCE_LOWбуде працювати (працює для мене).
Ферран Негре

6

Наскільки я бачив, з 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)

Видаляє вказаний канал сповіщень. Якщо ви створите новий канал з тим самим ідентифікатором, видалений канал буде видалено з усіма тими ж налаштуваннями, які він мав до його видалення.

NotificationChannel#setSound() в документації

Модифікується лише до подання каналу NotificationManager#createNotificationChannel(NotificationChannel)

Шкода, що notificationBuilder.setSound(defaultSoundUri)це також не працює:

Цей метод застарів на рівні API 26. Використовуйте замість нього NotificationChannel # setSound (Uri, AudioAttributes).

Також використання бібліотеки підтримки не працює. Отже, звук можна встановити лише один раз у програмі, а зміна користувачем можлива лише в налаштуваннях сповіщення. Для мене коментар Феррана Негре не спрацював. Я не розумію, чому Google зробив це обмеження. Шкода.


2
NotificationManager.IMPORTANCE_LOW

Він не видає звуку, коли створюється сповіщення, оскільки мені це потрібно в моїй музичній програмі.

І так, якщо ви вже створили канал сповіщень, вам потрібно або змінити ідентифікатор каналу, або просто видалити попередню програму та встановити знову.


2

Для мене рішенням було створити групове сповіщення .

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

Але в цьому випадку, якщо ви надішлете нове сповіщення з новим посвідченням особи, воно буде згруповане з попередніми сповіщеннями.


2

Я протестував багато андроїд-пристроїв, наступний код працює для мене належним чином

По-перше, створіть уведомлениеBuilder, якщо ваша версія 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)
        }

    }

По-друге, запустіть це повідомленняBuilder і встановіть звук нульовим

   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
        }

Сподіваюся, це працює для вас.


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

наведений нижче код стосується сповіщення, але звук, вібрація не буде відтворюватися на API 26, тому не турбуйтеся про setound або setvibrate

notificationManager.notify(channelId.toInt(), notificationBuilder.apply {
            setContentIntent(pendingIntent)
            setSmallIcon(R.drawable.img_logo)
            setTicker(title)
            setNumber(data["badge"]?.toIntOrNull() ?: 0)
            setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
            color = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
                resources.getColorMuteDepre(R.color.colorAccent2)
            } else {
                Color.parseColor("#ffffff")
            }


            setContentTitle(title)
            setContentText(body)
            setWhen(System.currentTimeMillis())
            setAutoCancel(true)
            setSound(null)
            setVibrate(longArrayOf())
            if (pushShake.isTrue() &&  data["sound"]?.equals("default", true) == true) {
                setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                    val vbmanager = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
                    vbmanager.vibrate(500)
                }
            }else{
                if (data["sound"]?.equals("default", true) == true) {
                    setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                }
                if (pushShake.isTrue() ) {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                        val vbmanager = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
                        vbmanager.vibrate(500)
                    }
                }
            }


            setStyle(
                NotificationCompat.BigTextStyle().bigText(body).setSummaryText(body).setBigContentTitle(
                    title
                )
            )
            setPriority(NotificationCompat.PRIORITY_DEFAULT)

        }.build())

1

NotificationCompat.Builder.setSilent(true)

Це дозволяє публікувати безшумне сповіщення (без звуку або вібрації) незалежно від налаштування важливості каналу.

Посилання: https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder#setSilent(boolean)


Звучить корисно. Я просто хочу зазначити, що це частина бібліотек Android Jetpack ( androidxякі, мабуть, більшість із нас і так використовують).
Даніель Ф

0

Якщо випадок схожий на мене, я змушений показати сповіщення про фонову службу, і я насправді не хочу показувати жодне сповіщення, рішення, яке працювало на 8.0:

.setPriority(NotificationManager.IMPORTANCE_NONE)

Завдяки цьому я не тільки не отримував настирливого звуку кожні 5 хвилин, але й мінімізував зовнішній вигляд самого повідомлення.

8.1 я не мав проблеми зі звуком із наступним:

.setPriority(NotificationManager.IMPORTANCE_MIN)

Я думаю, що OP все ще хоче показати повідомлення. Приховування сповіщення лише для того, щоб позбутися звуку, не схоже на правильну відповідь.
tir38,

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


0

Оскільки рішення IMPORTANCE має побічний ефект відсутність спливаючого повідомлення, я отримав остаточне рішення:

  1. додавання безшумного звукового ресурсу, який завантажується знизу репо
  2. встановити звук для каналу за допомогою тихого звукового ресурсу.

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


-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());

-2

Спочатку потрібно встановити

importance = NotificationManager.IMPORTANCE_LOW;

тоді

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

Поясніть, що робить останній розділ коду? Що DEFAULT_VIBRATEспільного з цим?
tir38

-2
NotificationManager.IMPORTANCE_LOW

Це спрацює, але ваше повідомлення також згорнуто.


Це вартий уваги побічний ефект, якщо це правда. Я не можу підтвердити це, оскільки використовую власні сповіщення, і вони не згортаються. На якій версії ОС це з вами відбувається? У мене це траплялося зNotificationManager.IMPORTANCE_MIN
Даніелем Ф

Користувацьке сповіщення також згортається, якщо ви передаєте 2 маленькі та великі повідомлення, до речі, я використовую пристрій 8.1 API.
Нікі

1
Що додає ця відповідь, що відповіді @DanielF та Akash ще не містять?
tir38,

-2

NotificationManager.IMPORTANCE_LOW спрацює точно


4
Здається, це просто повторення / підтвердження багатьох існуючих відповідей.
Панг

-2

Я зіткнувся з такою ж проблемою в 8.1 і вніс наступні зміни. Змініть пріоритет сповіщення як НИЗЬКИЙ, і це вимкне звук сповіщення.

NotificationManager.IMPORTANCE_LOW

Код такий:

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

2
Так, це те, що прийнята відповідь, а також відповіді від 27 червня та 16 травня стверджують, що останні два з кращим форматуванням коду.
Даніель Ф,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.