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