Android小知识-Android 8.0通知栏新增通知渠道

从Android 8.0(API级别26)开始,所有通知必须要分配一个渠道,对于每个渠道,可以单独设置视觉和听觉行为。然后用户可以在设置中修改这些设置,根据应用程序来决定哪些通知可以显示或者隐藏。

创建通知渠道之后,程序无法修改通知行为,创建之后只有用户可以修改,程序只能修改渠道名称跟渠道描述。

我们可以为一个应用程序创建多个通知渠道,不同的通知类型用不同的渠道。例如重要通知用一个渠道,可以为这个渠道重要性设置成最高,不怎么重要的通知用一个渠道,这个渠道重要性设置成最低。

创建一个通知

要创建一个通知,有以下几个步骤:

  1. 构造NotificationChannel对象,构造方法有三个参数:渠道id、渠道名称、渠道重要性级别。

  2. 调用NotificationChannel.setDescription方法可以设置渠道描述。这个描述在系统设置中可以看到。

  3. 调用NotificationManager.createNotificationChannel方法创建通知渠道。

以下是注册通知渠道的代码,记得先判断版本号是不是大于或者等于8.0,因为只有8.0以上才有通知渠道API。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

   //创建通知渠道

   CharSequence name = "渠道名称1";

   String description = "渠道描述1";

   String channelId="channelId1";//渠道id     

   int importance = NotificationManager.IMPORTANCE_DEFAULT;//重要性级别

   NotificationChannel mChannel = new NotificationChannel(channelId, name, importance);

   mChannel.setDescription(description);//渠道描述

   mChannel.enableLights(true);//是否显示通知指示灯

   mChannel.enableVibration(true);//是否振动



   NotificationManager notificationManager = (NotificationManager) getSystemService(

           NOTIFICATION_SERVICE);

   notificationManager.createNotificationChannel(mChannel);//创建通知渠道

}

创建通知渠道不会执行任何操作,所以在启动应用程序时最好调用以上代码。

执行以上代码,就能在设置->应用和通知->选择当前app->应用通知,在应用通知界面就能看到创建的通知渠道,如图1-1所示,可以单独开关当前的通知类别,还可以点击当前渠道,进入渠道详细界面,如图1-2所示,在渠道详细界面可以设置渠道的提示音,震动,屏幕锁定时显示方式等。

图1-1 单个app通知所有渠道列表

图1-2 渠道详细界面

默认情况下,通知的震动还有声音提示都是由NotificationManagerCompat类中重要性级别决定的,例如常量IMPORTANCE_DEFAULT和IMPORTANCE_HIGH,后面我们会讲到这些常量的具体作用。

如果你想改变该渠道的默认通知,可以调用NotificationChannel对象的方法进行修改。

以下介绍了几个常用的方法:

  • enableLights() 是否显示通知指示灯

  • setLightColor() 设置通知灯颜色

  • setVibrationPattern() 设置振动模式

注意:一旦创建了渠道,调用以上方法就会无效,只有用户在设置中才能修改。

上面那段代码只告诉了我们创建渠道,下面这段代码让我们在之前创建的渠道上发送一个通知。

//第二个参数与channelId对应

Notification.Builder builder = new Notification.Builder(this,channelId);

//icon title text必须包含,不然影响桌面图标小红点的展示

builder.setSmallIcon(android.R.drawable.stat_notify_chat)

       .setContentTitle("通知渠道1->标题")

       .setContentText("通知渠道1->内容")

       .setNumber(3); //久按桌面图标时允许的此条通知的数量

Intent intent=new Intent(this,NotificationActivity.class);

PendingIntent ClickPending = PendingIntent.getActivity(this, 0, intent, 0);

builder.setContentIntent(ClickPending);

notificationManager.notify(id,builder.build());

用Notification.Builder构造通知对象时,传入第二个参数就是渠道id,用这个渠道id就能跟我们之前创建的渠道进行关联。设置内容跟发送系统通知代码跟之前类似。运行以上代码就能在8.0的手机上显示通知了。

设置渠道重要性级别

渠道重要性级别影响该渠道中所有通知的显示,在创建NotificationChannel对象的构造方法中必须要指定级别,一共有5个重要性界别,范围从IMPORTANCE_NONE(0)至 IMPORTANCE_HIGH(4),如表1所示。

表1-1 渠道重要级别

查看渠道设置

我们都知道渠道创建之后不能通过代码修改,但是可以先查看该渠道的振动和声音等行为,如果需要修改,可以根据返回的内容再提示用户手动去打开。

  1. 调用NotificationManager.getNotificationChannel(String channelId)方法获取NotificationChannel对象,这个方法有个参数渠道id。

  2. 有了NotificationChannel对象就能调用getVibrationPattern、getSound、getImportance等方法。

示例代码如下所示:

NotificationChannel notificationChannel=notificationManager.getNotificationChannel(channelId);

long[] vibrationPattern=notificationChannel.getVibrationPattern();//震动模式

if(vibrationPattern!=null){

   Log.i("ansen","震动模式:"+vibrationPattern.length);

}

Uri uri=notificationChannel.getSound();//通知声音

Log.i("ansen","通知声音:"+uri.toString());

int importance=notificationChannel.getImportance();//通知等级

Log.i("ansen","通知等级:"+importance);

打开通知渠道设置

创建渠道之后,代码无法去修改这个渠道的行为,只有用户去设置中进行修改,为了让用户更快的找到当前渠道,Intent可以使用ACTION_CHANNEL_NOTIFICATION_SETTINGS打开通知渠道的系统设置。

以下代码打开通知渠道的设置界面:

Intent channelIntent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);

channelIntent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());

channelIntent.putExtra(Settings.EXTRA_CHANNEL_ID,channelId);//渠道id必须是我们之前注册的

startActivity(channelIntent);

需要传入两个参数,应用程序的包名跟渠道id。

删除通知渠道

调用deleteNotificationChannel(String channelId)方法删除渠道,代码如下所示:

NotificationManager mNotificationManager =

(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

mNotificationManager.deleteNotificationChannel(channelId);

8.0通知栏点击通知发送广播

前面的案例我们点击通知栏都是跳转到指定Activity,但是PendingIntent除了getActivity方法之外,还有getBroadcast跟getService。可以点击通知发送广播,开启Service。

于是我们修改显示通知的代码:

String BROADCAST_ACTION="android.intent.action.BROADCAST_ACTION";

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

//第二个参数与channelId对应

Notification.Builder builder = new Notification.Builder(this,channelId);

//icon title text必须包含,不然影响桌面图标小红点的展示

builder.setSmallIcon(android.R.drawable.stat_notify_chat)

       .setContentTitle("通知渠道1->标题")

       .setContentText("通知渠道1->内容")

       .setNumber(3); //长按桌面图标时允许的此条通知的数量

Intent intent = new Intent(BROADCAST_ACTION);

intent.putExtra("data","12345");//带上参数

PendingIntent pendingIntent = PendingIntent.getBroadcast(this,id,intent, PendingIntent.FLAG_UPDATE_CURRENT);

builder.setContentIntent(pendingIntent);

builder.setAutoCancel(true);

mNotificationManager.notify(id,builder.build());

}

新建Intent对象的时候就传入了一个action,同时给Intent传入一个字符串参数,然后调用PendingIntent.getBroadcast构造PendingIntent对象,最后调用notify方法显示通知。

新建一个类DynamicBroadcast,继承BroadcastReceiver,用来接收通知栏点击时发送的广播。在onReceive方法中打印一下我们传入的参数。

public class DynamicBroadcast extends BroadcastReceiver {

   @Override

   public void onReceive(Context context, Intent intent){

       String data = intent.getStringExtra("data");

       Log.i("data",data);

   }

}

前面的内容我们讲了广播的两种注册方式,静态注册跟动态注册,这里我们使用静态注册,在AndroidManifest.xml文件中application标签中增加如下代码:

<receiver android:name=".DynamicBroadcast"

   android:exported="true">

   <intent-filter>

       <action android:name="android.intent.action.BROADCAST_ACTION" />

   </intent-filter>

</receiver>

运行之后发现在Android8.0版本以下的手机正常,点击通知栏会打印广播的日志,但是在Android8.0版本或以上版本点击通知栏发现就没收到广播,从Android8.0API级别26)开始,无法在AndroidManifest.xml文件中声明隐式广播,系统的隐式广播正常使用。

所以呢如果你的手机是Android8.0以上版本的,就需要动态注册广播,这样才能接收到通知栏点击时发送的广播。

注释掉AndroidManifest.xml文件中声明的广播,然后在MainActivity的onCreate方法中注册广播,代码如下:

//动态注册广播

dynamicBroadcast=new DynamicBroadcast();

IntentFilter intentFilter=new IntentFilter(BROADCAST_ACTION);

registerReceiver(dynamicBroadcast,intentFilter);

动态注册的广播一定要在onDestroy方法中进行取消注册:

@Override

protected void onDestroy() {

   super.onDestroy();

   if(dynamicBroadcast!=null){

       unregisterReceiver(dynamicBroadcast);//取消注册广播

   }

}
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页