当前位置: 移动技术网 > 移动技术>移动开发>Android > Android桌面插件App Widget用法分析

Android桌面插件App Widget用法分析

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文实例讲述了android桌面插件app widget用法。分享给大家供大家参考,具体如下:

应用程序窗口小部件app widgets

应用程序窗口小部件(widget)是微小的应用程序视图,可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个app widget provider来发布一个widget。可以容纳其它app widget的应用程序组件被称为app widget宿主。下面的截屏显示了一个音乐app widget。

appwidget

这篇文章描述了如何使用app widget provider发布一个app widget。

基础知识the basics

为了创建一个app widget,你需要下面这些:

appwidgetproviderinfo 对象

描述一个app widget元数据,比如app widget的布局,更新频率,以及appwidgetprovider 类。这应该在xml里定义。

appwidgetprovider 类的实现

定义基本方法以允许你编程来和app widget连接,这基于广播事件。通过它,当这个app widget被更新,启用,禁用和删除的时候,你都将接收到广播通知。

视图布局

为这个app widget定义初始布局,在xml中。

另外,你可以实现一个app widget配置活动。这是一个可选的活动activity,当用户添加app widget时加载并允许他在创建时来修改app widget的设置。

下面的章节描述了如何建立这些组件:

在清单中声明一个应用小部件

首先,在应用程序androidmanifest.xml文件中声明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 < src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" type="text/javascript"> < srcsrc="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" type="text/javascript"> " />
</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 资源路径。

增加appwidgetproviderinfo元数据

appwidgetproviderinfo定义一个app widget的基本特性,比如最小布局尺寸,初始布局资源,刷新频率,以及(可选的)创建时加载的一个配置活动。使用单独的一个<appwidget-provider>元素在xml资源里定义appwidgetproviderinfo 对象并保存到项目的res/xml/目录下。

比如:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:minwidth="294dp" <!-- density-independent pixels -->
  android:minheight="72dp"
  android:updateperiodmillis="86400000" <!-- once per day -->
  android:initiallayout="@layout/example_appwidget"
  android:configure="com.example.android.exampleappwidgetconfigure" >
</appwidget-provider>

下面是<appwidget-provider>属性的总结:

·         minwidth 和minheight 属性的值指定了这个app widget布局需要的最小区域。

缺省的app widgets所在窗口的桌面位置基于有确切高度和宽度的单元网格。如果app widget的最小长宽和这些网格单元的尺寸不匹配,那么这个app widget将收缩到最接近的单元尺寸。(参见app widget design guidelines 以获取更多关于桌面单元尺寸的信息)

因为桌面布局方向(由此,单元的尺寸)可以变化,按照拇指规则,你应该假设最坏情况单元尺寸是74像素高和宽。不过,你必须从最后的尺寸中减去2以把像素计算过程中产生的任何的整数舍入误差考虑在内。要找到像素密度无关的最小宽度和高度,使用这个公式:

(number of cells * 74) - 2

遵循这个公式,你应该使用72dp为每一个单元高度,294dp为四个单元宽度。

·         updateperdiodmillis 属性定义了app widget框架调用onupdate()方法来从appwidgetprovider请求一次更新的频度。实际更新时间并不那么精确,而且我们建议更新频率越低越好-也许每小时不超过一次以节省电源。你也许还会允许用户在配置中调整这个频率-一些人可能想每15分钟一次股票报价,或者一天只要四次。
·         initiallayout属性指向定义app widget布局的资源。
·         configure属性定义了activity ,当用户添加app widget时启动,以为他或她配置app widget特性。这是可选的(阅读下面的creating an app widget configuration activity)。

参见appwidgetproviderinfo 类以获取更多可以被<appwidget-provider>元素接受的属性信息。

创建app widget布局

你必须在xml中为你的app widget定义一个初始布局并保存到项目的res/layout/ 目录下。你可以使用如下所列的视图对象来设计你的app widget,但是在此之前,请先阅读并理解app widget design guidelines.

如果你熟悉在xml中声明布局,那么创建这个app widget布局是很简单的。但是,你必须意识到那个app widget布局是基于remoteviews, 这并不支持所有类型的布局或视图小部件。

一个remoteviews对象(以及,相应的,一个app widget)可以支持下面这个布局类:

·         framelayout
·         linearlayout
·         relativelayout

以及下面的小部件类:

·         analogclock
·         button
·         chronometer
·         imagebutton
·         imageview
·         progressbar
·         textview

不支持这些类的派生。

使用appwidgetprovider类

你必须通过在清单文件中使用<receiver>元素来声明你的appwidgetprovider 类实现为一个广播接收器(参见上面的declaring an app widget in the manifest)。

appwidgetprovider 类扩展broadcastreceiver 为一个简便类来处理app widget广播。appwidgetprovider只接收和这个app widget相关的事件广播,比如这个app widget被更新,删除,启用,以及禁用。当这些广播事件发生时,appwidgetprovider 将接收到下面的方法调用:

onupdate(context, appwidgetmanager, int[])

这个方法调用来间隔性的更新app widget,间隔时间用appwidgetproviderinfo 里的updateperiodmillis属性定义(参见添加appwidgetproviderinfo元数据)。这个方法也会在用户添加app widget时被调用,因此它应该执行基础的设置,比如为视图定义事件处理器并启动一个临时的服务service,如果需要的话。但是,如果你已经声明了一个配置活动,这个方法在用户添加app widget时将不会被调用,而只在后续更新时被调用。配置活动应该在配置完成时负责执行第一次更新。(参见下面的创建一个app widget配置活动creating an app widget configuration activity。)

ondeleted(context, int[])

当app widget从宿主中删除时被调用。

onenabled(context)

当一个app widget实例第一次创建时被调用。比如,如果用户添加两个你的app widget实例,只在第一次被调用。如果你需要打开一个新的数据库或者执行其他对于所有的app widget实例只需要发生一次的设置,那么这里是完成这个工作的好地方。

ondisabled(context)

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

onreceive(context, intent)

这个接收到每个广播时都会被调用,而且在上面的回调函数之前。你通常不需要实现这个方法,因为缺省的appwidgetprovider 实现过滤所有app widget 广播并恰当的调用上述方法。

注意: 在android 1.5中, 有一个已知问题,ondeleted()方法在该调用时不被调用。为了规避这个问题,你可以像group post中描述的那样实现onreceive() 来接收这个ondeleted()回调。

最重要的appwidgetprovider 回调函数是onupdated(), 因为它是在每个app widget添加进宿主时被调用的(除非你使用一个配置活动)。如果你的app widget 要接受任何用户交互事件,那么你需要在这个回调函数中注册事件处理器。如果你的app widget不创建临时文件或数据库,或者执行其它需要清理的工作,那么onupdated() 可能是你需要定义的唯一的回调函数。比如,如果你想要一个带一个按钮的app widget,当点击时启动一个活动,你可以使用下面的appwidgetprovider实现:

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, 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);
      // tell the appwidgetmanager to perform an update on the current app widget
      appwidgetmanager.updateappwidget(appwidgetid, views);
    }
  }
}

这个appwidgetprovider 仅定义了onupdated() 方法,为了定义一个pendingintent,来启动一个活动并使用setonclickpendingintent(int, pendingintent)方法把它附着到这个app widget的按钮上。注意它包含了一个遍历appwidgetids中所有项的循环,这是一个ids数组,每个id用来标识由这个provider创建的一个app widget。这样,如果用户创建多于一个这个app widget的实例,那么它们将被同步更新。不过,对于所有的app widget实例,只有一个updateperiodmillis 时间表被管理。比如,如果这个更新时间表被定义为每隔两个小时,而且app widget的第二个实例是在第一个后面一小时添加的,那么它们将按照第一个所定义的周期来更新而第二个被忽略(它们将都是每2个小时进行更新,而不是每小时)。

注意: 因为这个appwidgetprovider 是一个广播接收器broadcastreceiver,不能保证你的进程在回调函数返回后仍然继续运行(参见应用程序基础>广播接收器的生命周期application fundamentals > broadcast receiver lifecycle以获取更多信息)。如果你的app widget设置过程能持续几秒钟(也许当执行网页请求时)而且你要求你的进程继续,考虑在onupdated()方法里启动一个服务service 。从这个服务里,你可以执行自己的app widget更新,而不必担心appwidgetprovider 由于一个应用程序无响应错误application not responding (anr)而关闭。参见wiktionary sample's appwidgetprovider,这是个app widget运行一个service的例子。

同样参见exampleappwidgetprovider.java 例子类。

接收app widget广播意图

appwidgetprovider 只是一个简便类。如果你想直接接收app widget 广播,你可以实现自己的broadcastreceiver 或者重写 onreceive(context, intent) 回调函数。你需要注意的4个意图如下:

·         action_appwidget_update
·         action_appwidget_deleted
·         action_appwidget_enabled
·         action_appwidget_disabled

创建一个app widget 配置活动

如果你想让用户在添加一个新的app widget时调整设置,你可以创建一个app widget配置活动。这个活动将被app widget宿主自动启动并允许用户在创建时配置可用的设置,比如app widget颜色,尺寸,更新周期或者其它功能设置。

这个配置活动应该在android清单文件中声明为一个通用活动。不过,它将被通过action_appwidget_configure活动而被app widget宿主启动,因此这个活动需要接受这个意图。比如:

<activity android:name=".exampleappwidgetconfigure">
  <intent-filter>
    <action android:name="android.appwidget.action.appwidget_configure" />
  </intent-filter>
</activity>

同样的,活动必须在appwidgetproviderinfo xml 文件中声明,通过android:configure属性(参见上面的添加appwidgetproviderinfo元数据adding the appwidgetproviderinfo metadata)。比如,配置活动可以声明如下:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  android:configure="com.example.android.exampleappwidgetconfigure"
  ... >
</appwidget-provider>

注意这个活动是用全名声明的,因为它将从你的程序包外被引用。
这就是所有关于配置活动你一开始需要了解的。现在你需要一个真实的活动。这儿就有,不过,当你实现这个活动时记住两件重要的事情:

•  app widget 宿主调用配置活动而且配置活动应该总是返回一个结果.这个结果应该包含这个通过启动该活动的意图传递的app widget id(以extra_appwidget_id保存在意图的附加段intent extras中)

•  当这个 app widget 被创建时将不会调用onupdate() 方法(当一个配置活动启动时,系统将不会发送action_appwidget_update广播).配置活动应该在 app widget 第一次被创建时负责从appwidgetmanager请求一个更新.不过, onupdate() 将在后续更新中被调用-只忽略第一次.

参见下面章节的代码片断,该示例说明了如何从配置中返回一个结果并更新这个app widget.

从配置活动中更新一个app widget

当一个app widget使用一个配置活动,那么当配置结束时,就应该由这个活动来更新这个app widget.你可以直接appwidgetmanager里请求一个更新来这么做.

下面是恰当的更新app widget 以及关闭配置活动这个过程的一个概要描述:

1. 首先,从启动这个活动的意图中获取app widget id:

intent intent = getintent();
bundle extras = intent.getextras();
if (extras != null) {
  mappwidgetid = extras.getint(
      appwidgetmanager.extra_appwidget_id,
      appwidgetmanager.invalid_appwidget_id);
}

2. 实施你的app widget 配置。

3. 当配置完成后,通过调用getinstance(context)获取一个appwidgetmanager实例:

复制代码 代码如下:
appwidgetmanager appwidgetmanager = appwidgetmanager.getinstance(context);

4. 以一个remoteviews布局调用updateappwidget(int, remoteviews)更新app widget:

remoteviews views = new remoteviews(context.getpackagename(), r.layout.example_appwidget);
appwidgetmanager.updateappwidget(mappwidgetid, views);

5. 最后,创建返回意图,设置活动结果,并结束这个活动:

intent resultvalue = new intent();
resultvalue.putextra(appwidgetmanager.extra_appwidget_id, mappwidgetid);
setresult(result_ok, resultvalue);
finish();

提示: 当你的配置活动第一次打开时,设置活动结果为result_canceled。这样,如果用户在结束之前从活动外返回,这个app widget 宿主会接收到配置取消通知而不会添加这个app widget。

更多关于android相关内容感兴趣的读者可查看本站专题:《android视图view技巧总结》、《android编程之activity操作技巧总结》、《android操作sqlite数据库技巧总结》、《android操作json格式数据技巧总结》、《android数据库操作技巧总结》、《android文件操作技巧汇总》、《android编程开发之sd卡操作方法汇总》、《android开发入门与进阶教程》、《android资源操作技巧汇总》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网