在文章RemoteViews的基本使用(上)之通知栏 中讲述了的RemoteViews使用场景之通知栏,这篇文章主要讲述RemoteViews在窗口小部件中的使用。在写好了一个窗口小部件之后,如果需要对小部件的界面进行更新,由于在本应用中无法调用findViewbyid(id)方法获取控件引用(需要跨进程访问界面),这个时候RemoteViews就派上用场了。在上篇文章中讲到,RemoteViews可以实现跨进程更新界面,内部实现原理是Binder机制,后面会单独更新一篇从源码角度分析RemoteViews。这篇文章主要介绍RemoteViews在窗口小部件的使用,并介绍窗口小部件的简单实现。
分析:在创建该资源文件时,选择Resource Type为AppWidget Provider,这样会自动生成一个带有appwidget-provider标签的文件,手写亦可。
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
}
else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
}
}
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if ("com.widget.wang".equals(intent.getAction())) {
//接受点击按钮后发送的广播,将RemoteView的图片设置为R.drawable.ic_launcher
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.my_appwidget);
rv.setImageViewResource(R.id.iv, R.drawable.ic_launcher);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName provider = new ComponentName(context, MyAppWidgetProvider.class);
appWidgetManager.updateAppWidget(provider, rv);
}
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.e("MyAppWidgetProvider", "call onEnabled");
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Log.e("MyAppWidgetProvider", "call onUpdate");
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.my_appwidget);
rv.setTextViewText(R.id.tv, "更新窗口小部件界面");
rv.setTextColor(R.id.tv, Color.WHITE);
Intent intent = new Intent();
intent.setAction("com.widget.wang");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 给Button设置点击事件,触发一个Intent,这里是发送广播
rv.setOnClickPendingIntent(R.id.btn, pi);
appWidgetManager.updateAppWidget(appWidgetIds, rv);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
Log.e("MyAppWidgetProvider", "call onDeleted");
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.e("MyAppWidgetProvider", "call onDisabled");
}
}