Android O

编程入门 行业动态 更新时间:2024-10-24 12:30:59
本文介绍了Android O - 通知频道 - 更改振动模式或声音类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

使用 Android O,我们可以获得通知渠道".

With Android O we get the "Notification Channels".

据我所知,这意味着用户无法在应用程序内设置通知音或其他相关的通知设置.

As far as I understand that means that the user can't set the notification tone or other related Notification settings inside the APP anymore .

用户需要转到通知渠道设置"并在此处更改音调或振动等strong> 因为 NotificationBuilder 中的所有方法,例如 setSound 都被忽略了.

The user needs to go to the "Notification Channels Setting" and change the tone or vibration etc. here because all methods from the NotificationBuilder like setSound are getting ignored.

所以真的没有方法可以通过代码将音调变为静音?或者通过代码改变振动模式?

So there is really NO way to change the tone to silent via code? Or to change the vibration pattern via code?

例如,用户可以在我的应用中设置振动模式.或者他可以从警报类型而不是通知类型中选择音调.

For example the user have the ability to set the vibration pattern in my app. Or he can pick tones from the alarm type instead of the notification type.

这一切都不再可能了吗?这是正确的还是有办法做到这一点?

All this is not possible anymore? Is this right or is there any way to do this?

推荐答案

您仍然可以在您的应用中提供声音和振动自定义,但这需要不同的方法.简而言之,这个想法是在 Android O 中手动播放声音和振动,而不是使用通知渠道(这比看起来容易).

You can still offer sound and vibration customization in your app, but it requires a different approach. In short, the idea is to play sound and vibration manually in Android O instead of using the notification channel (it's easier than it seems).

我是这样做的:

NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId); // builder.setSmallIcon(...) // builder.setContentTitle(...) // builder.setContentText(...) if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // play vibration vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(VibrationEffect.createWaveform(vibrationPattern, -1)); // play sound Intent serviceIntent = new Intent(context, SoundService.class); serviceIntent.setAction("ACTION_START_PLAYBACK"); serviceIntent.putExtra("SOUND_URI", soundUri.toString()); context.startForegroundService(serviceIntent); // the delete intent will stop the sound when the notification is cleared Intent deleteIntent = new Intent(context, SoundService.class); deleteIntent.setAction("ACTION_STOP_PLAYBACK"); PendingIntent pendingDeleteIntent = PendingIntent.getService(context, 0, deleteIntent, 0); builder.setDeleteIntent(pendingDeleteIntent); } else { builder.setVibrate(vibrationPattern); builder.setSound(soundUri); } notificationManager.notify(notificationId, builder.build());

SoundService.class 是我用 MediaPlayer 播放声音的地方:

SoundService.class is the place where I play the sound with MediaPlayer:

public class SoundService extends Service { MediaPlayer mMediaPlayer; @Override public IBinder onBind(Intent intent) { return null; } public int onStartCommand(Intent intent, int flags, int startId) { // foreground notification if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationCompat.Builder builder = new NotificationCompat.Builder(this, otherChannelId); builder.setSmallIcon(...) .setContentTitle(...) .setContentText(...) .setAutoCancel(true); startForeground(foregroundNotificationId, builder.build()); } // check action String action = intent.getAction(); switch (action) { case "ACTION_START_PLAYBACK": startSound(intent.getStringExtra("SOUND_URI")); break; case "ACTION_STOP_PLAYBACK": stopSound(); break; } // service will not be recreated if abnormally terminated return START_NOT_STICKY; } private void startSound(String uriString) { // parse sound Uri soundUri; try { soundUri = Uri.parse(uriString); } catch (Exception e) { cleanup(); return; } // play sound if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { cleanup(); } }); } try { mMediaPlayer.setDataSource(this, soundUri); mMediaPlayer.prepareAsync(); } catch (Exception e) { cleanup(); } } private void stopSound() { if (mMediaPlayer != null) { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; } cleanup(); } private void cleanup() { stopSelf(); } }

建议

  • 使用 IMPORTANCE_DEFAULT(对于用户来说这是高")、空声音(setSound(null,null))和空振动(setVibrationPattern(null))创建您的通知渠道) 并在频道说明中说明这是推荐的设置,以避免与应用程序自己的自定义发生冲突.
  • 让整个事情对您有利:不要删除一项功能,而是为用户提供一个新功能.您可以让他们有机会使用您的自定义功能或通知渠道功能(例如,您可以检查当前渠道的重要性,并根据级别您可以使用一种或另一种).
  • Create your notification channel with IMPORTANCE_DEFAULT (for the user this is 'High'), a null sound (setSound(null,null)) and a null vibration (setVibrationPattern(null)) and explain in the channel description that this is the recommended setting in order to avoid conflicts with the app's own customization.
  • Turn the whole thing into your favor: instead of removing a feature, give users a new one. You can give them the chance to use your customization features or the notification channel features (for example, you can check the current channel importance and depending on the level you can use one thing or the other).

前台通知

启动Android O,后台启动的服务必须作为前台服务启动.这意味着 SoundService 需要前台通知.您有一些选择:

Starting Android O, services started from the background must be started as foreground services. This means SoundService needs a foreground notification. You have some options for this:

  • 创建一个带有停止播放"按钮的漂亮前台通知,以便用户可以停止声音而无需删除启动它的通知.

  • Create a nice foreground notification with a button that says 'Stop playback' so that the user can stop the sound without removing the notification that started it.

创建一个简单的通知并将其发送到禁用的频道(如果您使用 IMPORTANCE_NONE 创建它们,则可以创建禁用的频道).这样做后,系统会显示默认的应用程序正在后台运行"通知而不是前台通知,但用户可以根据需要在状态栏中隐藏此通知.

Create a simple notification and send it to a disabled channel (you can create disabled channels if you create them with IMPORTANCE_NONE). Doing this, the default system 'App is running in the background' notification will appear instead of your foreground notification, but users can hide this notification from the status bar if they want.

编辑:在 Android 8.1 中,使用 IMPORTANCE_NONE 创建禁用的频道似乎没有用,因为在您发送通知时会自动启用该频道.最好从一开始就用 IMPORTANCE_LOW 创建它,让用户根据需要更改重要性.

EDIT: in Android 8.1 it seems that creating a disabled channel with IMPORTANCE_NONE is not useful, as the channel will be enabled automatically when you send a notification. It may be better to create it with IMPORTANCE_LOW from the beginning and let users change the importance if they want.

更多推荐

Android O

本文发布于:2023-11-27 10:13:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1637652.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!