AppWidget详解

最近一直专研Android开发,希望得到大家的支持与帮助!这是最近学AppWidget做的笔记,希望帮到需要的人!让大家更快的进步!(一下只标注了核心代码,相信大家一定可以看懂的,若需要源码,可以回复说明,也希望大家顶顶贴!至于奖品吧。。。。当然期待哦!)
一、核心功能介绍(一)appwidget介绍:
我们的appwidget与我们对应的activity不是同一个进程,appwidget是homescreen中的一个进程。所以,我们不能直接对某一个控件进行事件监听,而是通过RemoteViews进行处理,而且我们也不能直接用intent进行启动activity,用pendingintent。
(二)pendingintent介绍(如同一个锦囊,用来包装intent对象):
顾名思义,是还未确定的Intent。可以看做是对intent的一个包装,目的是对RemoteViews进行设置。形象点讲就是我们进程A中的intent想要在进程B中执行,需要pendingintent进行包装,然后添加到进程B中,进程B中遇到某个事件,然后执行intent。
1.在创建PendingIntent对象之前要先创建intent对象:
Intent intent = newIntent(context,SecondActivity.class);
2.创建PendingIntent的方法 (有三种)
1)启动一个activity
PndingIntentpendingIntent=PendingIntent.getActivity(context,
requestCode, intent,flags);
2)发送一个广播
.getBroadcast(context,requestCode, intent, flags);
3)发送一个服务
.getService(context,requestCode, intent, flags);
(三)RemoteViews:
即远程的views。他的作用是他所表示的对象运行在另外的进程中。
RemoteViews 的作用:
1.RemoteViews 对象表示了一系列的 view 对象
2.RemoteViews 所表示的对象运行在另外的进程当中
二、开发流程:
* 1 、在 src 文件夹下写一个类继承自 AppWidgetProvider
* 2 、在 res/xml 文件夹下新建 appwidgetprovderinfo.xml
* 3 AndroidManifest.xml 注册 Receiver
* 4 AppWidgetManger :负责管理 AppWidget ,向 AppwidgetProvider 发送通知。
* 5 RemoteViews :一个可以在其他应用进程中运行的类,向 AppWidgetProvider 发送通知。
(一)、继承AppWidgetProvider类,并重载下列方法:
onUpdate onReceive 方法尤为重要):
onUpdate :到达指定时间之后或者用户向桌面添加appwidget时候会调用这个方法。
onDelete :当appwidget被删除时,会调用这个方法。
Enable :当一个appwidget第一次被创建,会调用这个方法。
nDisable :当最后一个appwidget实例被删除后,会调用这个方法。
onReveice :接受广播事件。
生命周期为:
当第一个widget被创建出来时,执行顺序是:
onreceive
onEnabled
onreceive
onUpdate

当第二个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate

当第三个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate

删除一个widget时,执行顺序为:
onreceive
onDeleted

删除最后一个widget时,执行顺序为:
onreceive
onDeleted
onreceive
onDisabled

应考虑用户可以在桌面添加多个相同的App Widget,因此系统调用我们重载的方法时,很多时候都是传给我们一个id数组。
onUpdate是非常重要的一个方法。当用户在桌面添加一个App Widget时,或者用户定义的时钟updatePeriodMillis响应时,此方法都会被调用。但是如果用户定义了configurationActivity时,在用户添加小控件时,onUpdate不会被调用。
    @Override
public void onUpdate(Contextcontext, AppWidgetManager appWidgetManager, int [] appWidgetIds) {
       // TODO Auto-generatedmethod stub
       super .onUpdate(context, appWidgetManager, appWidgetIds);
    }
(二)、在res/xml文件夹下定appwidgetproviderinfo.xml
在res文件夹下创建名为xml的文件夹,然后添加一个xml文件,Tag为appwidget-provider,
1 、屏幕一般被分为,4x4 单元,因此我们定义的miniHeight miniWidth 不要超过4x4 单元的大小,每一单元大小为72x72dp, Google 提供的基本原则是用你想占用的单元格数量乘以 74 ,再减去 2
2 initialLayout 用来声明Layout 文件,该xml 文件就在layout 文件夹下!
3 updatePeriodMills 来定义更新AppWidget 的时钟,当不需要更新时设置为0
代码如下:
// 用来更新 App Widget 的时钟,当不需要更新时设置为 0
定义一个App Widget ,我们也需要定义它的Layout 文件。在App Widget 中,不是所有的Android 控件都能放入App Widget Layout 中去的,现阶段只有下面一些Layout 和控件才能放入App Widget 中。
还有在程序中要控制App Widget 的控件都通过RemoteViews 来控制。
布局类:
LinearLayout FrameLayout RelativeLayout
控件类:
AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar
TextView,ViewFlipper,ListView,GridView,StackView,AdapterViewFlipper
如果上述以外的控件或者Layout 类被放入App Widget Layout 文件中的话,App Widget 将不能在桌面显示。
(三)、在AndroidManifest.xml中进行配置
前面已经讲过,所有的AppWidgetProvider 实际上都是BroadcastReceiver ,因此在Manifest 里面申明时使用receiver 标签。meta-data 标签的名字固定为"android.appwidget.provider" resource 用来声明AppWidgetProviderInfoxml intent-filter 里面添“android.appwidget.action.
APPWIDGET_UPDATE ”,当我们定义的时钟android:updatePeriodMillis 响应时,会广播APPWIDGET_UPDATE ,此时我们的onUpdate 会被调用。
代码如下:
< receiver android:name="com.example.mywidget.MainActivity">
    < intent-filter >
       < action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
   
          < meta-data
               android:name="android.appwidget.provider"
               android:resource="@xml/mywidget"/>
三、AppWidget 框架的主要类介绍
1)AppWidgetManger
    * bindAppWidgetId(int appWidgetId,ComponentName provider)
      
通过给定的 ComponentName 绑定 appWidgetId
    * getAppWidgetIds(ComponentNameprovider)
      
通过给定的 ComponentName 获取 AppWidgetId
    * getAppWidgetInfo(intappWidgetId)
      
通过 AppWidgetId 获取 AppWidget 信息
    * getInstalledProviders()
      
返回一个 List 的信息
    * getInstance(Context context)
      
获取 AppWidgetManger 实例使用的上下文对象
    * updateAppWidget(int[]appWidgetIds, RemoteViews views)
      
通过 appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新 AppWidget 组件
    * updateAppWidget(ComponentNameprovider, RemoteViews views)
通过 ComponentName 对传进来的 RemoeteView 进行修改,并重新刷新 AppWidget 组件
    * updateAppWidget(int appWidgetId,RemoteViews views)
      
通过 appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新 AppWidget 组件
四、在onUpdate方法中启动另一个activity
目标:创建一个appwidget(为一个button),点击后,启动一个activity。
onUpdate中写入代码:
for ( int i= 0;i
                < action android:name="mars.appwidget03.UPDATE_APP_WIDGET"/>
// 定义一个常量字符串,该常量用于命名 Action
private static final String UPDATE_ACTION = "mars.appwidget03.UPDATE_APP_WIDGET" ;
onReceive方法中:
@Override
    public void onReceive(Context context, Intent intent) {
       super .onReceive(context, intent);
       Stringaction = intent.getAction();
       if ( UPDATE_ACTION .equals(action)) {
           System. out .println( "onReceive--->" + UPDATE_ACTION );
       }
    }
onUpdate方法中:
    @Override
    public void onUpdate(Context context, AppWidgetManagerappWidgetManager, int [] appWidgetIds) {
       // 创建一个 Intent 对象
       Intent intent = new Intent();
       // Intent 对象设置 Action
       intent.setAction( UPDATE_ACTION );
// 使用 getBroadcast 方法,得到一个 PendingIntent 对象,当该对象执行时,会发送一个广播
PendingIntentpendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout. example_appwidget );
remoteViews.setOnClickPendingIntent(R.id. widgetButtonId , pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
    }
六、使用RemoteViews对象跟新AppWidget当中的控件状态
注:由于 AppWidget 和主程序不在同一个进程当中,不能用普通的方法进行操作
1 、在 RemoteViews 类当中有一系列的方法可以更新控件;
2 、在使用 RemoteViews 更新控件状态之后,需要使用 AppWManager 通知 AppWidget 进行更新。
3 、需要创建两个对象 :AppWidgetManager( 负责管理 AppWidget, AppwidgetProvider 发送通知 ) ComponentName 对象
AndroidManifest.xml中的receiver中添加:
< intent-filter >
                < action android:name="mars.appwidget03.UPDATE_APP_WIDGET"/>
</ intent-filter >
onReceive方法中:
@Override
    public void onReceive(Context context, Intent intent) {
       String action = intent.getAction();
       if ( UPDATE_ACTION .equals(action)) {
RemoteViews remoteViews= new RemoteViews(context.getPackageName(),
R.layout. example_appwidget );
remoteViews.setImageViewResource(R.id. imageId, R.drawable. ku);
      remoteViews.setTextViewText(R.id. widgetTextId , "test" );
// 创建一个 AppWidgetManager 对象
AppWidgetManager appWidgetManager =AppWidgetManager.getInstance(context);
// 创建一个 ComponentName 对象
ComponentName componentName = new ComponentName(context,
ExampleAppWidgetProvider. class );
    appWidgetManager.updateAppWidget(componentName, remoteViews);
     } else {
            super .onReceive(context, intent);
       }
    }
onUpdate方法中:
    @Override
public void onUpdate(Context context, AppWidgetManagerappWidgetManager,
int [] appWidgetIds) {
       Intent intent = new Intent();
       intent.setAction( UPDATE_ACTION );
PendingIntent pendingIntent= PendingIntent.getBroadcast(context, -1,
intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout. example_appwidget );
remoteViews.setOnClickPendingIntent(R.id. widgetButtonId , pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
    }


APKBUS原创,转出请注明出处http://www.apkbus.com/forum.php及作者dreamyounger!


1.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值