安卓:App Widget应用程序小组件(一)
2013-09-28 20:10
417 查看
App Widgets 应用程序小组件(一)
关键的类
AppWidgetProvider
AppWidgetProviderInfo
AppWidgetManager
应用程序小组件是最小的能够嵌入到其他应用程序的应用程序Views,它能接收周期性的更新。这些Views以小组件的形式进行交付,你可以以一个应用程序小组件提供者的形式发布。能够持有App Widgets的应用程序被称作App Widget host.下面是音乐小组件的快照:
本文主要讨论"应用程序小组件提供者"(App Widget provider)。
Widget Design
For information about how to design your app widget, read the Widgets design
guide.
The Basics 基础
为了创建一个 App Widget,你需要这样做:AppWidgetProviderInfo对象 描述App widget 的元数据,例如他的布局,更新频率,AppWidgetProvider 类。这些都应该在XML文件中定义。
AppWidgetProvider类的实现 定义了基本的接口,允许你使用基于广播事件的方式编程。通过它,你能接收到App Widget的更新,使能,失效,删除。
View layout视图布局定义了关于App Widget的原始布局。此外,你可以实现一个App Widget配置Activity。
这是个可选的Activity,它允许在创建App
Widget时修改设置。 下面的章节描述了如何构建小组件。
Declaring an App Widget in the Manifest
在配置文件中声明App Widget。*译者提示:关键的几个注意点(1)(2)(3)
(1)指定AppWidgetProvider对象(实际就是一个广播接收器) <receiver>标签项name所指:
ExampleAppWidgetProvider
(2)指定AppWidgetProviderInfo对象(配置信息)
通过android.appwidget.provider,确定其是ProviderInfo类型
android.appwidget.provider
指定该对象对应的XML文件位置(显示在桌面上的widget的布局文件)
@xml/example_appwidget_info
(3)指定广播更新的类型:WIDGET UPDATE
android.appwidget.action.APPWIDGET_UPDATE
下面是译文:
首先,在应用程序的AndroidManifest文件中声明AppWidgetProvider类。
<receiver android:name="ExampleAppWidgetProvider" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" /> </receiver>
元素
<receiver>需要android:name属性,它指定了小组件的AppWidgetProvider。
元素<intent-filter>必须包括<action>元素,而<action>元素必定含有
android:name属性。这个属性指定了AppWidgetProvider接收ACTION_APPWIDGET_UPDATE广播。这是唯一必须显式声明的广播,
AppWidgetManager自动发送其他种类的小组件广播给AppWidgetProvider。
元素<meta-data>指定了AppWidgetProviderInfo资源,并需要如下属性:
android:name- 指定元数据的名字. 使用
android.appwidget.provider来识别数据 作为
AppWidgetProviderInfo描述符.
android:resource- 指定
AppWidgetProviderInfo资源位置.
增加 AppWidgetProviderInfo 元数据
它定义了一些必要的属性,例如最小布局尺寸,原始布局资源,更新周期,创建时的配置Activity(可选)。在XML中定义AppWidgetProviderInfo对象应当使用<appwidget-provider>元素,并保存在工程的res/xml/文件夹中。举例如下:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="86400000" android:previewImage="@drawable/preview" android:initialLayout="@layout/example_appwidget" android:configure="com.example.android.ExampleAppWidgetConfigure" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard" android:initialKeyguardLayout="@layout/example_keyguard"> </appwidget-provider>
下面是<appwidget-provider>属性的总结:
属性
minWidth和
minHeight指定了小组件默认情况下消耗的空间。
属性minResizeWidth和
minResizeHeight指定了绝对最小值,小于此值将导致无效。使用时,应当小于
minWidth和
minHeight属性。
属性updatePeriodMillis指定了小组件框架通过调用)]onUpdate()回调方法来更新AppWidgetProvider的时间。
属性initialLayout指定了App
Widget布局资源.
属性configure指定了App
Widget创建时可选的Activity,它可用于设置小组件.
属性autoAdvanceViewId设置后,组件持有者会自动为子视图增加ID。在安卓3.0引入。
属性resizeMode指定了小组件调整大小的规则。你使用这个属性来使得桌面小组件能够被调整大小——横向的,纵向的,或者两者皆可。在安卓3.1版本引入。
属性minResizeHeight指了组件被重调大小的最小高度值。安卓4.0引入。
属性minResizeWidth 指了组件被重调大小的最小宽度值。安卓4.0引入。
属性widgetCategory声明你的小组件能否显示在桌面,或者锁屏,或者两者中。安卓4.2引入。
属性
initialKeyguardLayout指定了定义在锁屏中的小组件的布局。安卓4.2引入。
注意:如果设备在更新时,正处于睡眠状态,那么设备将被唤醒来执行更新。如果更新时间超过一小时,那么这不会对电池构成显著的影响。如果你需要更高频率的更新,且不需要在睡眠时更新,使用基于闹钟的方式。使用AlarmManager,在AppWidgetProvider中设定Intent.使用
ELAPSED_REALTIME或者
RTC
闹钟类型都可以,它只会在设备醒着的时候才驱动闹铃。这时,设定updatePeriodMillis为0(zero).
Creating the App Widget Layout 创建小组件布局
你应该定义一个初始的布局XML文件,并保存在res/layout/目录下。你可以使用下面的View.在你开始设计之前,你必须阅读,并理解AppWidget Design Guidelines.
如果你熟悉布局,创建小组件布局是简单的。你必须有这样一种意识:小组件是基于RemoteViews,他不支持每一种布局或者组件视图。
*译者提示:就是说你可以认为小组件是在其他的应用程序里面运行,所以它的形式受到了限制。
下面这些是支持的:
FrameLayout
LinearLayout
RelativeLayout
GridLayout
下面这些类是支持的,但是它的子类不支持:
AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
RemoteViews还支持
ViewStub。它是一种不可见的,0尺寸的视图,你可以在允许时膨胀它。
使用AppWidgetProvider类
使用Manifest中的<receiver>标签AppWidgetProvider作为继承自BroadcastReceiver的便利类,它能够接受小组件广播。它只接收与其相关的广播,例如更新,删除,使能,失效。当广播事件发生时,AppWidgetProvider 接收下面这些方法的调用:
)]onUpdate()经过了updatePeriodMillis间隔后,这个方法会被调用,以更新App
Widget。在用户添加App
Widget时,这个方法也会被调用,所以它应该执行必要的更新,例如定义View的处理函数或者开启一个临时的Service。当然,如果你定义了配置Activity,那么在添加小组件中将不会被触发,但是在随后的更新中会被调用。有必要将第一次更新的事情交给配置Activity来执行。
onAppWidgetOptionsChanged()
This is called when the widget is first placed and any time the widget is resized. You can use this callback to show or hide content based on the widget's size ranges. You get the size ranges by calling
getAppWidgetOptions(),
which returns a
Bundlethat includes the
following:
OPTION_APPWIDGET_MIN_WIDTH—Contains
the lower bound on the current width, in dp units, of a widget instance.
OPTION_APPWIDGET_MIN_HEIGHT—Contains
the lower bound on the current height, in dp units, of a widget instance.
OPTION_APPWIDGET_MAX_WIDTH—Contains
the upper bound on the current width, in dp units, of a widget instance.
OPTION_APPWIDGET_MAX_HEIGHT—Contains
the upper bound on the current width, in dp units, of a widget instance.
This callback was introduced in API Level 16 (Android 4.1). If you implement this callback, make sure that your app doesn't depend on it since it won't be called on older devices.
onDeleted(Context, int[])
当App Widget被从App
Widget host删除时,这个方法被调用。
onEnabled(Context)
当第一个实例被创建时调用。举个例子,如果在App Widget中有两个实例,这仅仅在第一次创建时被调用。
onDisabled(Context)
这仅仅在最后一个实例被从App Widget host移除才调用。
onReceive(Context, Intent)
任何广播都会触发此回调函数,它先于其他上面提到的回调函数。你通常不需要实现这个方法,这是因为App widget Provide的过滤机制,以及以上已经实现好的回调。
AppWidgetProvider最重要的回调方法是)]onUpdate(),因为你每向容器中添加一个都会触发此方法(除非你配置了“设置Activity”)。如果你接收任何的用户交互事件,那么你应该在事件处理中注册这个回调。如果你的应用程序不会创建任何临时文件后者数据库,或者其他需要被清除的任务,那么onUpdate()仅仅只是定义了的一个回调。举个例子,如果你希望点击你的widget之后,会启动一个Activity,那么你可以按照下面的实现。
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N = appWidgetIds.length; // Perform this loop procedure for each App Widget that belongs to this provider for (int i=0; i<N; i++) { int appWidgetId = appWidgetIds[i]; // 创建一个启动ExampleActivity 的 Intent ,然后用PendingIntent包装它. Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); // Get the layout for the App Widget and attach an on-click listener // to the button RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // 告诉 AppWidgetManager 对当前的Widget执行更新 onUpdate() appWidgetManager.updateAppWidget(appWidgetId, views); } } }
AppWidgetProvider 仅仅定义了)]onUpdate()方法,这是为了定义一个启动Activity的PendingIntent,并将这个PendingIntent与小组件的按钮通过方法setOnClickPendingIntent(int,
PendingIntent)来进行绑定。注意到,这包含了一个迭代访问所有appWidgetIds条目的循环,这是一个包含提供者创建的小组件的ID标识符数组。在这种情况下,如果用户创建不止一个小组件实例,他们都将被同时更新。举个例子,如果更新被定为2个小时一次,第二个组件是在第一个组件添加之后添加的,那么他们将会以第一个定义的周期进行更新,第二个将被忽略(就是他们同时以两小时一次进行更新,而不是每小时)
注意:由于AppWidgetProvider扩展自BroadcastReceiver,不担保回调函数返回后,你的程序保持运行状态。如果你的小组件更新程序需要花费数秒,那么考虑在)]onUpdate()方法中启动一个服务。
在那个服务中,你可以执行小组件的更新,而不需要担心小组件由于 ANR错误被关闭。
相关文章推荐
- 安卓翻译——app组件
- (4.1.27.1)Android之桌面组件App Widget案例
- AppWidget组件的处理事件
- AppWidget(桌面组件)
- 安卓四大组件之一#3-使用Intent的隐式意图访问系统app
- Android的桌面组件App Widget的使用方法 AppWidgetProvider RemoteViews
- 安卓控件APPwidget 一
- Android桌面组件App Widget开发三步走
- 安卓开发之 App Widget
- Android桌面组件AppWidget讲解
- Android之桌面组件AppWidget
- Android之桌面组件App Widget案例
- 安卓中设定组件大小出现android.widget.linearlayout layoutparams错误的解决
- 桌面组件AppWidget
- 使用cordova将Ext JS 6.2的Modern应用程序打包为安卓APP
- 【Android API指南】App组件(1) - 应用程序基础
- (4.1.27.1)Android之桌面组件App Widget案例之高仿墨迹天气桌面组件
- 安卓开发小知识-AppWidget入门
- 理解与应用Android桌面组件AppWidget
- android app widget,安卓桌面小工具的使用