美文网首页androidandroid
8.0通知栏新增通知渠道

8.0通知栏新增通知渠道

作者: Android开发666 | 来源:发表于2018-03-30 14:37 被阅读109次

    从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所示,在渠道详细界面可以设置渠道的提示音,震动,屏幕锁定时显示方式等。

    image

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

    image

    图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所示。

    用户可见的重要性级别 重要性(Android 8.0及更高版本)
    紧急(发出声音并显示为提醒通知) IMPORTANCE_HIGH
    高(发出声音) IMPORTANCE_DEFAULT
    中等(没有声音) IMPORTANCE_LOW
    低(无声音并且不会出现在状态栏中) IMPORTANCE_MIN

    表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版本或以上版本点击通知栏发现就没收到广播,我以为是8.0增加了通知渠道的问题,后面查看官网API,在Broadcasts类下面看到了这句话:

    Beginning with Android 8.0 (API level 26), the
    system imposes additional restrictions on
    manifest-declared receivers. If your app targets
    API level 26 or higher, you cannot use the manifest
    to declare a receiver for most implicit broadcasts
    (broadcasts that do not target your app
    specifically).
    

    大概意思是从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);//取消注册广播
        }
    }
    

    源码下载

          Android开发666 - 安卓开发技术分享
                 扫描二维码加关注
    
    Android开发666

    相关文章

      网友评论

        本文标题:8.0通知栏新增通知渠道

        本文链接:https://www.haomeiwen.com/subject/kwlicftx.html