今天,我开始针对API 26,这迫使我使用通知通道。
我的问题是,现在在每个新通知(包括对其的更新)上都会播放烦人的声音。
如何禁用此声音?
我尝试用自定义的mp3声音替换此声音,然后将其传递给带有静音的mp3,但这被忽略。
我只是添加了一个优先级非常低的通知,基本上是给用户一个与应用程序交互后执行某些操作的选项。没有理由大声喊叫,用户将知道他可以参考该通知,因为他已经对应用进行了某些操作,他知道该操作将导致显示通知。
用户真的会开始被那种声音烦恼。
Answers:
如果您想保持频道的重要性,而只是删除声音,notificationChannel.setSound(null, null);
似乎就可以了。
编辑: 确保重命名频道(并删除旧频道)以将其应用于现有用户。(可以创建频道,但不能由应用程序修改频道,只有用户可以。)
NotificationManager.IMPORTANCE_DEFAULT
。这会禁用声音,并且是重要的一个不错的选择。请注意,如果您使用NotificationManager.IMPORTANCE_HIGH
且多次显示相同的通知,它将不断弹出。IMPORTANCE_DEFAULT
如果您显示相同的通知,使用还可以防止该通知再次弹出。
NotificationManager.IMPORTANCE_DEFAULT
,但在创建通知时仍然有声音
(更新2019-05:Android Q变得更糟NotificationManager.IMPORTANCE_LOW
,至少在模拟器中使用时我什至会发出声音...)
解决方案是为其使用NotificationManager.IMPORTANCE_LOW
并创建一个新渠道。创建频道后,您将无法更改重要性(可以,但是可以忽略新的重要性)。频道信息似乎将由系统永久存储,并且仅在卸载应用程序时才会删除创建的任何频道。[更新:根据Ferran Negre的评论,您可以通过删除频道nm.deleteNotificationChannel(nChannel.getId());
并使用重新创建频道,nm.createNotificationChannel(nChannel);
但是显然存在一个限制,即您无法创建具有与已删除频道相同ID的频道,并且期望能够应用不同的频道设置为未删除的频道,请参见编码器的答案]
虽然先前的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
,就像用户明确将设置从默认更改为高时那样。关闭通知然后再次打开后,该通知也将重置为默认值。
IMPORTANCE_DEFAULT
并播放了声音
nm.deleteNotificationChannel(nChannel.getId());
并nm.createNotificationChannel(nChannel);
在以后。然后NotificationManager.IMPORTANCE_LOW
将工作(为我工作)。
据我所知,由于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)。
另外,使用支持库也不起作用。因此,声音只能在应用程序中设置一次,并且用户只能在通知设置中进行更改。对我来说,费兰·内格雷的评论没有用。我不明白为什么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的新通知,则它将与以前的通知分组在一起。
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())
我已经测试了很多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
}
希望对您有用。
您可以使用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
由于IMPORTANCE解决方案具有没有通知弹出窗口的副作用,所以我得到的最终解决方案是:
https://github.com/anars/blank-audio/blob/master/1-second-of-silence.mp3
无需使用 .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());