安卓系统升级appwidget在系统中的id是固定的吗

Android中AppWidget的分析与运用:AppWidgetProvider - Android当前位置:& &&&Android中AppWidget的分析与运用:AppWidgetProvideAndroid中AppWidget的分析与运用:AppWidgetProvider&&网友分享于:&&浏览:133次Android中AppWidget的分析与应用:AppWidgetProvider田海立@CSDN&本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrvodier在整个AppWidget体系中所扮演的角色。分析了AppWidgetProvider如何被AppWidget系统所识别;AppWidgetProvider何时/如何通过RemoteViews提供并更新数据;如何响应通过RemoteViews提供的PendingIntent的按钮点击操作。&因为一般应用开发者并不关注AppWidget其他部分(比如,AppWidgetHost,或AppWidget内部组件)的开发,所以一般就直接把AppWidgetProvider开发称为“AppWidget开发”。一、实现一个AppWidgetProvider&要实现一个AppWidgetProvider,需要:实现AppWidgetProvider的子类,并至少override onUpdate()方法[非必须,但是如果不这样做,该AppWidgetProvider就没有提供任何内容,也就不是AppWidgetProvider了];在AndroidManifest.xml中,声明上述的AppWidgetProvider的子类是一个Receiver,并且:该Receiver的intent-filter的Action必须包含“android.appwidget.action.APPWIDGET_UPDATE”;该Receiver的meta-data为“android.appwidget.provider”,并用一个xml文件来描述布局属性。在2.2的xml文件中描述布局属性的节点名称必须为“appwidget-provider”。以上几点皆是AppWidget系统判断是否是AppWidgetProvider的标志。后面本文的3.2中详述是如何被检索并加入到系统中的。&二、AppWidgetProvider类分析&AppWidgetProvider是一个BroadcastReceiver,必须在AndroidManifest.xml中声明该Receiver,并接收“android.appwidget.action.APPWIDGET_UPDATE”。&类AppWidgetProvider的实现是一个模板模式:图一、AppWidgetProvider&在AppWidgetProvider的onReceiver()实现中已经对接收到的ActionAppWidgetManager.ACTION_APPWIDGET_UPDATE / AppWidgetManager.ACTION_APPWIDGET_DELETED/ AppWidgetManager.ACTION_APPWIDGET_ENABLED以及AppWidgetManager.ACTION_APPWIDGET_DISABLED做了处理,分别执行onUpdate()/ onDeleted() / onEnabled() / onDisabled()。&所以,AppWidgetProvider的实现类,要overrideonReceive(),以及onXXX()[注:至少要实现onUpdate(),在这里AppWidgetProvider通过RemoteViews提供内容给AppWidgetHost,否则,所谓的AppWidgetProvider什么也没提供]。而在onReceive()的开始处就要执行super.onReceive()让AppWidgetProvider来分发AppWidgetProvider所要处理的上述广播消息。&AppWidgetProvider处理AppWidget中的广播:onUpdate() 处理AppWidgetManager.ACTION_APPWIDGET_UPDATE广播。该广播在需要AppWidgetProvider提供RemoteViews数据时,由AppWidgetService.sendUpdateIntentLocked()发出。onDeleted() 处理AppWidgetManager.ACTION_APPWIDGET_DELETED广播。该广播在有该AppWidgetProvider的实例被删除时,由AppWidgetService.deleteAppWidgetLocked()发出。onEnabled() 处理AppWidgetManager.ACTION_APPWIDGET_ENABLED广播。该广播在该AppWidgetProvider被实例化时,由AppWidgetService.sendEnableIntentLocked()发出。onDisabled() 处理AppWidgetManager.ACTION_APPWIDGET_DISABLED广播。该广播在该AppWidgetProvider的所有实例中的最后一个实例被删除时,由AppWidgetService.deleteAppWidgetLocked()发出。一般地,AppWidgetProvider必须处理onUpdate();onEnabled()和onDisabled()最好也要处理;onDeleted()可以不处理。&三、AppWidgetProvider的如何被系统识别&3.1 AppWidgetProvider中配置AndroidManifest.xml&Android中“电量控制”这个AppWidget是由Settings中的SettingsAppWidgetProvider实现的,先来看它的AndroidManifest.xml。&下面是Settings中关于SettingsAppWidgetProvider这个AppWidgetProvider的描述信息:
&receiver android:name=&.widget.SettingsAppWidgetProvider&
android:label=&@string/gadget_title&android:exported=&true&&
&intent-filter&
&action android:name=&android.appwidget.action.APPWIDGET_UPDATE& /&
&action android:name=&android.net.wifi.WIFI_STATE_CHANGED&/&
&action android:name=&android.net.conn.BACKGROUND_DATA_SETTING_CHANGED& /&
&action android:name=&android.bluetooth.adapter.action.STATE_CHANGED& /&
&action android:name=&android.location.PROVIDERS_CHANGED&/&
&action android:name=&com.android.sync.SYNC_CONN_STATUS_CHANGED& /&
&/intent-filter&
&meta-data android:name=&android.appwidget.provider&android:resource=&@xml/appwidget_info& /&
&/receiver&这其中满足一中的1&2的要求,另外,这个AppWidget要处理设置Wifi、Bluetooth、GPS、数据同步和亮度,所以要处理这些相应的设置项变化时的广播通知。对3这点,还要要看res/xml/appwidget_info.xml文件&appwidget-provider xmlns:android=&/apk/res/android&
android:minWidth=&294dip&
android:minHeight=&72dip&
android:updatePeriodMillis=&0&
android:initialLayout=&@layout/widget&
&/appwidget-provider&这里定义了最小宽度minWidth、最小高度minHeight和初始layoutinitialLayout,用来在AppWidgetProvider还未通过RemoteViews提供数据之前,AppWidgetHost就能够获知需要为该AppWidget预留大概的位置;updatePeriodMillis指示是否需要周期性的更新AppWidget,0是不需要周期更新。&3.2 AppWidgetProvider的信息被系统所识别这部分是由AppWidgetService实现。当包含AppWidgetProvider的apk被安装到系统中的时候,AppWidgetService会监听广播,并处理相应的AppWidgetProvider:监听到有包被加入(Intent.ACTION_PACKAGE_ADDED或Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)时,执行addProvidersForPackageLocked()/ updateProvidersForPackageLocked() 添加或更新其中的AppWidgetProvider;监听到有包被移除(Intent.ACTION_PACKAGE_REMOVED或Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)时,执行removeProvidersForPackageLocked()移除其中的AppWidgetProvider。&下面重点关注如何加入AppWidgetProvider,看addProvidersForPackageLocked()的实现:
voidaddProvidersForPackageLocked(String pkgName) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.setPackage(pkgName);
List&ResolveInfo& broadcastReceivers =mPackageManager.queryBroadcastReceivers(intent,
PackageManager.GET_META_DATA);
final int N = broadcastReceivers == null ? 0 :broadcastReceivers.size();
for (int i=0; i&N; i++) {
ResolveInfo ri = broadcastReceivers.get(i);
ActivityInfo ai = ri.activityI
if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE)!= 0) {
if (pkgName.equals(ai.packageName)) {
addProviderLocked(ri);
}检索所加入包中的所有AppWidgetManager.ACTION_APPWIDGET_UPDATE的Receiver,并放入broadcastReceivers:List&ResolveInfo&;[Line#2~ 5]对每一个这样的Broadcast,满足下列要求的加入已安装AppWidgetProvider列表:不是安装在外存储器上;Receiver的包名与安装的包名相同;Meta-data的节点名必须是&appwidget-provider&[解析meta-data中android:resource指向的xml内容]&解析meta-data中android:resource指向的xml内容时,所要解析哪些内容是由frameworks/base/core/res/res/values/attrs.xml中的AppWidgetProviderInfo配置:
&declare-styleable name=&AppWidgetProviderInfo&&
&!-- Minimum width of the AppWidget. --&
&attr name=&minWidth&/&
&!-- Minimum height of the AppWidget. --&
&attr name=&minHeight&/&
&!-- Update period in milliseconds, or 0 if the AppWidget will updateitself. --&
&attr name=&updatePeriodMillis& format=&integer&/&
&!-- A resource id of a layout. --&
&attr name=&initialLayout& format=&reference&/&
&!-- A class name in the AppWidget's package to be launched toconfigure.
If not supplied, then no activity will be launched. --&
&attr name=&configure& format=&string& /&
&/declare-styleable&这些值被解析出来之后,连同label、icon以及由ComponentName(packageName,className)构造的provider被赋值到AppWidgetProviderInfo中,并被记录在AppWidgetService的mInstalledProviders:ArrayList&Provider&中。图二、AppWidgetProviderInfo&四、AppWidgetProvider的Enable与Disable&因为AppWidgetProvider只是提供显示内容,具体显示是显示在AppWidgetHost中的。因为Android机制的关系,后台的AppWidgetProvider很容易被系统杀掉。所以AppWidgetProvider在收到AppWidgetManager.ACTION_APPWIDGET_ENABLED和AppWidgetManager.ACTION_APPWIDGET_DISABLED而执行的onEnbaled()和onDisabled()中是恰当的设置实现AppWidgetProvider的包能不能被移除设置的恰当点。&在onEnbaled()中,该AppWidgetProvider正在被使用,不让被杀掉:
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName(&com.android.settings&,&.widget.SettingsAppWidgetProvider&),
PONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);在onDisabled()中,该AppWidgetProvider不再被使用,可以被杀掉了:
Class clazz =com.android.settings.widget.SettingsAppWidgetProvider.
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName(&com.android.settings&,&.widget.SettingsAppWidgetProvider&),
PONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);&五、AppWidgetProvider通过RemoteViews提供内容&在需要AppWIdgetProvider提供RemoteViews时,AppWidget系统会发出AppWidgetManager.ACTION_APPWIDGET_UPDATE广播,进而onUpdate()会被执行。图三、AppWidgetProvider提供RemoteViews&&在onUpdate()中,创建RemoteViews的实例,传入AppWidgteProvider所在的包名和该AppWidget所要用的Layout;[Seq#5]&如果要响应layoutId中某个viewId被点击操作,要创建本地的PendingIntent,并通过setOnClickPendingIntetn设置到RemoteViews中;[Seq#6~ #9]&为layoutId中要显示的控件加上显示元素,比如某个ImageView的ImageResource。[Seq#10]&用AppWidgetManager.updateAppWidget()更新RemoteViews到系统中,AppWidget系统会更新与之绑定的AppWidgetHost。[Seq#11]&RemoteViews设置与显示详细实现可参考《Android中RemoteViews的实现》;AppWidgetHost如何更新RemoteView可参看《Android中AppWidget的分析与应用:AppWidgetHost》。&六、通过PendingIntent设置按钮响应&上面讲到,可以通过给RemoteViews设置PendingIntent获知感兴趣的View被点击时的响应:
Intent launchIntent = new Intent();
launchIntent.setClass(context, SettingsAppWidgetProvider.class);
launchIntent.addCategory(Intent.CATEGORY_ALTERNATIVE);
launchIntent.setData(Uri.parse(&custom:& + buttonId));
PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* norequestCode */,
launchIntent, 0 /* no flags */);buttonId是layout中的各个Button对应的自定义的Id,该Id只要在本程序中用来能够区分出是哪个Button就可以,被指进”custom:”参数。&AppWidgetProvider本身就是个BroadcastReceiver,在其onReceive()中,就可以判断出是哪个Button被点击了:
if(intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
Uri data = intent.getData();
int buttonId = Integer.parseInt(data.getSchemeSpecificPart());
if (buttonId == BUTTON_WIFI) {
// 切换Wifi状态
} else if (buttonId == BUTTON_BRIGHTNESS) {
// 切换亮度
} else if (buttonId == BUTTON_SYNC) {
// 切换数据同步设置
} else if (buttonId == BUTTON_GPS) {
// 切换GPS打开开关
} else if (buttonId == BUTTON_BLUETOOTH) {
// 切换蓝牙打开状态
}&总结本文讲述了:&实现一个AppWidgetProvider所需要的配置和实现;&AppWidgetProvider如何被AppWidget识别和加入到已安装列表;&AppWidgetProvider如何生成RemoteViews对象,并更新到AppWidgetHost;&AppWidgetProvider响应按钮操作。&可进一步参考的文章Android AppWidget框架&&& AppWidget系统框架。Android中选取并绑定AppWidget&&& 看如何调用本文描述的已经获取的AppWidgetProvider列表的。Android中AppWidget的分析与应用:AppWidgetProvider&&& 本文。Android中AppWidget的分析与应用:AppWidgetHost&&& 可以看选取并绑定AppWidgetProvider之后,Launcher作为AppWidgetHost如何创建显示RemoteViews里AppWidgetProvider所提供的图形元素。Android中RemoteViews的实现&&& RemoteViews的内部如何实现设置进去的OnClickPendingIntent和ViewImageResource的。&
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有评论-1987&
trackbacks-0
& & &Appwidget就是手机应用中常常放在桌面(即home)上的一些应用程序,比如说闹钟等。这种应用程序的特点是它上面显示的内容能够根据系统内部的数据进行更新,不需要我们进入到程序的内部去,比如说闹钟指针的摆动等。本节内容就简单的介绍下实现这种功能所用到的appwidget技术,通过3个例子由浅入深来学会使用它。参考资料是mars的教程。
  实验基础:
  自己实现一个AppWidget的步骤如下:
  1. 在src目录下新建一个名为xml的文件夹,在该文件夹下新建一个xml文件,该xml文件的根标签为appwidget-provider. 该xml文件主要是对所建立的appwidget的一个属性设置,其中比较常见的属性有appwidget更新的时间,其初始的布局文件等等。
  2. 在src下的layout文件夹下新建一个xml文件夹,然后在xml文件夹新建一个布局文件,该布局文件就是第一步中需要加载的appwidget初始化时所需的布局文件,因此该xml文件的根标签为与layout有关,比如说LinearLayout类型等。
  3. 在src的包目录下新建一个java文件,该文件为实现所需建立的appwidget全部功能,其中比较重要的功能是接收广播消息来更新appwidget的内容。该java文件时一个类,继承AppWidgetProvider这个类,复写其中的onDeleted,onDisabled,onEnabled,onReceive,onUpdate等方法。其中几个方法都是与AppWidgetProvider的生命周期有关的。其中onDeleted()方法是当appwidget删除时被执行,onDisabled()是当最后一个appwidget被删除时执行,onEnabled()为当第一个appwidget被建立时执行,onReceive()为当接收到了相应的广播信息后被执行(在每次添加或者删除appwidget时都会执行,且在其它方法执行的前面该方法也会被执行,其实本质上该方法不是AppWidgetProvider这个类的生命周期函数);onUpdate()为到达了appwidget的更新时间或者一个appwidget被建立时执行。
  在android4.1模拟器中,在桌面上添加一个appwidget的方法是在WIDGETS栏目(和APPS栏目并列)中选中所需要添加的appwidget,并按住鼠标不动,一会儿会出现手机桌面空白处,放在自己想放的位置即可。在该模拟器中删除一个appwidge的方法是选中该appwidget一会儿,然后向屏幕上方拖动,屏幕上方会出现XRemove字样,放进去即可。
  &appwidget中本身里面就有一个程序(有个activity),但是我们在桌面上添加一个appwidget后也相当于一个程序,这2个程序本身不是在同一个进程当中,而是在各自单独的进程中。
  例一:
  实验说明:
  这个例子实现一个最简单的appwidget,即我们的appwidget只有一个按钮,按钮上面写着&我的常用密码字样&,没有其它功能,呵呵。然后我们在appwidget的java类的程序中,每个生命周期函数都在后台打印出一句话,内容是与该生命周期函数名相对应的。
  实验结果:
  往桌面添加自己创建的一个appwidget效果如下所示:
  该实验室先后在桌面上放2个appwidget,然后依次删除2个appwidget,则程序后台的输出结果如下所示:
  实验主要代码及注释(附录有实验工程code下载链接):
  MainActivity.java不用更改任何代码,采用默认的就行了,这里就不贴出来了。
my_passward_provider.java(Appwidget功能实现):
package com.example.appwidget1;
import android.appwidget.AppWidgetM
import android.appwidget.AppWidgetP
import android.content.C
import android.content.I
public class my_password_provider extends AppWidgetProvider {
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDeleted()");
super.onDeleted(context, appWidgetIds);
public void onDisabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDisabled()");
super.onDisabled(context);
public void onEnabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onEnabled()");
super.onEnabled(context);
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onReceive()");
super.onReceive(context, intent);
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onUpdate()");
super.onUpdate(context, appWidgetManager, appWidgetIds);
res/xml/my_password.xml:
&?xml version="1.0" encoding="utf-8"?&
&appwidget-provider xmlns:android="/apk/res/android"
android:minWidth="200dp"
android:minHeight="100dp"
android:updatePeriodMillis="600000"
android:initialLayout="@layout/my_password_initillayout"
&/appwidget-provider&
res/layout/my_password_initilayout.xml:
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" &
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_appwidget"
&/LinearLayout&
  例二:
  该实验的目的主要是学会在appwidget中使用PendingIntent和RemoteViews这2个类,并最终对它们有一定的了解。
  实验说明:
  这个例子在上面的例子中多增加了一个功能,即当我们把appwidget添加到桌面上的时候(上面那个例子是个按钮),单击这个按钮,这个时候程序会从home界面跳转到其它activity界面。那么怎么实现监听appwidget上的按钮控件呢?这里实现该过程与在activity中的方法不同。在此之前,我们需要了解2个概念。
  PendingIntent:
  PendingIntent与以前我们的Intent不同,以前我们新建一个intent时,立刻就用它启动一个activity,或者启动一个service,亦或是发送一个broadcast。这里我们新建一个PendingIntent后,按照字面意思并不马上使用它,而是当我们需要使用它的时候再启动,比如说当某一事件需要响应时,我们这时候可以使用建立好了的PendingIntent了。一个PendingIntent中包含了一个intent。Mars老师把PendingIntent比作成三国中的&精囊妙计&,从下面mars老师的2张示意图中可以更深一步了解PendingIntent。
  建立PendingIntent示意图:
  响应PendingIntent示意图:
  RemoteViews:
  RemoteView代表了与调用它的那个activity不在同一个进程的view,因此叫做&远程view&。在appWidget中使用这个类就可以实现当对appwidget的那个进程进行操作时响应其它进程中的activity。而RemoteViews则表示了一系列的RemoteView。
  实验结果与例一一样,只不过是在单击appwidget上的按钮时,会自动跳转到相应的activity上。这里就不截图看效果了。
  实验主要部分及代码(附录有实验工程code下载链接):
  其它部分与例一都差不多,只不过是在appwidget生命周期的onUpdate()函数不同,下面是对应其文件的java代码:
package com.example.appwidget1;
import android.app.PendingI
import android.appwidget.AppWidgetM
import android.appwidget.AppWidgetP
import android.content.C
import android.content.I
import android.widget.RemoteV
public class my_password_provider extends AppWidgetProvider {
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDeleted()");
super.onDeleted(context, appWidgetIds);
public void onDisabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDisabled()");
super.onDisabled(context);
public void onEnabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onEnabled()");
super.onEnabled(context);
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onReceive()");
super.onReceive(context, intent);
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onUpdate()");
for(int i = 0; i & appWidgetIds. i++)
System.out.println(appWidgetIds[i]);
//该构造函数之间把跳转的2个activity给联系起来了
Intent intent =
new Intent(context, MyPasswordActivity.class);
//创建一个PendingIntent
PendingIntent pendint_intent = PendingIntent.getActivity(context, 0, intent, 0);
//创建一个remoteview对象,第2个参数为appwidget的初始布局文件
RemoteViews remote_views = new RemoteViews(context.getPackageName(), R.layout.my_password_initillayout);
//为RemoteViews中的button按钮添加监听器,第二个参数为PendingIntent类型,当事件触发时才执行
remote_views.setOnClickPendingIntent(R.id.my_password, pendint_intent);
//更新appwidget
appWidgetManager.updateAppWidget(appWidgetIds[i], remote_views);
super.onUpdate(context, appWidgetManager, appWidgetIds);
  例三:
  实验说明:
  这个例子在例二的基础上增加一些功能,即利用appwidget的onUpdate()方法中发送广播信息,然后在onReceive()方法中来接收广播消息,从而来更改appwidget的外观,这里是更改它的图片和文本显示。
  这个例子不像上面那样采用getActivity来创建PendingI,而是采用的getBroadcast,因为这里需要的是发送广播信息,而不是跳转到另一个activity。
同样的,需要啊manifest.xml文件中队appwidget这个类来注册它的接收器,action过滤时采用的是自己定义的action,名字可以自己随便取,保证不和系统提供的action名字相同即可,该程序中采用的是"my.action.APPWIDGET_UPDATE"这个名字。
  Appwidget中有1个按钮,一个ImageView,一个TextView。程序实现的是这么一个功能:appwidget在桌面被创建时,imageview和textview都有各自的内容,当按钮按下时,这2个控件的内容都会发生变化,这种变化都是通过RemotViews的方法实现的。其中imageview是用的setImageViewResource()函数,textview是用的setTextViewText()函数。
  从上面的解释可以看到,为什么在同一个类(这里指继承AppWidgetProvide的那个类)中,从onUpdate()函数发送出去的广播能够在onReceiver()函数里接收呢?这是因为AppWidgetProvider的其它4个生命周期函数的执行都是由onReceiver分发下去的。由mars老师提供的这张示意图可以看出它们之间的关系:
  实验结果:
  桌面上创建appwidget时显示如下:
  单击按钮后,显示如下:
  实验主要部分代码即注释(附录有实验工程code下载链接):
AndriodManifest.xml:
&manifest xmlns:android="/apk/res/android"
package="com.example.appwidget1"
android:versionCode="1"
android:versionName="1.0" &
android:minSdkVersion="8"
android:targetSdkVersion="15" /&
&application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" &
android:name=".MainActivity"
android:label="@string/title_activity_main" &
&intent-filter&
&action android:name="android.intent.action.MAIN" /&
&category android:name="android.intent.category.LAUNCHER" /&
&/intent-filter&
&/activity&
&receiver android:name=".my_password_provider" &
&intent-filter&
&action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&
&/intent-filter&
&intent-filter&
&action android:name="my.action.APPWIDGET_UPDATE"/&
&/intent-filter&
&meta-data
android:name="android.appwidget.provider"
android:resource="@xml/my_password" /&
&/receiver&
android:name=".MyPasswordActivity"
android:label="@string/title_activity_my_password" &
&/activity&
&/application&
&/manifest&
my_password_provider.java(里面有appwidget的生命周期函数):
package com.example.appwidget1;
import android.app.PendingI
import android.appwidget.AppWidgetM
import android.appwidget.AppWidgetP
import ponentN
import android.content.C
import android.content.I
import android.graphics.C
import android.widget.RemoteV
public class my_password_provider extends AppWidgetProvider {
private static final String MY_ACTION = "my.action.APPWIDGET_UPDATE";
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDeleted()");
super.onDeleted(context, appWidgetIds);
public void onDisabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onDisabled()");
super.onDisabled(context);
public void onEnabled(Context context) {
// TODO Auto-generated method stub
System.out.println("appwidget---&onEnabled()");
super.onEnabled(context);
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(MY_ACTION.equals(action))
RemoteViews remote_views = new RemoteViews(context.getPackageName(), R.layout.my_password_initillayout);
//更改appwidget界面中的图片
remote_views.setImageViewResource(R.id.my_image, R.drawable.no);
//更改appwidget界面中textview中的文字内容
remote_views.setTextViewText(R.id.my_text, "no");
remote_views.setTextColor(R.id.my_text, Color.RED);
//获得本context的AppWidgetManager
AppWidgetManager appwidget_manager = AppWidgetManager.getInstance(context);
//新建一个ComponentName,该ComponentName指的是针对appwidget整体而言的;而RemoteViews是针对appwidget
//中各个部件之和而言的,这两者有些区别
ComponentName component_name = new ComponentName(context, my_password_provider.class);
//上面2句代码是为下面更新appwidget做准备的
appwidget_manager.updateAppWidget(component_name, remote_views);
super.onReceive(context, intent);
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction(MY_ACTION);
//以发送广播消息的方式创建PendingIntent.
PendingIntent pending_intent = PendingIntent.getBroadcast(context, 0, intent, 0);
//创建一个remoteviews,其布局文件为appwidget的初始布局文件
RemoteViews remote_views = new RemoteViews(context.getPackageName(), R.layout.my_password_initillayout);
//为按钮添加监听器
remote_views.setOnClickPendingIntent(R.id.my_password, pending_intent);
//更新appwidget
appWidgetManager.updateAppWidget(appWidgetIds, remote_views);
super.onUpdate(context, appWidgetManager, appWidgetIds);
res/layout/my_password_initillayout.xml(appwidget的布局文件):
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" &
android:id="@+id/my_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_appwidget" /&
&ImageView
android:id="@+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:src="@drawable/yes"
android:id="@+id/my_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/yes"
android:textColor="#0000ff"
&/LinearLayout&
Res/xml/my_password.xml(appwidget的属性设置xml文件):
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" &
android:id="@+id/my_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_appwidget" /&
&ImageView
android:id="@+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:src="@drawable/yes"
android:id="@+id/my_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/yes"
android:textColor="#0000ff"
&/LinearLayout&
  总结:通过这几个例子,可以初步了解创建一个appwidget的整个流程,并且学会了简单的是appwidget和其它的进程间进行通信。
& & &参考资料:
& & &附录:
阅读(...) 评论()
阿萨德发斯蒂芬

我要回帖

更多关于 安卓系统下载 的文章

 

随机推荐