一,写在前面
这篇文章介绍Android中RemoteViews的基本使用,使用有这样的两个场景:通知栏,窗口小部件。下面会介绍如何实现向通知栏发送一个通知包括:系统默认样式的通知,自定义样式的通知;以及如何实现窗口小部件,并更新界面。值得一提的是,在开发一个应用的时候,若需要实现向通知栏发送通知,或窗口小部件,会发现我们无法直接通过findViewById来获取控件从而更新UI,因为这些界面根本就不在我们开发的应用里,应用里只有对应的xml文件。但是,可以通过使用RemoteViews来更新界面,内部实现原理是Binder机制,这样才能跨进程的处理UI。本篇文章不对RemoteViews的源码进行分析,只是涉及到RemoteViews的两个使用场景,后面会码一篇blog对RemoteViews进行源码角度的分析,敬请期待!
二,通知栏
在手机接收到微信消息时,手指沿着手机屏幕往下滑动,在通知栏会收到一条通知,于是通知栏就展现在我们面前了。那么如何向通知栏发送一条通知呢?
代码如下:
package com.example.notificationdemo;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.RemoteViews;
public class MainActivity extends Activity {
private NotificationManager nm;
public static int id = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
public void clickButton(View v) {
switch (v.getId()) {
//发送默认样式的通知
case R.id.btn1:
Notification notification = new Notification();
notification.icon = R.drawable.ttnkh;
//通知到来时,在状态栏上显示有动画的文字(手机厂商定制手机后,可能不显示tickerText)
notification.tickerText = "I am tickerText";
//显示时间(手机厂商也可能会修改时间展示方式)
notification.when = System.currentTimeMillis();
//点击通知后,通知会消失(默认是不消失)
notification.flags = Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, DemoActivity1.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, "I am contentTitle", "I am contentText", pi);
nm.notify(id, notification);
break;
//发送自定义样式通知
case R.id.btn2:
Notification n = new Notification();
n.tickerText = "我是tickerText";
n.when = System.currentTimeMillis();
n.icon = R.drawable.ic_launcher;
n.flags = Notification.FLAG_AUTO_CANCEL;
//点击通知进入页面DemoActivity1
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity1.class), PendingIntent.FLAG_UPDATE_CURRENT);
n.contentIntent = pendingIntent;
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.remote_view);
PendingIntent click_pi = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity2.class), PendingIntent.FLAG_UPDATE_CURRENT);
//点击图片进入页面DemoActivity2
remoteViews.setOnClickPendingIntent(R.id.iv_remoteview, click_pi);
n.contentView = remoteViews;
nm.notify(id, n);
break;
default:
break;
}
}
}
点击按钮R.id.btn1,R.id.btn2分别发送默认样式通知,发送自定义样式通知。xml布局文件就不再粘贴了,比较简单,这里主要分析点击两个按钮后如何发送通知的。
发送系统默认通知步骤:
1,获取NotificationManager对象,一个系统服务;
2,创建Notification对象,这里是创建空参对象,有参亦可;
3,设置Notification一些字段的值,例如:icon,tickerText,when,flags;
4,调用notification.setLatestEventInfo(Context context,CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent);
点击按钮R.id.btn1,通知栏截图如下:
步骤3中字段在代码中都有注释,比较好理解。这里主要说一下步骤4,:PendingInent,它是一个需要触发的intent,这是它和普通的intent的区别。PendingInent对象获取方式不同,触发执行的意图也不同,触发后的意图总体来说有三种:进入某一Activity,发送广播,启动服务,分别调用PendingIntent.getActivity(...),PendingIntent.getBroadcast(...),PendingIntent.getService(...)。调用notification.setLatestEventInfo方法,会传入一个PendingIntent,在点击了通知栏的通知后,会触摸相应的意图,可以进入一个Activity,或发送一个广播,或启动一个服务。如果想实现一个自定义样式的通知,怎么做了?
发送自定义样式的通知步骤:
步骤1,2,3同发送系统默认通知步骤1,2,3;
4:获取一个PendingIntent对象,给Notification对象的contentIntent 字段设置值:n.contentIntent = pendingIntent;
5:创建RemoteViews对象,更新控件,设置控件点击后触发的意图;
6:给Notification对象的contentView字段设置值:n.contentView = remoteViews;
点击按钮R.id.btn2,通知栏截图如下:
分析:步骤4,n.contentIntent = pendingIntent,是设置点击通知后触发的意图。
步骤5,RemoteViews构造方法中传入两个参数:包名,xml布局文件。这个xml布局文件对应如上通知中的界面,上面布局文件比较简单,客官忍忍,这不是本篇文章重点。
需要注意的是:在点击通知后,进入的是页面DemoActivity1;点击图片后,进入页面DemoActivity2,它们分别对应不同的PendingIntent。
三,另外
如果需要更新通知的界面,就需要操作RemoteViews,调用该对象的相关方法实现,这里不再一一讲解方法,查下API还是比较好理解的。但是要注意,RemoteViews并不能操作所有的View类型,支持的View类型如下:
布局: LinearLayout,RelativeLayout,FrameLayout,GridLayout
控件: AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar,TextView,ViewFlipper,ListView,GridView,StackView, AdapterViewFlipper
注:只支持这些View,不包括其子类,以及自定义的View。
四,最后
RemoteViews在通知栏上的使用,就是实现一个自定义界面的通知。下篇文章将讨论RemoteViews的另一个使用场景-“窗口小部件”,
RemoteViews的基本使用(下)之窗口小部件。
这篇文章就分享到这里啦,有疑问可以留言,亦可纠错,亦可补充,互相学习...^_^