[android] NotificationChannel에서 사운드 비활성화

오늘 저는 알림 채널을 사용해야하는 API 26을 타겟팅하기 시작했습니다.

내 문제는 이제 새로운 알림 (업데이트 포함)마다 성가신 소리가 재생된다는 것입니다.

이 소리를 어떻게 비활성화 할 수 있습니까?

이 사운드를 사용자 지정 mp3 사운드로 교체 한 다음 무음이있는 mp3를 전달하려고 시도했지만 무시됩니다.

기본적으로 사용자가 앱과 상호 작용 한 후 몇 가지 작업을 수행 할 수있는 옵션을 제공하는 매우 낮은 우선 순위의 알림을 추가하고 있습니다. 큰 소리를 낼 이유가 없습니다. 사용자는 알림이 표시되도록하는 앱으로 특정 작업을 수행했기 때문에 알림을 참조 할 수 있음을 알게됩니다.

사용자는 그 소리에 정말로 짜증을 내기 시작할 것입니다.



답변

채널의 중요성을 유지하고 싶다면 사운드를 제거하는 것만으로도 효과가있는 notificationChannel.setSound(null, null);것 같습니다.

편집 :
기존 사용자에게 적용되도록 채널의 이름을 바꾸고 이전 채널을 삭제하십시오. (채널은 만들 수 있지만 앱에서 수정할 수는 없으며 사용자 만 할 수 있습니다.)


답변

(업데이트 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(기본적으로 NotificationManager.IMPORTANCE_HIGH소리가 나지 않음) 채널을 만들 때 Android가 실제로 “다소”로 등록 (기본적으로 소리 재생)하기 때문입니다.

알림 옵션 (알림 항목을 길게 누름)으로 이동하여이를 확인할 수 있으며, 여기서 유형임을 읽은 NotificationManager.IMPORTANCE_HIGH다음 알림을 비활성화 한 다음 다시 활성화합니다. 이 과정 NotificationManager.IMPORTANCE_HIGH에서 실제로 등록 된에서 소리가 나지 않는 것으로 “다운 그레이드”됩니다 NotificationManager.IMPORTANCE_DEFAULT.

이 버그는 Android 문제 추적기에 제출되었으므로 별표를 표시 할 수 있습니다 (Google에서 “수정할 수 없음 (실행 불가능)”으로 표시했습니다.


BTW,에서 새로운 문서 https://developer.android.com/training/notify-user/channels은
기본 동작은 그 방법이 사용했다는 주장은, 그 기본은 안드로이드 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사용자가 명시 적으로 설정을 기본값에서 높음으로 변경하는 것처럼 어떻게 든 마술처럼으로 업그레이드되었습니다 . 또한 알림을 껐다가 다시 켜면 기본값으로 재설정됩니다.


답변

내가 아는 한 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의 의견은 작동하지 않았습니다. Google 이 이러한 제한을 한 이유를 이해할 수 없습니다 . 너무 나쁘다.


답변

NotificationManager.IMPORTANCE_LOW

내 음악 응용 프로그램에서 동일한 알림이 필요하므로 알림이 생성 될 때 소리가 나지 않습니다.

예, 이미 알림 채널을 만든 경우 채널 ID를 변경하거나 이전 응용 프로그램을 제거하고 다시 설치해야합니다.


답변

저에게 해결책은 그룹 알림만드는 것이 었습니다 .

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

그러나이 경우 새 ID로 새 알림을 보내면 이전 알림과 함께 그룹화됩니다.


답변

많은 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를 초기화하고 사운드를 null로 설정합니다.

   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
        }

그것이 당신을 위해 일하기를 바랍니다.


답변

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에서 재생되지 않으므로 setsound 또는 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())