文章目录
前言
最近一段时间写的都是android源码的文章,前几天在公司作了一个需求是关于前台服务的,在写前台服务的时候深刻使用到了通知,今天就先写一篇文章总结一下通知的相关内容,后面有时间了在介绍一下前台服务的相关内容。java
通知概述
本篇文章主要介绍通知的如下知识点:android
- 不一样android版本上通知功能
- 通知的结构
- 建立通知
- 通知的操做
- 从通知启动 Activity
- 展开式通知
- 通知渠道
- 通知的级别
- 自定义通知
上面的这么多内容基本覆盖了通知百分之八十的知识点,了解这些足够平常通知的使用了。程序员
不一样android版本上通知功能
Android 4.1(API 级别 16)api
- 引入了展开式通知模板(称为通知样式),能够提供较大的通知内容区域来显示信息。用户可使用单指向上/向下滑动的手势来展开通知。
Android 5.0(API 级别 21)微信
- 引入了锁定屏幕和浮动通知。
- 向 API 集添加了通知是否在锁定屏幕上显示的方法 (setVisibility()),以及指定通知文本的“公开”版本的方法。
- 添加了 setPriority() 方法,告知系统该通知应具备的“干扰性”(例如,将其设置为“高”,可以使该通知以浮动通知的形式显示)。
Android 7.0(API 级别 24)app
- 用户可使用内联回复直接在通知内回复(用户能够输入文本,而后将其发送给通知的父级应用)。
Android 8.0(API 级别 26)布局
- 如今必须将单个通知放入特定渠道中。
- 用户如今能够按渠道关闭通知,而不是关闭应用的全部通知。
- 包含活动通知的应用会在应用图标上方显示通知“标志”。(小圆点或数字)
- 用户能够暂停抽屉式通知栏中的通知。您能够为通知设置自动超时。
- 能够设置通知的背景颜色。
通知的结构
- 小图标:此为必要图标,经过 setSmallIcon() 设置。
- 应用名称:此由系统提供。
- 时间戳:此由系统提供,不过您能够经过 setWhen() 进行替换,或使用 setShowWhen(false) 将其隐藏。
- 大图标:此为可选图标(一般仅用于联系人照片;请勿将其用于应用图标),经过 setLargeIcon() 设置。
- 标题:此为可选内容,经过 setContentTitle() 设置。
- 文本:此为可选内容,经过 setContentText() 设置。
建立通知
为了在不一样的android版本中兼容通知,android在support-compat包中提供了NotificationCompat和NotificationManagerCompat来帮助咱们更加方便的使用通知。
因为咱们是在android10上使用通知,因此咱们必须兼容全部的android版本,那么咱们建立通知的步骤就以下:
测试
- 建立渠道:在android8.0以上须要建立,如下不用建立
- 设置点击事件
- 构造Notification对象并显示通知
1.建立渠道
因为咱们只须要在android8.0以上建立,因此在代码中进行判断:gradle
private String createNotificationChannel(String channelID, String channelNAME, int level) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel(channelID, channelNAME, level); manager.createNotificationChannel(channel); return channelID; } else { return null; } }
这里封装了一个方法,若是api大于android8.0就建立渠道返回渠道id,不然返回空。这里我只传了三个必要的参数,还有其余的设置在通知渠道那一节单独介绍。动画
2.设置点击事件
每一个通知都应该对点按操做作出响应,一般是在应用中打开对应于该通知的 Activity。为此,您必须指定经过 PendingIntent 对象定义的内容 Intent,并将其传递给 setContentIntent()。
Intent intent = new Intent(this, Main2Activity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
3.构造Notification对象并显示通知
Intent intent = new Intent(this, Main2Activity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); String channelId = createNotificationChannel("my_channel_ID", "my_channel_NAME", NotificationManager.IMPORTANCE_HIGH); NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(100, notification.build());
这里经过NotificationCompat.Builder构造通知须要的信息,注意这里调用了setAutoCancel(true),它会在用户点按通知后自动移除通知,若是不调用或者传参数为false就会在点击后依然存在,可是若是用户清除下拉框的全部消息会把这样的通知清理掉。若是不想用户把他清理掉呢?能够调用setOngoing(true)方法,这样除非你的app死掉或者在代码中取消,不然他都不会消失。
通知的操做
1.添加操做按钮
一个通知最多能够提供三个操做按钮,让用户能够快速响应,例如暂停提醒,甚或回复短信。但这些操做按钮不该该重复用户在点按通知时执行的操做。
要添加操做按钮,请将 PendingIntent 传递给 addAction() 方法。这就像是设置通知的默认点按操做,不一样的是不会启动 Activity,而是能够完成各类其余任务,例如启动在后台执行做业的 BroadcastReceiver,这样该操做就不会干扰已经打开的应用。
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class); snoozeIntent.setAction(ACTION_SNOOZE); snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0); PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0); NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .addAction(R.drawable.icon, "按钮", snoozeIntent ) .setAutoCancel(true);
2.添加进度条
通知能够包含动画形式的进度指示器,向用户显示正在进行的操做状态。
经过setProgress(max, progress, false)方法来设置和更新进度
- 第一个参数进度的最大值
- 第二个参数是当前进度值
- 第三个参数是是不是肯定性进度条,具体意思看我下面的例子
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .addAction(R.drawable.icon, "按钮", pendingIntent) .setAutoCancel(true); // Issue the initial notification with zero progress int PROGRESS_MAX = 100; int PROGRESS_CURRENT = 0; notification.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(100, notification.build());
上面对进度条进行了初始化,而后不断调用下面的方法进行更新:
//更新 notification.setContentText("Download complete") .setProgress(0,0,false); notificationManager.notify(100, notification.build());
上面的例子是一个肯定性的进度条,这个怎么理解呢,我给大家看一个不肯定性的进度条大家就知道了,将第三个参数设置为true,效果以下:
3.设置锁定屏幕公开范围
要控制锁定屏幕中通知的可见详情级别,请调用 setVisibility() 并指定如下值之一:
- VISIBILITY_PUBLIC 显示通知的完整内容。
- VISIBILITY_SECRET 不在锁定屏幕上显示该通知的任何部分。
- VISIBILITY_PRIVATE 显示基本信息,例如通知图标和内容标题,但隐藏通知的完整内容。
4.更新通知
要在发出此通知后对其进行更新,请再次调用 NotificationManagerCompat.notify(),并将以前使用的具备同一 ID 的通知传递给该方法。若是以前的通知已被关闭,则系统会建立一个新通知。
您能够选择性调用 setOnlyAlertOnce(),这样通知只会在通知首次出现时打断用户(经过声音、振动或视觉提示),而以后更新则不会再打断用户。
5.移除通知
除非发生如下状况之一,不然通知仍然可见:
- 用户关闭通知。
- 用户点击通知,且您在建立通知时调用了 setAutoCancel()。
- 您针对特定的通知 ID 调用了 cancel()。此方法还会删除当前通知。
- 您调用了 cancelAll() 方法,该方法将移除以前发出的全部通知。
- 若是您在建立通知时使用 setTimeoutAfter() 设置了超时,系统会在指定持续时间事后取消通知。若是须要,您能够在指定的超时持续时间过去以前取消通知。
从通知启动 Activity
通知的点击操做是由PendingIntent实现的,经过PendingIntent能够跳转Activity,开启服务,发送广播,咱们着重来说一下跳转Activity的操做,跳转分为两种类型,一是这个Activity单独在一个任务栈中,点击返回就直接返回到桌面;二是这个Activity拥有一个定义好的返回栈,点击返回会根据任务栈顺序进行回退。
1.单独任务栈
因为从通知启动的“特殊 Activity”不须要返回堆栈,所以您能够经过调用 getActivity() 来建立 PendingIntent,但您还应确保在清单中定义了相应的任务选项。
在清单中,将如下属性添加到 元素中。
android:taskAffinity=""
与您将在代码中使用的 FLAG_ACTIVITY_NEW_TASK 标记结合使用,将此属性设置为空能够确保这类 Activity 不会进入应用的默认任务。具备应用默认类似性的任何现有任务都不会受到影响。
android:excludeFromRecents=“true”
用于从“最近”中排除新任务,以避免用户意外返回它。
<activity android:name=".ResultActivity" android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity>
Intent intent = new Intent(this, Main2Activity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
2.完整任务栈
定义应用的 Activity 层次结构
经过向应用清单文件中的每一个 元素添加 android:parentActivityName 属性,定义 Activity 的天然层次结构。例如:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity" /> ... </activity>
构建包含返回堆栈的 PendingIntent
要启动包含 Activity 的返回堆栈的 Activity,您须要建立 TaskStackBuilder 的实例并调用 addNextIntentWithParentStack(),向其传递您要启动的 Activity 的 Intent。
只要您为每一个 Activity 定义了父 Activity(如上文所述),就能够调用 getPendingIntent() 来接收包含整个返回堆栈的 PendingIntent。
Intent resultIntent = new Intent(this, ResultActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addNextIntentWithParentStack(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
若有必要,您能够经过调用 TaskStackBuilder.editIntentAt() 向堆栈中的 Intent 对象添加参数。有时候须要这样作,以确保返回堆栈中的 Activity 在用户向上导航到它时显示有意义的数据。
展开式通知
基本通知一般包括标题、一行文本,以及用户能够执行的一项或多项响应操做。要提供更多信息,您还能够应用本页介绍的多个通知模板之一来建立大型展开式通知。
1.添加大图片
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .setStyle(new NotificationCompat.BigPictureStyle() .bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.image))) .setAutoCancel(true);
这里经过setStyle来使用系统提供的模版建立大图片通知,要使该图片仅在通知收起时显示为缩略图,请调用 setLargeIcon() 并传入该图片,同时调用 BigPictureStyle.bigLargeIcon() 并传入 null,这样大图标就会在通知展开时消失:
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.image)) .setStyle(new NotificationCompat.BigPictureStyle() .bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.image)) .bigLargeIcon(null)) .setAutoCancel(true);
2.添加大文本
应用 NotificationCompat.BigTextStyle,以在通知的展开内容区域显示文本:
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .setStyle(new NotificationCompat.BigTextStyle() .bigText("不管是否意识到 Gradle 的存在,每位 Android 程序员都会直接或间接的与 Gradle 打交道。每当经过 Android Studio 新建一个工程时,AS 都会自动建立一个通用的目录结构,而后就能够进行开发,在 app 的 build.gradle 中添加一些依赖,点击右上角的 Sync Now")) .setAutoCancel(true);
3.收件箱样式的通知
若是您想要添加多个简短的摘要行(例如收到的电子邮件的片断),可对通知应用 NotificationCompat.InboxStyle。这样,您就能够添加多条内容文本,而且每条文本均截断为一行,而不是显示为 NotificationCompat.BigTextStyle 提供的一行连续文本。
要添加新行,最多可调用 addLine() 6 次。若是添加的行超过 6 行,则仅显示前 6 行。
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setContentTitle("通知") .setContentText("收到一条消息") .setContentIntent(pendingIntent) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .setStyle(new NotificationCompat.InboxStyle() .addLine("不管是否意识到 Gradle 的存在,每位 Android 程序员都会直接或间接的与 Gradle 打交道。每当经过 Android Studio 新建一个工程时") .addLine("AS 都会自动建立一个通用的目录结构,而后就能够进行开发,在 app 的 build.gradle 中添加一些依赖,点击右上角的 Sync Now") .addLine("编写代码,点击绿色小箭头 Run 运行代码,一切都这么美好")) .setAutoCancel(true);
通知渠道
从 Android 8.0(API 级别 26)开始,全部的通知都必须分配到相应的渠道。对于每一个渠道,您能够设置应用于其中的全部通知的视觉和听觉行为(也就是通知的级别)。而后,用户能够更改这些设置,并肯定您应用中的哪些通知渠道应具备干扰性或应该可见。我认为添加这个功能主要是为了让用户可以更透明的管理通知。(百分之九十九的人都不知道,知道也不会去看,唉!!!)
咱们来看一下酷狗音乐的通知渠道状况(不一样的手机厂商系统不一样显示会有出入):
能够看到酷狗总共有5个通知渠道,咱们看一下酷狗推送消息这个渠道:
渠道详情里有重要程度(也就是通知的级别)、提示音、震动等设置,这些都是咱们能够在代码中设置的,固然用户也能够主动的修改他们。
前面已经讲了通知渠道的建立,下面来看一下建立的时候能够作哪些额外操做:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel(channelID, channelNAME, level); //设置提示音 channel.setSound(); //开启指示灯 channel.enableLights(); //开启震动 channel.enableVibration(); //设置锁屏展现 channel.setLockscreenVisibility(); //设置渠道描述 channel.setDescription(); manager.createNotificationChannel(channel);
这里只列举了一部分,在Android 7.1(API 级别 25)如下这些都是直接在NotificationCompat.Builder中设置的,只是在 Android 8.0(API 级别 26)上把这些功能拆分到了渠道设置上。
在建立了渠道以后就没法更改这些设置了。 这里须要单独讲一下,不管咱们调用多少次建立渠道的方法,对于同一个渠道ID只有第一次建立是有效的,由于建立的时候会去判断是否存在这个渠道,若是存在是不会从新建立的。其实这么说也不彻底对,有兴趣的能够看一下我在文章最后作的一个分析。
虽然在建立渠道以后咱们不能再去修改他,可是咱们能够获取渠道设置,由于渠道设置对用户是透明的,用户能够去随意的设置他,因此咱们能够在获取渠道设置以后引导用户设置咱们想要的行为。好比我是微信的开发者,微信的通知被用户手动关掉了,我在检测到通知被关以后就会去告诉用户这个通知很重要不能关掉,而后引导用户跳到那个页面进行设置。主要的步骤以下:
1.读取通知渠道设置
- 经过调用 getNotificationChannel() 或 getNotificationChannels() 获取 NotificationChannel 对象。
- 查询特定的渠道设置,例如 getVibrationPattern()、getSound() 和 getImportance()。
2.打开通知渠道设置
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName()); intent.putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId()); startActivity(intent);
注意,该 intent 须要两个提取项,分别用于指定您应用的软件包名称(也称为应用 ID)和要修改的渠道。
其实还有一个渠道分组没讲,可是用的不多就不说了。
通知的级别
通知的级别主要体如今通知的展现方式上,有的通知只在状态栏如今一个图标,有的通知却会弹出来悬浮在屏幕上(例如微信),这就是经过设置通知的级别实现的。在 Android 7.1(API 级别 25)及更低版本上是经过priority这个属性设置,在 Android 8.0(API 级别 26)及更高版本上是经过importance属性设置。
用户可见的重要性级别 | 重要性(Android 8.0 及更高版本) | 优先级(Android 7.1 及更低版本) |
---|---|---|
紧急 发出提示音,并以浮动通知的形式显示 |
IMPORTANCE_HIGH | PRIORITY_HIGH 或 PRIORITY_MAX |
高 发出提示音 |
IMPORTANCE_DEFAULT | PRIORITY_DEFAULT |
中 不发出提示音 |
IMPORTANCE_LOW | PRIORITY_LOW |
低 不发出提示音,且不会在状态栏中显示 |
IMPORTANCE_MIN | PRIORITY_MIN |
1.Android 7.1(API 级别 25)及更低版本
经过setPriority(NotificationCompat.PRIORITY_LOW)方法能够直接设置。
2.Android 8.0(API 级别 26)及更高版本
在Android8.0中这一功能须要在通知渠道中设置
NotificationChannel channel = new NotificationChannel(channelID, channelNAME, NotificationManager.IMPORTANCE_LOW);
最后一个参数就是通知的级别,除了在建立渠道的时候设置,在渠道建立完成以后也能够设置
NotificationChannel channel = new NotificationChannel(channelID, channelNAME, NotificationManager.IMPORTANCE_LOW); channel.setImportance(NotificationManager.IMPORTANCE_LOW);
兼容
对比上面两个设置方法,咱们发现把这两个设置都加上,而且设置相同的等级就能够兼容全部的版本。
自定义通知
使用自定义通知布局时,请特别注意确保您的自定义布局适用于不一样的设备屏幕方向和分辨率。虽然对于全部界面布局,此建议都适用,但它对通知布局而言尤其重要,由于抽屉式通知栏中的空间很是有限。自定义通知布局的可用高度取决于通知视图。一般状况下,收起后的视图布局的高度上限为 64 dp,展开后的视图布局的高度上限为 256 dp。
自定义通知有两种,一种是为内容区域建立自定义布局,另外一种是建立彻底自定义的通知布局。
1.为内容区域建立自定义布局
若是您须要自定义内容区域的布局,能够将 NotificationCompat.DecoratedCustomViewStyle 应用到您的通知。借助此 API,您能够为一般由标题和文本内容占据的内容区域提供自定义布局,同时仍对通知图标、时间戳、子文本和操做按钮使用系统装饰。
自定义布局的使用方式以下:
- 构建基本通知(使用 NotificationCompat.Builder)
- 调用 setStyle(),向其传递一个 NotificationCompat.DecoratedMediaCustomViewStyle 实例。
- 将自定义布局扩充为 RemoteViews 的实例。
- 调用 setCustomContentView() 以设置收起后通知的布局。您还能够选择调用 setCustomBigContentView() 来为展开后通知设置不一样的布局。
String channelId = createNotificationChannel("my_channel_ID", "my_channel_NAME", NotificationManager.IMPORTANCE_MAX); RemoteViews notificationLayout = new RemoteViews(getPackageName(), R.layout.custom_notification_item); RemoteViews notificationLayoutExpanded = new RemoteViews(getPackageName(), R.layout.custom_notification_large); NotificationCompat.Builder notification = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) .setStyle(new NotificationCompat.DecoratedCustomViewStyle()) .setCustomContentView(notificationLayout) .setCustomBigContentView(notificationLayoutExpanded) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setAutoCancel(true); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(100, notification.build());
2.建立彻底自定义的通知布局
若是您不但愿使用标准通知图标和标题装饰通知,请按照上述步骤使用 setCustomBigContentView(),但不要调用 setStyle()。
要支持低于 Android 4.1(API 级别 16)的 Android 版本,您还应调用 setContent(),向其传递同一 RemoteViews 对象。
总结
在测试建立了渠道以后还能不能修改的时候我发现有些信息是能修改的,可是大部分是不能的,因而我去看了一下建立渠道的源码,结果发现前面说的渠道在建立以后就不能进行修改了其实不彻底对,正确的是大部分主要的都不能修改了,有一些次要的信息仍是能修改的,看一下建立渠道时发现渠道已经存在处理的代码:
NotificationChannel existing = r.channels.get(channel.getId()); // Keep most of the existing settings if (existing != null && fromTargetApp) { if (existing.isDeleted()) { existing.setDeleted(false); needsPolicyFileChange = true; // log a resurrected channel as if it's new again MetricsLogger.action(getChannelLog(channel, pkg).setType( com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN)); } //发现渠道名字不一样会更新 if (!Objects.equals(channel.getName().toString(), existing.getName().toString())) { existing.setName(channel.getName().toString()); needsPolicyFileChange = true; } //发现渠道描述不一样会更新 if (!Objects.equals(channel.getDescription(), existing.getDescription())) { existing.setDescription(channel.getDescription()); needsPolicyFileChange = true; } //我也不知道是什么 if (channel.isBlockableSystem() != existing.isBlockableSystem()) { existing.setBlockableSystem(channel.isBlockableSystem()); needsPolicyFileChange = true; } //发现组不一样会更新 if (channel.getGroup() != null && existing.getGroup() == null) { existing.setGroup(channel.getGroup()); needsPolicyFileChange = true; } // Apps are allowed to downgrade channel importance if the user has not changed any // fields on this channel yet. //当用户没有手动修改过渠道的信息,而且要更新的通知等级小于现有的等级能够更新 final int previousExistingImportance = existing.getImportance(); if (existing.getUserLockedFields() == 0 && channel.getImportance() < existing.getImportance()) { existing.setImportance(channel.getImportance()); needsPolicyFileChange = true; } // system apps and dnd access apps can bypass dnd if the user hasn't changed any // fields on the channel yet if (existing.getUserLockedFields() == 0 && hasDndAccess) { boolean bypassDnd = channel.canBypassDnd(); if (bypassDnd != existing.canBypassDnd()) { existing.setBypassDnd(bypassDnd); needsPolicyFileChange = true; if (bypassDnd != mAreChannelsBypassingDnd || previousExistingImportance != existing.getImportance()) { updateChannelsBypassingDnd(mContext.getUserId()); } } } updateConfig(); return needsPolicyFileChange; }
经过代码发现setName、setDescription、setGroup是能够被修改的,setImportance也能修改可是必须当用户没有手动修改过渠道的信息,而且要修改的通知等级小于现有的等级能够修改。