Android中Notification的使用(一)

本篇博客只是对Android通知进行了比较浅显的研究,适合通知栏初学者借鉴。废话不多说开始撸代码。

Android开发环境

(1)AndroidStudio 3.1.2
(2)Android设备Honor 8 Lite

一、撸代码和效果图

1.1 Demo功能展示

Android中Notification的使用(一)_第1张图片
关于Android8.0以上系统通知栏的使用介绍,详细使用可以查看 Android通知栏微技巧,8.0系统中通知栏的适配
@Override
    protected void onCreate(Bundle savedInstanceState) {
      ....
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "chat";
            String channelName = "聊天消息";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            createNotificationChannel(channelId, channelName, importance);

            channelId = "subscribe";
            channelName = "订阅消息";
            importance = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importance);

            channelId = "music";
            channelName = "酷狗音乐";
            importance = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importance);

            channelId = "progress";
            channelName = "notify自带进度条";
            importance = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importance);

            channelId = "uc_progress";
            channelName = "UC下载进度条";
            importance = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importance);
        }

      .....
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createNotificationChannel(String channelId, String channelName, int importance) {
        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        /**
         * Android8.0启动震动,记得添加震动权限
         */
        channel.enableVibration(true);
        /**
         * 先等2秒,再震动2秒,然后就不震动了,所以这个long数组的元素要是偶数个因为奇数个最后一个没用
         */
        channel.setVibrationPattern(new long[]{2000, 2000, 2000});
        /**
         * 设置通知到来时手机关屏时指示灯的提示颜色
         */
        channel.enableLights(true);
        channel.setLightColor(Color.YELLOW);
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
    }

1.2 通知栏API的使用

Android中Notification的使用(一)_第2张图片
代码分析
/**
     * 第一个样式通知栏:
     */
    private void firstNotification() {
        //创建Builder的时候传入“chat”
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "chat");
        Intent intent = new Intent(this, AActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        Notification notify = builder.
                //Android8.0上面LargeIcon没有效果
                        setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_directions_railway)).
                        setSmallIcon(R.drawable.ic_local_car).
                        setTicker("通知来了Ticker").  //话说这个有上升动画
                setContentInfo("ContentInfo--通知文本").//这个在通知中显示不出来
                setContentText("ContentText--通知文本").
                        setContentTitle("ContentTitle--通知文本").
                        setContentIntent(pendingIntent).
                        setColor(Color.YELLOW).
                //setVibrate(new long[]{2000, 2000, 2000, 2000}).//Android8.0不起作用
                //setLights(Color.parseColor("#0000FF"), 5, 5).//Android8.0不起作用
                        build();
        notify.flags = Notification.FLAG_NO_CLEAR;//此标记为该同志将不会清楚
        notificationManager.notify(1, notify);

    }

1.3 模仿酷狗通知

Android中Notification的使用(一)_第3张图片
代码分析
  /**
     * 酷狗通知栏---自定义通知栏
     */
    private void kuGouNotification() {
        if (kuGouNotify == null) {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "music");
            kuGouContentView = new RemoteViews(getPackageName(), R.layout.notify_kugou_layout);

            Intent preIntent = new Intent();
            preIntent.setAction("com.kugou.action.pre");
            PendingIntent prePendingIntent = PendingIntent.getBroadcast(this, 100, preIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            kuGouContentView.setOnClickPendingIntent(R.id.iv_previous, prePendingIntent);

            Intent nextIntent = new Intent();
            nextIntent.setAction("com.kugou.action.next");
            PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 200, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            kuGouContentView.setOnClickPendingIntent(R.id.iv_next, nextPendingIntent);

            Intent closeIntent = new Intent();
            closeIntent.setAction("com.kugou.action.close");
            PendingIntent closePendingIntent = PendingIntent.getBroadcast(this, 300, closeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            kuGouContentView.setOnClickPendingIntent(R.id.iv_close, closePendingIntent);

            Intent intent = new Intent(this, BActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_CANCEL_CURRENT);


            kuGouNotify = builder.
                    setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_music)).
                    setSmallIcon(R.drawable.ic_music).
                    setOngoing(true).//设置当前通知栏是否不间断的运行,添加这个之后生成的自定义布局的通知才生效
                    setOnlyAlertOnce(true).
                    setCustomContentView(kuGouContentView).
                    setCustomBigContentView(kuGouContentView). //设置折叠的通知栏
                    setContentIntent(pendingIntent).
                    //悬挂式通知栏,适配乐视上面的折叠通知栏显示不出来
                    setFullScreenIntent(null, true).
                    build();
        }

        if (simpleTarget == null) {
            simpleTarget = new SimpleTarget() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) {
                    kuGouContentView.setImageViewBitmap(R.id.iv_music, resource);
                    notificationManager.notify(2, kuGouNotify);  //放到此处进行发出通知,使得图片加载成功之后弹出通知
                }
            };
        }
        Glide.with(this).asBitmap().load(Uri.parse(musicPictures[currentIndex])).into(simpleTarget);
//        notify.bigContentView = contentView;   //该方法在API28已经过时
    }

   private class KuGouBroadCastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String intentAction = intent.getAction();
            Log.e("intentAction", intentAction);

            if ("com.kugou.action.pre".equals(intentAction)) {
                currentIndex = currentIndex == 0 ? 4 : currentIndex - 1;
            } else if ("com.kugou.action.next".equals(intentAction)) {
                currentIndex = currentIndex == 4 ? 0 : currentIndex + 1;
            } else if ("com.kugou.action.close".equals(intentAction)) {
                notificationManager.cancel(2);
                return;
            }

            kuGouNotification();
        }
    }

1.4 通知栏自定义进度条

Android中Notification的使用(一)_第4张图片
代码分析
    private int currentProgress = 1;
    private NotificationCompat.Builder notifyBuilder = null;  //Builder
    private Notification notifyDefine = null;

    /**
     * 通知栏自带进度条
     */
    private void notifyDefineProgress() {
        if (notifyBuilder == null) {
            notifyBuilder = new NotificationCompat.Builder(this, "progress");
            Intent intent = new Intent(this, CActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_CANCEL_CURRENT);

            notifyDefine = notifyBuilder.
                    setSmallIcon(R.drawable.ic_file_download).
                    setTicker("通知来了Ticker").  //话说这个有上升动画
                    setContentText("ContentText--通知文本").
                    setContentTitle("ContentTitle--通知文本").
                    setContentIntent(pendingIntent).
                    //第三个参数为true时代表是间断的进度条,为false的时候就是正常进度条
                            setProgress(100, currentProgress, false).
                            build();
            notifyDefine.flags = Notification.FLAG_NO_CLEAR;
        }
        notifyDefine = notifyBuilder.setProgress(100, currentProgress, false).build();
        notificationManager.notify(3, notifyDefine);
        handler.sendEmptyMessageDelayed(1, 1000);
    }

1.5 模仿UC通知栏下载进度条

Android中Notification的使用(一)_第5张图片
代码分析
private boolean isDownload = true;
    private Notification ucNotification = null;
    private RemoteViews ucContentView = null;
    private int ucCurrentProgress = 1;
    private int ucCurrentSecondProgress = 5;

    private void ucDownloadProgress() {
        if (ucNotification == null) {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "music");
            ucContentView = new RemoteViews(getPackageName(), R.layout.notify_uc_layout);
            ucContentView.setImageViewResource(R.id.iv_pause_play, isDownload ? R.drawable.ic_pause_circle : R.drawable.ic_play_circle);
            //给ProgressBar设置进度
            ucContentView.setProgressBar(R.id.pb, 100, ucCurrentProgress, false);
            //更新ProgressBar第二层进度条
            ucContentView.setInt(R.id.pb, "setSecondaryProgress", ucCurrentSecondProgress);


            Intent preIntent = new Intent();
            preIntent.setAction("com.uc.action.pause.play");
            PendingIntent prePendingIntent = PendingIntent.getBroadcast(this, 100, preIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            ucContentView.setOnClickPendingIntent(R.id.iv_pause_play, prePendingIntent);


            Intent intent = new Intent(this, BActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_CANCEL_CURRENT);
            ucNotification = builder.
                    setSmallIcon(R.drawable.ic_toys_black).
                    setOngoing(true).//设置当前通知栏是否不间断的运行,添加这个之后生成的自定义布局的通知才生效
                    setCustomBigContentView(ucContentView). //设置折叠的通知栏
                    setContentIntent(pendingIntent).
                    build();
        }


        ucContentView.setImageViewResource(R.id.iv_pause_play, isDownload ? R.drawable.ic_pause_circle : R.drawable.ic_play_circle);
        ucContentView.setProgressBar(R.id.pb, 100, ucCurrentProgress, false);
        ucContentView.setInt(R.id.pb, "setSecondaryProgress", ucCurrentSecondProgress);
        if (isDownload) {
            ucContentView.setImageViewResource(R.id.iv_icon, R.drawable.uc_rotate);
            handler.sendEmptyMessageDelayed(2, 1000);
        } else { //false时给iv_icon设置不旋转,必须放在notify方法之前否则该图片设置将会不生效
            ucContentView.setImageViewResource(R.id.iv_icon, R.drawable.ic_toys_black);
        }
        notificationManager.notify(4, ucNotification);  //放到此处进行发出通知,使得图片加载成功之后弹出通知
    }

    private class UCBroadCastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String intentAction = intent.getAction();

            if ("com.uc.action.pause.play".equals(intentAction)) {
                isDownload = !isDownload;
            }

            if (ucCurrentProgress > 100) {
                ucCurrentProgress = 1;
                ucCurrentSecondProgress = 5;
            }

            if (!isDownload) {
                //false时给iv_icon设置不旋转
                ucContentView.setImageViewResource(R.id.iv_icon, R.drawable.ic_toys_black);
                handler.removeMessages(2);
            }

            ucDownloadProgress();
        }
    }

三、开发遇到的错误

3.1 Binary XML file line #54: Class not allowed to be inflated android.view.View

解决办法:
Remove the 'View' you are using as a shadow in your layout(or Replace View with TextView) and it works fine. XML used for Remoteview should make use of Views which has @android.widget.RemoteViews.RemoteView annotation. Since a plain View does not has this annotation, you cannot use that in your xml.
意思就是在自定义通知栏时,通知栏的自定义布局中不能使用控件TextView

四、推荐文章

设置Android通知栏Notification的字体/图标颜色随背景色变化而变化

源码地址

你可能感兴趣的:(Android中Notification的使用(一))