Android Widget 小部件(一) 简单实现

本文详细介绍了在Android中创建Widget的过程,包括在AndroidManifest.xml中声明接收器,定义Widget描述文件,以及使用布局文件和提供服务来更新Widget显示的内容。通过实例展示了如何更新Widget的UI,并响应特定的动作来触发服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建Widget的一般步骤:
在AndroidManifest.xml中

  1. <receiver android:name="com.jackie.ui.TimerWidgetProvider">  
  2.              <intent-filter>  
  3.                  <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>  
  4.                  <!-- 自定义action -->  
  5.                  <action android:name="com.jackie.action.start"/>  
  6.              </intent-filter>  
  7.              <meta-data android:name="android.appwidget.provider"  
  8.                  android:resource="@xml/timer_widget_provider"/>  
  9.                  <!--  android:resource="" 定义了Widget的信息使用timer_widget_provider.xml描述 -->  
  10. </receiver>  

Widget描述文件:timer_widget_provider.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:minWidth="180dp"  
  4.     android:minHeight="40dp"  
  5.     android:updatePeriodMillis="5000"  
  6.     android:previewImage="@drawable/ic_launcher"  
  7.     android:initialLayout="@layout/timer_widget"  
  8.     android:resizeMode="horizontal|vertical"  
  9.     android:widgetCategory="keyguard|home_screen"  
  10.     android:configure="com.jackie.ui.AppWidgetConfigureActivity" >  
  11.     <!--   
  12.         计算size的公式: (70*n) -30  n为部件所需的大小(占几格)   当前的就是  3X1  
  13.         minResizeWidth  
  14.         minResizeHeight   能被调整的最小宽高,若大于minWidth minHeight 则忽略  
  15.         label   选择部件时看到标签  
  16.         icon    选择部件时看到图标  
  17.         updatePeriodMillis  更新时间间隔  
  18.         previewImage    选择部件时 展示的图像  3.0以上使用  
  19.         initialLayout   布局文件  
  20.         resizeMode      调整size模式  
  21.         configure       如果需要在启动前先启动一个Activity进行设置,在这里给出Activity的完整类名  
  22.         widgetCategory="keyguard|home_screen"  widget可添加的位置 锁屏界面|桌面  
  23.           
  24.         autoAdvanceViewId=@id/xx    与集合部件一起使用,指定该id所表示的集合的item自动推进  
  25.   
  26.         集合部件:3.0后才有。view:ListView、GridView、StackView、AdapterViewFilpper  
  27.      -->  
  28. </appwidget-provider>  

Widget使用的布局:timer_widget.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal"  
  6.     android:background="@drawable/widget_background" >  
  7.       
  8.     <TextView   
  9.         android:id="@+id/counter"  
  10.         android:layout_width="0dp"  
  11.         android:layout_height="match_parent"  
  12.         android:layout_weight="1"  
  13.         android:gravity="center"  
  14.         android:text="00:00"  
  15.         android:singleLine="true"  
  16.         android:textAppearance="?android:attr/textAppearance"/>  
  17.     <ImageView  
  18.         android:id="@+id/start_stop"  
  19.         android:layout_width="0dp"  
  20.         android:layout_height="match_parent"  
  21.         android:layout_weight="1"  
  22.         android:scaleType="center"  
  23.         android:src="@android:drawable/ic_media_play"/>  
  24. </LinearLayout>  

处理Widget相关事件的 AppWidgetProvider
  1. package com.jackie.ui;  
  2.   
  3. import java.util.Arrays;  
  4.   
  5. import com.jackie.R;  
  6. import com.jackie.service.TimerWidgetService;  
  7.   
  8. import android.app.PendingIntent;  
  9. import android.appwidget.AppWidgetHost;  
  10. import android.appwidget.AppWidgetManager;  
  11. import android.appwidget.AppWidgetProvider;  
  12. import android.content.ComponentName;  
  13. import android.content.Context;  
  14. import android.content.Intent;  
  15. import android.text.format.DateUtils;  
  16. import android.widget.RemoteViews;  
  17.   
  18. /* 
  19.  * AppWidgetProvider 必须要接收android.appwidget.action.APPWIDGET_UPDATE 广播 
  20.  *  
  21.  */  
  22. public class TimerWidgetProvider extends AppWidgetProvider {  
  23.       
  24.     @Override //更新部件时调用,在第1次添加部件时也会调用  
  25.     public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
  26.             int[] appWidgetIds) {  
  27.         super.onUpdate(context, appWidgetManager, appWidgetIds);  
  28.         System.out.println("onUpdate widget:" + Arrays.toString(appWidgetIds));  
  29.         /* 
  30.          * 构造pendingIntent发广播,onReceive()根据收到的广播,更新 
  31.          */  
  32.         Intent intent = new Intent(context, TimerWidgetService.class);  
  33.         PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);  
  34.         RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.timer_widget);  
  35.         rv.setOnClickPendingIntent(R.id.start_stop, pendingIntent);  
  36.         appWidgetManager.updateAppWidget(appWidgetIds, rv);  
  37.     }  
  38.       
  39.     @Override   //部件从host中删除  
  40.     public void onDeleted(Context context, int[] appWidgetIds) {  
  41.         super.onDeleted(context, appWidgetIds);  
  42.         System.out.println("onDeleted widget");  
  43.     }  
  44.       
  45.     @Override //第1次创建时调用,之后再创建不会调用  
  46.     public void onEnabled(Context context) {  
  47.         super.onEnabled(context);  
  48.         System.out.println("onEnabled widget");  
  49.     }  
  50.       
  51.     @Override //当最后一个部件实例 被删除时 调用  用于清除onEnabled执行的操作  
  52.     public void onDisabled(Context context) {  
  53.         super.onDisabled(context);  
  54.         System.out.println("onDisabled widget");  
  55.     }  
  56.       
  57.     @Override //  
  58.     public void onReceive(Context context, Intent intent) {  
  59.         super.onReceive(context, intent);  
  60.         System.out.println("onReceive widget");  
  61.         /* 
  62.          * 接收 <action android:name="com.jackie.action.start"/> 
  63.            在其他组件或activity或service中发送这些广播 
  64.             
  65.          */  
  66.         if (intent.getAction().equals("com.jackie.action.start")) {  
  67.             long time = intent.getLongExtra("time"0);  
  68.              updateWidget(context, time);
  69.         }  
  70.     }  
  71.       
  72.     private void updateWidget(Context context, long time) {  
  73.         //RemoteViews处理异进程中的View  
  74.         RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.timer_widget);  
  75.         System.out.println("time=" + time);  
  76.         rv.setTextViewText(R.id.counter, DateUtils.formatElapsedTime(time / 1000));  
  77.           
  78.         AppWidgetManager am = AppWidgetManager.getInstance(context);  
  79.         int[] appWidgetIds = am.getAppWidgetIds(new ComponentName(context, TimerWidgetProvider.class));  
  80.         am.updateAppWidget(appWidgetIds, rv);//更新所有实例  
  81.     }  
  82. }  
AppWidgetProvider中使用的TimerWidgetService:

  1. package com.jackie.service;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6.   
  7. public class TimerWidgetService extends Service {  
  8.   
  9.     @Override  
  10.     public IBinder onBind(Intent intent) {  
  11.         return null;  
  12.     }  
  13.       
  14.     @Override  
  15.     public void onCreate() {  
  16.         super.onCreate();  
  17.     }  
  18.       
  19.     @Override  
  20.     public int onStartCommand(Intent intent, int flags, int startId) {  
  21.         /* 
  22.          * do some thing 
  23.          */  
  24.         //发送广播通知 widget 更新状态  
  25.         sendBroadcast(new Intent("com.jackie.action.start").putExtra("time", System.currentTimeMillis()));  
  26.         return Service.START_STICKY;  
  27.     }  
  28. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值