Android组件之App Widgets

最近下定决心潜心学习下Android的基础,开始研读Android的官方文档,先学习下平时不太常用的组件——App Widgets。

那既然要学习App Widgets,首先需要知道App Widgets到底是什么,那我们先来看看官网上的定义:App Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates. 翻译成中文:App Widgets是可以嵌入到其他应用,如桌面,并能接收到周期性更新的微型应用视图。有了这个定义很清楚的就明白了,App Widgets是什么了,它就是一个小组件。那么怎么实现App Widgets呢?

如果希望实现点击桌面上的小组件,打开应用程序,实现步骤:

  1. 完成普通应用程序的相关开发,例如笔者写一个简单的音乐播放器;

  2. 在AndroidManifest.xml中,加入以下代码:

    <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属性,它指定了App Widget使用的AppWidgetProvider 。

    <intent-filter>元素必须包括一个含有android:name属性的<action>元素。该元素指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE 广播。这是唯一你必须显式声明的广播。当需要的时候,AppWidgetManager 会自动发送所有其他App Widget广播给AppWidgetProvider。

    <meta-data> 元素指定了AppWidgetProviderInfo 资源并需要以下属性:

    • android:name – 指定元数据名称。
    • android:resource – 指定AppWidgetProviderInfo 资源路径。
  3. 在layout中创建小组件的视图xml,example_appwidget.xml,如本例中笔者编写的视图中包括TextView和ImageButton,如下:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:orientation="horizontal"
        android:background="#ffffffff"
        android:padding="@dimen/widget_margin">
    
        <TextView
            android:id="@+id/app_widget_text"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="@string/main" />
    
        <ImageButton
            android:id="@+id/app_widget_play"
            android:layout_width="@dimen/my_button_width"
            android:layout_height="match_parent"
            android:contentDescription="@string/play"
            android:src="@drawable/ic_action_play" />
    </LinearLayout>

    其中在res/values/dimens.xml中:

    <dimen name=”widget_margin”>8dp</dimen>

    <dimen name=”my_button_width”>32dp</dimen>

  4. 创建xml目录,在xml目录中创建example_appwidget_info.xml,加入如下代码:

    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="216dp"
        android:minHeight="56dp"
        android:updatePeriodMillis="86400000"
        android:initialLayout="@layout/example_appwidget">
    </appwidget-provider>

    minWidth和minHeight属性的值指定了这个App Widget布局需要的默认最小区域。默认的App Widgets所在窗口的桌面位置基于有确切高度和宽度的单元网格。如果App Widget的最小长宽和这些网格单元的尺寸不匹配,那么这个App Widget将收缩到最接近的单元尺寸。关于尺寸具体怎样设计比较好,可参考点击此处

    updatePerdiodMillis 属性定义了App Widget框架调用onUpdate()方法来从AppWidgetProvider请求一次更新的频度。实际更新时间并不那么精确,而且我们建议更新频率越低越好-也许每小时不超过一次以节省电源。你也许还会允许用户在配置中调整这个频率-一些人可能想每15分钟一次股票报价,或者一天只要四次。

    initialLayout属性指向定义App Widget布局的资源。

  5. 创建类ExampleAppWidgetProvider,代码如下:

    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];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, MainActivity.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.example_appwidget);
            views.setOnClickPendingIntent(R.id.app_widget_text, pendingIntent);
            Intent intentClcik = new Intent(context, PlayMusicService.class);
            PendingIntent pendingIntentClcik = PendingIntent.getService(context, 0, intentClcik, 0);
            views.setOnClickPendingIntent(R.id.app_widget_play, pendingIntentClcik);
            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
                }
            }
        }

    AppWidgetProvider类是处理App Widget广播的,继承于BroadcastReceiver。AppWidgetProvider仅能接收到App Widget相关的广播,如更新,删除,启用,禁用。相应会调用如下方法:

    • onUpdate()

    这个方法调用来间隔性的更新App Widget,间隔时间用AppWidgetProviderInfo 里的updatePeriodMillis属性定义。这个方法也会在用户添加App Widget时被调用,因此它应该执行基础的设置,比如为视图定义事件处理器并启动一个临时的服务Service,如果需要的话。但是,如果你已经声明了一个配置活动,这个方法在用户添加App Widget时将不会被调用,而只在后续更新时被调用。配置活动应该在配置完成时负责执行第一次更新。

    • onAppWidgetOptionsChanged()

    当小组件第一次被放置在宿主或者被重新定义尺寸时调用。你可以使用这个回调来展示或者隐藏基于小组件尺寸范围的内容。你可以通过调用getAppWidgetOptions()方法来获得尺寸范围,getAppWidgetOptions()方法会返回一个Bundle,包括有:

    OPTION_APPWIDGET_MIN_WIDTH—以dp为单位的小组件实例的最小宽度
    OPTION_APPWIDGET_MIN_HEIGHT—以dp为单位的小组件实例的最小高度
    OPTION_APPWIDGET_MAX_WIDTH—以dp为单位的小组件实例的最大宽度
    OPTION_APPWIDGET_MAX_HEIGHT—以dp为单位的小组件实例的最大高度
    

    这个回调API Level16(Android 4.1)以上支持,如果实现了该方法,请确保应用不依赖于此方法,因为在比较老的机器上该方法无法被调用。

    • onDeleted(Context, int[])

    每次从宿主中删除App Widget实例时调用。

    • onEnabled(Context)

    当AppWidget实例第一次创建时调用。例如,如果用户添加两个App Widget实例,只会调用一次该方法。如果需要打开一个新的数据库或者完成对所有App Widget实例只进行一次的其他设置,可以放在这里执行。

    • onDisabled(Context)

    当你的App Widget的最后一个实例被从宿主中删除时被调用。你应该在onEnabled(Context)中做一些清理工作,比如删除一个临时的数据库。

    • onReceive(Context, Intent)

    每次广播均会调用此方法,并且在上述其他方法之前被调用。一般不需要实现该方法,因为默认的AppWidgetProvider可以过滤出所有的App Widget广播,并且调用以上方法。

    最重要的AppWidgetProvider 回调函数是onUpdated(), 因为它是在每个App Widget添加进宿主时被调用的(除非你使用一个配置活动)。如果你的App Widget 要接受任何用户交互事件,那么你需要在这个回调函数中注册事件处理器。如果你的App Widget不创建临时文件或数据库,或者执行其它需要清理的工作,那么onUpdated() 可能是你需要定义的唯一的回调函数。

    所以在本程序中,笔者仅实现了onUpdate()方法。

    调用PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)方法,可以启动一个新的Activity,调用PendingIntent.getService(Context context, int requestCode, Intent intent, int flags)方法,可以启动一个新的Service。

    这里点击程序入口的TextView可以启动程序的MainActivity,点击播放的ImageButton,可以启动播放音乐的Service。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值