欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Widget 桌面组件开发介绍

程序员文章站 2024-03-05 18:57:43
android widget 桌面组件开发 widget是android1.5版所引进的特性之一.widget,可让用户在主屏幕界面及时了解程序显示的重要信息.标准的an...

android widget 桌面组件开发

widget是android1.5版所引进的特性之一.widget,可让用户在主屏幕界面及时了解程序显示的重要信息.标准的android系统已包含几个widget的示例,如模拟时钟,音乐播放器等.

一、appwidget 框架类

1、appwidgetprovider :继承自 broadcastrecevier , 在appwidget 应用 update、enable、disable 和 delete 时接收通知。其中,onupdate、onreceive 是最常用到的方法,它们接收更新通知。

2、 appwidgetprovderinfo:描述 appwidget 的大小、更新频率和初始界面等信息,以xml 文件形式存在于应用的 res/xml/目录下。

3、appwidgetmanger :负责管理 appwidget ,向 appwidgetprovider 发送通知。

4、remoteviews :一个可以在其他应用进程中运行的类,向 appwidgetprovider 发送通知。

二、appwidget 框架的主要类介绍

 1) appwidgetmanger 类

bindappwidgetid(int appwidgetid, componentname provider)
  通过给定的componentname 绑定appwidgetid

getappwidgetids(componentname provider)
  通过给定的componentname 获取appwidgetid

getappwidgetinfo(int appwidgetid)
  通过appwidgetid 获取 appwidget 信息

getinstalledproviders()
  返回一个list<appwidgetproviderinfo>的信息

getinstance(context context)
  获取 appwidgetmanger 实例使用的上下文对象

updateappwidget(int[] appwidgetids, remoteviews views)
  通过appwidgetid 对传进来的 remoteview 进行修改,并重新刷新appwidget 组件

updateappwidget(componentname provider, remoteviews views)
  通过 componentname 对传进来的 remoeteview 进行修改,并重新刷新appwidget 组件

updateappwidget(int appwidgetid, remoteviews views)
  通过appwidgetid 对传进来的 remoteview 进行修改,并重新刷新appwidget 组件

2) 继承自 appwidgetprovider 可实现的方法为如下:

1、ondeleted(context context, int[] appwidgetids)

2、ondisabled(context context)

3、onenabled(context context)

4、onreceive(context context, intent intent)
  tip:因为 appwidgetprovider 是继承自broadcastreceiver  所以可以重写onrecevie 方法,当然必须在后台注册receiver

5、onupdate(context context, appwidgetmanager appwidgetmanager, int[] appwidgetids)

三,demo 详解

 1.建立widget内容提供者文件,我们在res下建立xml文件夹,并且新建一个widget_provider.xml代码入下:

<?xml version="1.0" encoding="utf-8"?>   
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
  android:minwidth="50dip"  
  android:minheight="50dip"  
  android:updateperiodmillis="10000"  
  
  android:initiallayout="@layout/main"  
/>   

 tip:上文说过appwidgetprovderinfo 是在res/xml 的文件形式存在的,看参数不难理解,比较重要的是这里android:initiallayout="@layout/main" 此句为指定桌面组件的布局文件。

 主要设置的参数如下:

minwidth: 定义wdiget组件的宽度

minheight: 定义wdiget组件的高度

updateperiodmillis: 更新的时间周期

initiallayout: widget的布局文件

configure: 如果需要在启动前先启动一个activity进行设置,在这里给出activity的完整类名(后面会说到,与一般activity的实现有些许差别)

*widget大小的计算 :(单元格数*74)-2,api上说是为了防止像素计算时的整数舍入导致错所以-2...不是很明白

 2.修改main.xml布局,代码如下:

<?xml version="1.0" encoding="utf-8"?>   
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"  
  android:orientation="vertical"  
  android:layout_width="fill_parent"  
  android:layout_height="fill_parent"  
  android:background="@drawable/wordcup"  
  >   
<textview    
  android:id="@+id/wordcup"  
  android:layout_width="fill_parent"   
  android:layout_height="wrap_content"   
  android:text="@string/hello"  
  android:textsize="12px"  
  android:textcolor="#ff0000"  
  />
</linearlayout>

 tips:定义了widget界面布局的xml文件(位于res/layout/..),需要注意的是使用的组件必须是remoteviews所支持的,目前原生api中支持的组件如下:

framelayout、linearlayout、relativelayout

analogclock、button、chronmeter、imagebutton、imageview、progressbar、textview

*如果使用了除此之外的组件,则在widget创建时会导致android.view.inflateexceptionn异常。

ps:这就导致有一些功能或样式无法实现,如很基本的list或文本编辑框都是无法直接实现的。如果想自定义widget中的view的话只能通过修改framework来提供相应组件的支持。

 3.写一个类继承自appwidgetprovider

package com.android.tutor;   
import java.util.calendar;   
import java.util.date;   
import java.util.gregoriancalendar;   
import java.util.timer;   
import java.util.timertask;   
import android.appwidget.appwidgetmanager;   
import android.appwidget.appwidgetprovider;   
import android.content.componentname;   
import android.content.context;   
import android.widget.remoteviews;   
public class widetdemo extends appwidgetprovider {   
  /** called when the activity is first created. */  
    
  @override  
  public void onupdate(context context, appwidgetmanager appwidgetmanager,   
      int[] appwidgetids) {   
       
    timer timer = new timer();   
    timer.scheduleatfixedrate(new mytime(context,appwidgetmanager), 1, 60000);   
    super.onupdate(context, appwidgetmanager, appwidgetids);   
  }   
     
     
  private class mytime extends timertask{   
    remoteviews remoteviews;   
    appwidgetmanager appwidgetmanager;   
    componentname thiswidget;   
       
    public mytime(context context,appwidgetmanager appwidgetmanager){   
      this.appwidgetmanager = appwidgetmanager;   
      remoteviews = new remoteviews(context.getpackagename(),r.layout.main);   
         
      thiswidget = new componentname(context,widetdemo.class);   
    }   
    public void run() {   
         
      date date = new date();   
      calendar calendar = new gregoriancalendar(2010,06,11);   
      long days = (((calendar.gettimeinmillis()-date.gettime())/1000))/86400;   
      remoteviews.settextviewtext(r.id.wordcup, "距离南非世界杯还有" + days+"天");   
      appwidgetmanager.updateappwidget(thiswidget, remoteviews);   
         
    }   
       
  }   
    
}  

 appwidgetprovider实际上就是一个broadcastreceiver,里面提供了以下函数:

onreceive(context, intent)

onupdate(context , appwidgetmanager, int[] appwidgetids)

onenabled(context)

ondeleted(context, int[] appwidgetids)

ondisabled(context)

可通过重写以上函数来监听widget状态的变化并进行相应的处理。

onupdate 为组件在桌面上生成时调用,并更新组件ui,onreceiver 为接收广播时调用更新ui,一般这两个方法是比较常用的。

widget的更新与activity不同,必须借助于remoteviews和appwidgetmananger。

函数调用周期

[启动 - 无confiure activity] 
onreceive
onenabled —— 第一个widget被显示
onreceive
onupdate —— 刷新界面

[启动 - 带confiuration activity] 
onreceive
onupdate

[拖动] 
<无状态变化>

[周期更新] 
onreceive
onupdate

[删除] 
onreceive
ondeleted —— widget被删除
onreceive
ondisabled —— 最后一个widget被移除

[启动时位置不够] 
onreceive
onenabled
onreceive
onupdate
onreceive
ondeleted
onreceive
ondisabled

 *每次状态的变化会触发onreceive,一般该函数是不需要重写的。

 四、修改配置文件androidmanifest.xml,后台注册receiver,代码如下:

<?xml version="1.0" encoding="utf-8"?>   
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
   package="com.android.tutor"  
   android:versioncode="1"  
   android:versionname="1.0">   
  <application android:icon="@drawable/icon" android:label="@string/app_name">   
    <receiver android:name=".widetdemo"  
         android:label="@string/app_name">   
      <intent-filter>   
        <action android:name="android.appwidget.action.appwidget_update" />   
      </intent-filter>   
      <meta-data android:name="android.appwidget.provider"  
            android:resource="@xml/widget_provider"  
      />   
    </receiver>   
  </application>   
  <uses-sdk android:minsdkversion="7" />   
</manifest>   

 tips:

因为是桌面组件,所以暂时不考虑使用activity 界面,当然你在实现做项目时可能会需要点击时跳转到activity 应用程序上做操作,典型的案例为android  提供的音乐播放器。

上面代码中比较重要的是这一句 <meta-data android:name="android.appwidget.provider"  android:resource="@xml/appwidget_provider"></meta-data>  大意为指定桌面应用程序的appwidgetprovderinfo  文件,使其可作其管理文件。

五、添加修改资源

增加图片素材。

<?xml version="1.0" encoding="utf-8"?>   
<resources>   
  <string name="hello">hello world, widetdemo!</string>   
  <string name="app_name">daystoworldcup</string>   
</resources>

以上就是对android widget 资料的整理,希望能帮助需要的朋友。