android 8.0 通知栏Notification适配、自定义铃声及其channel介绍

版权声明:越努力,越幸运! https://blog.csdn.net/mingtiannihao0522/article/details/83584038

一、8.0手机 通知栏适配

针对Android 8.0手机,无论是推送消息还是自定义的Notification,如果不作处理都将无法收到通知。项目跑在Android 8.0模拟器上弹出了Toast: ***Developer warning for package “xxx.xxx.xxx” Failed to post notification on channel “12345” See log for more details***追其原因:由于此条通知没有查找到应用中对应的NotificationChannel的原因,而无法弹出来。那NotificationChannel是个什么鬼,查阅官文得知,这是Android O新增的通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。

此时我们需要单独创建notificationChannel,我直接将代码贴出来,在Application中初始化就好了

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            // 通知渠道的id 这个地方只要一直即可
            String id = "111111";
            // 用户可以看到的通知渠道的名字.
            CharSequence name = "notification channel";
            // 用户可以看到的通知渠道的描述
            String description = "notification description";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel mChannel = new NotificationChannel(id, name, importance);
            // 配置通知渠道的属性
            mChannel.setDescription(description);
            // 设置通知出现时的闪灯(如果 android 设备支持的话)
            mChannel.enableLights(true);
            mChannel.setLightColor(Color.RED);
            // 自定义声音
           mChannel.setSound(Uri.parse("android.resource://" + getPackageName() + "/raw/qqqq"),null);
            // 设置通知出现时的震动(如果 android 设备支持的话)
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            //最后在notificationmanager中创建该通知渠道
            mNotificationManager.createNotificationChannel(mChannel);
        }

1、然后自定义通知时候:传入相同的id即可

NotificationCompat.Builder  builder = new NotificationCompat.Builder(context, "111111");

//后面的通知创建不多赘述。

2、针对推送,不同厂家是不一样的。贴出阿里推送(个人比较推荐阿里推送,免费,推送到大率很高)

在控制台发送时候:
在这里插入图片描述

将8.0推送配置文档贴在这里:

https://help.aliyun.com/knowledge_detail/67398.html

这样便可以收到通知了。。

二、自定义铃声所遇到的坑

Android8.0 Google推出了NotificationChannel渠道的概念,对于NotificationChannel我们可以通过以下方式来设置铃声和振动。

NotificationChannel channel = new NotificationChannel(newChannelId, BaseApplication.getAppString(R.string.push_channel_name), NotificationManager.IMPORTANCE_HIGH);
            if (!TextUtils.isEmpty(uri)) {
                Logger.i(TAG, "8.0通知铃声:" + uri);
                Uri mUri = Uri.parse(uri);
                channel.setSound(mUri, Notification.AUDIO_ATTRIBUTES_DEFAULT);
            } else {
                channel.setSound(null, null);
            }
            Logger.i(TAG, "8.0是否开启振动:" + vibrateEnable);
            channel.enableLights(true);
            if (vibrateEnable) {
                channel.enableVibration(true);
                channel.setVibrationPattern(new long[]{
                        100, 200, 300
                });
            } else {
                channel.enableVibration(false);
                channel.setVibrationPattern(new long[]{0});
            }
            nm.createNotificationChannel(channel);

那么如何的修改铃声和振动呢?最初天真的我以为重新调用NotificationChannel.setSound()方法来修改铃声,最终结果大家都清楚,是不会生效的,看了google的文档有这样一句话
在这里插入图片描述
意思是只能在create一个渠道之前修改铃声,在创建之后不支持修改。没办法,只能去重新创建一个渠道设置铃声振动。对于之前创建的渠道,你必须还得去通过deleteNotificationChannel(String channelId)去删除。但是这里又有另外一个坑。你什么时候去删除呢?第一次测试我是在修改铃声或者振动的时候创建一个新的渠道,把之前所有旧的渠道都删除,但是这样会有一个bug,之前渠道上还在状态栏显示的Notification都会删除掉,所有要做一个判断,如果当前渠道在状态栏没有notification显示则删除,否则继续保存,代码如下:

private static void deleteNoNumberNotification(NotificationManager nm, String newChannelId) {
        List<NotificationChannel> notificationChannels = nm.getNotificationChannels();
        if (Utils.isEmpty(notificationChannels) || notificationChannels.size() < 5) {
            return;
        }
        for (NotificationChannel channel : notificationChannels) {
            if (channel.getId() == null || channel.getId().equals(newChannelId)) {
                continue;
            }

            int notificationNumbers = getNotificationNumbers(nm, channel.getId());
            Logger.i(TAG, "notificationNumbers: " + notificationNumbers + " channelId:" + channel.getId());
            if (notificationNumbers == 0) {
                Log.i(TAG, "deleteNoNumberNotification: " + channel.getId());
                nm.deleteNotificationChannel(channel.getId());
            }
        }
    }

    /**
     * 获取某个渠道下状态栏上通知显示个数
     *
     * @param mNotificationManager NotificationManager
     * @param channelId            String
     * @return int
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private static int getNotificationNumbers(NotificationManager mNotificationManager, String channelId) {
        if (mNotificationManager == null || TextUtils.isEmpty(channelId)) {
            return -1;
        }
        int numbers = 0;
        StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications();
        for (StatusBarNotification item : activeNotifications) {
            Notification notification = item.getNotification();
            if (notification != null) {
                if (channelId.equals(notification.getChannelId())) {
                    numbers++;
                }
            }
        }
        return numbers;
    }

三、Android O Preview 之 通知渠道(Notification Channels)

介绍
Android O 引入了 通知渠道(Notification Channels),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道,以向用户显示通知。若并不以 Android O 为目标平台,当应用运行在 android O 设备上时,其行为将与运行在 Android 7.0 上时相同。
开发者可以为需要发送的每个不同的通知类型创建一个通知渠道。还可以创建通知渠道来反映应用的用户做出的选择。例如,可以为聊天应用的用户创建的每个聊天组建立单独的通知渠道。
Android O 的用户可以使用一致的系统 UI 管理大多数与通知有关的设置。所有发布至通知渠道的通知都具有相同的行为。
具体的可以浏览该文章的详细介绍
链接:https://www.jianshu.com/p/92afa56aee05

猜你喜欢

转载自blog.csdn.net/mingtiannihao0522/article/details/83584038