转自:http://blog.csdn.net/zhangphil/article/details/50461944
Android桌面小部件AppWidget(2)
在附录文章1的基础上,我再写一篇关于Android AppWidget的文章,本篇文章实现一个简单功能,此功能亦是对附录文章1所实现功能的增强和改进,本文的代码实现的功能:假设桌面小部件只包含一个Button和一个TextView,当点击Button后,后台启动一个服务(IntentService实现),该服务每个一秒发送一个简单的字符串消息数据data,然后将此消息数据更新到桌面小部件的TextView里面实时显示。
这次,在Androidmanifest.xml有关receiver的定义中,与附录文章1相比,将增加一个action:action_update。本例中,Button的按击事件将触发后台启动服务,后台服务Service每隔一秒制造一个简单字符串数据,然后将此数据实时的以广播形式发给AppWidge,AppWidge收到后,就更新到桌面小部件的TextView里面。
(1)定义AppWidget。
先在Androidmanifest.xml里面定义APP widget的,以Android广播形式:
- <receiver android:name="zhangphil.widget.AppWidget" >
-
- <intent-filter>
- <action android:name="action_button" />
- </intent-filter>
-
- <intent-filter>
- <action android:name="action_update" />
- </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>
两个用于广播接收的action:action_button和action_update,其中action_button用于在桌面小部件接收用户的点击事件,此action_button将随即启动后台服务,而后台启动的服务将发送广播数据,数据中的广播过滤器即是:action_update。
涉及到的res/xml目录下的appwidget.xml代码文件:
- <?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="300dip"
- android:previewImage="@drawable/ic_launcher"
- android:resizeMode="horizontal|vertical"
- android:updatePeriodMillis="0"
- android:widgetCategory="home_screen" >
-
- </appwidget-provider>
(2)上次Java代码实现窗口小部件。
核心的AppWidget.java代码:
- package zhangphil.widget;
-
- 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 {
-
- @Override
- public 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(Constants.ACTION_UPDATE)) {
- String data = intent.getStringExtra(Constants.KEY_DATA);
- Log.d(Constants.KEY_DATA, data);
-
- RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
- remoteViews.setTextViewText(R.id.text, data);
-
- AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
- ComponentName componentName = new ComponentName(context, AppWidget.class);
- appWidgetManager.updateAppWidget(componentName, remoteViews);
- }
-
-
- if (action.equals(Constants.ACTION_BUTTON)) {
- Intent serviceIntent = new Intent(context, MyService.class);
- context.startService(serviceIntent);
- }
- }
-
- @Override
- public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
- Log.d(this.getClass().getName(), "onUpdate");
-
- Intent intent = new Intent(Constants.ACTION_BUTTON);
- PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
-
-
- RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
-
-
- remoteViews.setOnClickPendingIntent(R.id.btn, pendingIntent);
-
-
- appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
- }
-
-
-
-
- @Override
- public void onDeleted(Context context, int[] appWidgetIds) {
- super.onDeleted(context, appWidgetIds);
- Log.d(this.getClass().getName(), "onDeleted");
- }
-
- @Override
- public void onDisabled(Context context) {
- super.onDisabled(context);
- Log.d(this.getClass().getName(), "onDisabled");
- }
-
-
-
-
- @Override
- public void onEnabled(Context context) {
- super.onEnabled(context);
- Log.d(this.getClass().getName(), "onEnabled");
- }
- }
RemoteViews用到的appwidget_layout.xml,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>
(3)后台服务Service。
MyService.java代码文件,此service是一个Android IntentService,具体实现也可以是Service。此service功能简单,是有桌面小部件的button按钮触发,然后在后台启动,启动后在一个for循环里面循环产生一个简单的字符串数据通过广播形式广播出去,注意打进去的广播过滤器是:action_update。
- package zhangphil.widget;
-
- import android.app.IntentService;
- import android.content.Intent;
-
- public class MyService extends IntentService {
-
- private static int ID = 0;
-
- public MyService() {
- super("ZhangPhilService");
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- return super.onStartCommand(intent, flags, startId);
- }
-
- @Override
- protected void onHandleIntent(Intent intent) {
- myLongTimeTask(ID++);
- }
-
- private void myLongTimeTask(int id) {
- for (int i = 0; i < 5; i++) {
-
- Intent intent = new Intent(Constants.ACTION_UPDATE);
- intent.putExtra(Constants.KEY_DATA, "Zhang Phil @ CSDN " + id + ":" + i);
- sendBroadcast(intent);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
记得要将此service注册到Androidmanifest.xml里面:
- <service android:name="zhangphil.widget.MyService" >
- </service>
(4)公共变量的定义(次要)。
因为涉及到众多公共变量的写入和读出,所以定义了一个单独的Constants.java代码类,专门定义公共的变量定义:
- package zhangphil.widget;
-
- public class Constants {
- public static final String ACTION_BUTTON = "action_button";
- public static final String ACTION_UPDATE = "action_update";
- public static final String KEY_DATA = "data";
- }
(5)完整的代码结构。
如图所示:
![](https://img-blog.csdn.net/20160105135112541?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
最终,代码运行结果如图所示:
![](https://img-blog.csdn.net/20160105133137110?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
推荐:http://blog.csdn.net/jjwwmlp456/article/details/38466969