最近一直专研Android开发,希望得到大家的支持与帮助!这是最近学AppWidget做的笔记,希望帮到需要的人!让大家更快的进步!(一下只标注了核心代码,相信大家一定可以看懂的,若需要源码,可以回复说明,也希望大家顶顶贴!至于奖品吧。。。。当然期待哦!)
一、核心功能介绍(一)appwidget介绍:
当第三个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate
删除一个widget时,执行顺序为:
onreceive
onDeleted
删除最后一个widget时,执行顺序为:
onreceive
onDeleted
onreceive
onDisabled
一、核心功能介绍(一)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
onEnabled
onreceive
onUpdate
当第二个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate
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
* 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 组件
目标:创建一个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!