Android桌面小部件AppWidget(1)

Android桌面小部件AppWidget的使用,本例假设实现一个简单的功能,窗口小部件有一个Android Button和TextView,当点击桌面小部件时候,把系统当前的毫秒事件显示在TextView里面。

(1)首先需要在Androidmanifest.xml文件代码定义窗口小部件(类似广播的静态注册):

 <receiver android:name=".AppWidget" >            <intent-filter>                <action android:name="action_button" />            </intent-filter>                        <intent-filter>                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/appwidget" />        </receiver>


其中需要在res/xml目录下新建一个appwidget.xml代码文件定义appwidget-provider相关属性:

<?xml version="1.0" encoding="utf-8"?><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"    android:initialLayout="@layout/appwidget_layout"    android:minHeight="20dip"    android:minWidth="200dip"    android:previewImage="@drawable/ic_launcher"    android:resizeMode="horizontal|vertical"    android:updatePeriodMillis="0"    android:widgetCategory="home_screen" ></appwidget-provider>


之所以同时定义了:

 <intent-filter>                <action android:name="action_button" />            </intent-filter>

是因为在我写的这个例子中,将有Button触发事件,但Android窗口小部件机制不像普通Android activity一样直接在类似Button的onClick的方法内处理业务逻辑,而是通过广播出去一个事件,然后又接受者通过RemoteViews处理。


(2)自己写一个类继承自AppWidgetProvider(核心关键):

import android.app.PendingIntent;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.util.Log;import android.widget.RemoteViews;public class AppWidget extends AppWidgetProvider {private final String ACTION_BUTTON = "action_button";/** * 接受广播事件 */@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);Log.d(this.getClass().getName(), "onReceive");if (intent == null)return;String action = intent.getAction();if (action.equals(ACTION_BUTTON)) {// 只能通过远程对象来设置appWidget中的状态RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);remoteViews.setTextViewText(R.id.text, ""+System.currentTimeMillis());AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);ComponentName componentName = new ComponentName(context, AppWidget.class);// 更新appWidgetappWidgetManager.updateAppWidget(componentName, remoteViews);}}/** * 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用 * appWidgetIds:桌面上所有的widget都会被分配一个唯一的ID标识,这个数组就是他们的列表 */@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {Log.d(this.getClass().getName(), "onUpdate");Intent intent = new Intent(ACTION_BUTTON);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);// 小部件在Launcher桌面的布局RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);// 事件remoteViews.setOnClickPendingIntent(R.id.btn, pendingIntent);// 更新AppWidgetappWidgetManager.updateAppWidget(appWidgetIds, remoteViews);}/** * 删除AppWidget */@Overridepublic void onDeleted(Context context, int[] appWidgetIds) {super.onDeleted(context, appWidgetIds);Log.d(this.getClass().getName(), "onDeleted");}@Overridepublic void onDisabled(Context context) {super.onDisabled(context);Log.d(this.getClass().getName(), "onDisabled");}/** * AppWidget首次创建调用 */@Overridepublic void onEnabled(Context context) {super.onEnabled(context);Log.d(this.getClass().getName(), "onEnabled");}}


Android的桌面小部件从继承AppWidgetProvider开始,以我写的代码为例,我创建了一个Android窗口小部件名字叫AppWidget。AppWidgetProvider本身从一定角度上讲是一个Android的广播。
一般的,重写AppWidget里面的onReceive方法,用以后面的更新操作。
AppWidget的onUpdate里面完成view事件的初始化操作,在AppWidget里面,由于窗口小部件与本地代码运行在不同的进程空间,所以只能通过RemoteViews处理与相关view绑定的事件响应。
本例的RemoteViews需要的布局文件在res/layout下的appwidget_layout.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    android:background="#33000000" >    <Button        android:id="@+id/btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="按钮" >    </Button>       <TextView        android:id="@+id/text"        android:text="text"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

RemoteViews将基于appwidget_layout.xml负责在桌面窗口小部件的外观。

在onUpdate里面完成view与事件的绑定后,以本文为例,那么之后对按钮button的按击所产生的事件将会被传递广播到AppWidget的onReceive里面。AppWidget的交互设计模型是在onUpdate里面通过RemoteViews把view通过与事件绑定在一起,然后之后的事件触发及操作,是在onUpdate里面通过广播的形式广播出去一个Intent,此广播将有AppWidget的onReceive接收处理,在AppWidget的onReceive里面更新桌面小部件的UI等等。即:
onUpdate -> onReceive ,此过程基于广播机制。


代码运行结果如图:

Android桌面小部件AppWidget(1)_第1张图片

更多相关文章

  1. 更简单的学习Android事件分发
  2. android 创建快捷桌面
  3. 【笔记】android捕获触摸事件
  4. android 同一个TextView不同文字的点击事件
  5. Android事件传递机制
  6. Android studio实现按钮的点击事件
  7. Android中点击事件之FocusChangedListener实现步骤
  8. Android EditText获取焦点事件

随机推荐

  1. Android(安卓)知识点总结 (二) view绘制流
  2. ubuntu下PjSip2.10编译 for android
  3. Android(安卓)友盟简单快速集成
  4. [Android]Ams 广播发送原理(三)
  5. Android(安卓)day_11-2 (服务)
  6. Android(安卓)- 原生的动作意图(native a
  7. Android(安卓)一条竖线或横线、画边框
  8. android控件与常用控件
  9. Android基础教程:第3版:修订版(china-pub
  10. Android(安卓)NestedScrolling机制