Android深入理解RemoteViews

1 前言

RemoteViews可以理解为一种远程的View,其实他和远程的Service是一样的,RemoteViews表示的是一种View的结构,他可以在其他的进程中显示,最常用的就是通知栏桌面小组件

2 RemoteViews应用

2.1 在通知栏上的应用

2.1.1 什么是通知

通知是在常规UI界面之外向用户展示消息的工具,当系统发出通知时,它会以图表的形式显示在状态栏中。

2.1.2 如何发送一个通知

(1)获取NotificationManager通知管理类;
(2)使用Notification.Builder构建器构建Notification对象,必要属性有三项:①小图标,通过setSmallIcon()方法设置;
②标题,通过setContentTitle()方法设置;③内容,通过setContentText()方法设置;
(3)调用manager.notify()发出通知。

2.1.3 基本的Builder方法

(1)方法介绍
在这里插入图片描述
(2)必要属性有三项
①小图标,通过setSmallIcon()方法设置
②标题,通过setContentTitle()方法设置
③内容,通过setContentText()方法设置

(3) 让通知常驻通知栏

//让通知常驻通知栏
builder.setOngoing(true);
Notification n = builder.build();
n.flags = Notification.FLAG_NO_CLEAR;
2.1.5 解决Android 8.0不能弹出通知
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        String channelId = "001";
        NotificationChannel channel = new NotificationChannel(channelId, "my_channel", NotificationManager.IMPORTANCE_DEFAULT);
        // 是否在桌面icon右上角展示小红点
        channel.enableLights(true);
        // 小红点颜色
        channel.setLightColor(Color.GREEN);
        // 是否在久按桌面图标时显示此渠道的通知
        channel.setShowBadge(true);
        manager.createNotificationChannel(channel);

        // Notification.Builder需要多设置一个
        builder.setChannelId(channelId);
}

Notification Android8.0中无法发送通知,提示:No Channel found for pkg

2.1.5 发送默认通知

在这里插入图片描述

    private void sendDefaultNotification() {
        // 1、获取NotificationManager通知管理类
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 2、使用Notification.Builder构建器构建Notification对象
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("Notification练习");
        builder.setContentText("this is notification.");
        builder.setTicker("滚动消息......");
        builder.setSmallIcon(R.drawable.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
        builder.setWhen(System.currentTimeMillis());
        builder.setOngoing(true);
//        // 设置通知可以自动取消:builder.setAutoCancel(true)
//        notification.flags = Notification.FLAG_AUTO_CANCEL;
//        // 让通知常驻通知栏:builder.setOngoing(true)
//        notification.flags = Notification.FLAG_NO_CLEAR;

        // 设置点击通知执行意图
        Intent intent = new Intent(this, DemoActivity_2.class);
//        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        builder.setContentIntent(pendingIntent);

        // Android 8.0不能弹出通知解决方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "001";
            NotificationChannel channel = new NotificationChannel(channelId, "my_channel", NotificationManager.IMPORTANCE_DEFAULT);
            // 是否在桌面icon右上角展示小红点
            channel.enableLights(true);
            // 小红点颜色
            channel.setLightColor(Color.GREEN);
            // 是否在久按桌面图标时显示此渠道的通知
            channel.setShowBadge(true);
            manager.createNotificationChannel(channel);

            // Notification.Builder需要多设置一个
            builder.setChannelId(channelId);
        }

        Notification notification = builder.build();
        // 3、调用manager.notify()发出通知
        manager.notify(NOTIFICATION_DEFAULT_ID, notification);
    }
2.1.6 更新通知界面内容

(1)原理:使用相同的Id再次发送一个内容不同的通知即可。
(2)效果
在这里插入图片描述
(3)例子

    private int mProgress = 0;
     
    private void updateDefaultNotification() {
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("音乐下载")
                .setContentText("下载进度:" + mProgress + "%")
                .setSmallIcon(R.drawable.ic_launcher);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String channelId = "002";
            NotificationChannel channel = new NotificationChannel(channelId, "download_channel", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
            builder.setChannelId(channelId);
        }
        Notification notification = builder.build();
        manager.notify(NOTIFICATION_DEFAULT_ID, notification);
        mProgress += 10;
    }
2.1.7 点击通知执行意图
Intent intent = new Intent(this,Main2Activity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
// 给通知添加点击意图
builder.setContentIntent(pi);
2.1.8 实现进度条的通知

(1)方法

setProgress(100, 10, false); // 带有进度条
setProgress(0, 0, false);        // 取消进度条
setProgress(100, 10, true);      // 不确定性进度条

(2)效果
在这里插入图片描述
(3)例子

    private void sendProgressNotification() {
        final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        final Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("进度")
                .setContentText("进度...")
                .setProgress(100, 10, true);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String channelId = "003";
            NotificationChannel channel = new NotificationChannel(channelId, "download_channel", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
            builder.setChannelId(channelId);
        }

        Notification notification = builder.build();
        manager.notify(NOTIFICATION_PROGRESS_ID, notification);
        // 每隔1秒更新进度条进度,启动工作线程
        new Thread() {
            @Override
            public void run() {
                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        for (int i = 1; i <= 10; i++) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            // 发通知:带有进度条
                            builder.setProgress(100, i * 10, false);
                            Notification n = builder.build();
                            manager.notify(NOTIFICATION_PROGRESS_ID, n);
                        }

                        // 更新通知内容
                        manager.cancel(NOTIFICATION_PROGRESS_ID);  // 清除通知
                        builder.setProgress(0, 0, false); // 取消进度条
                        builder.setContentText("音乐下载完毕");
                        Notification n = builder.build();
                        manager.notify(NOTIFICATION_PROGRESS_ID, n);
                    }
                }, 2000);
            }
        }.start();
    }
2.1.9 自定义通知的UI界面

(1)效果
在这里插入图片描述
(2)例子

private void sendCustomNotification() {
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.drawable.ic_launcher);
        builder.setTicker("hello world");
        builder.setWhen(System.currentTimeMillis());
        builder.setOngoing(true);

        // 设置整个通知栏点击通知执行意图
        Intent intent = new Intent(this, DemoActivity_1.class);
        intent.putExtra("sid", "" + NOTIFICATION_CUSTOM_ID);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        System.out.println(pendingIntent);
        builder.setContentIntent(pendingIntent);

        // 给RemoteViews中的TextView设置文本内容
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification);
        remoteViews.setTextViewText(R.id.msg, "自定义通知: " + NOTIFICATION_CUSTOM_ID);
        remoteViews.setImageViewResource(R.id.icon, R.drawable.icon1);
        // 给RemoteViews中的TextView添加点击事件,TextView添加点击意图
        PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity_2.class), PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.open_activity2, openActivity2PendingIntent);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            builder.setCustomContentView(remoteViews);
        } else {
            builder.setContent(remoteViews);
        }

        // Android 8.0不能弹出通知解决方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "005";
            NotificationChannel channel = new NotificationChannel(channelId, "download_channel", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
            builder.setChannelId(channelId);
        }

        Notification notification = builder.build();
        manager.notify(NOTIFICATION_CUSTOM_ID, notification);
    }
2.1.10 学习链接

Android中的Notification

2.2 RemoteViews在桌面小部件的应用

Android桌面小部件是我们经常看到的,比如时钟、天气、音乐播放器等等。 它可以让 App 的某些功能直接展示在桌面上,极大的增加了用户的关注度。 误区:当App的小部件被放到了桌面之后,并不代表我们的App就可以一直在手机后台运行了;虽然它还是能被杀掉,但是用户能看的见它了啊,用户可以点击就

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值