您的位置:首页 > 其它

Widget、Timer、TimerTask、Handler、Message的综合使用

2016-02-28 20:19 453 查看

每一个Widget实际上就是一个BroadcastReceive,它们通过XML文件来描述Widget的细节。AppWidget框架通过Broadcast intents和Widget通信。Widget在更新组件与普通的android应用程序有些本质的不同。android应用程序在更新组件是会首先获得要更新组件的对象,然后直接对组件更新。而在Widget中并不能直接获得Widget中组件的对象,要想更新组件,必须要使用RemoteViews作为代理来更新Widget中的组件。

下面来看一下开发App Widget的具体步骤。

1.建立一个XML布局文件,在该布局文件中定义在Widget中显示的组件,但要注意,Widget并不支持所有的android组件。只能在Widget中使用如下组件类:

1)用于布局的组件类

FrameLayout

LinearLayout

RelativeLayout

2)用于开发界面的组件类

AnalogClock

Button

Chronometer  计时器

ImageButton

ImageView

ProgressBar

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="280dp"
android:layout_height="130dp"
android:background="@drawable/frame"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.clockwidget.MainActivity" >

<TextView
android:id="@+id/main_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="30sp"
android:text="@string/hello_world" />

</RelativeLayout>


2.创建Widget描述文件。该文件时XML格式,必须放在res/xml目录中。基本格式如下:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="300dp"
android:minHeight="150dp"
android:initialLayout="@layout/activity_main"   />


3.建立Widget类,该类必须从AppWidgetProvider类继承(AppWidgetProvider是BroadcastReceiver的子类,因此,Widget类可以接收广播消息)。在AppWidgetProvider中定义了几个接收Widget各种事件的方法,其中onUpdate是最常用的方法。在Widget加载时或到了android:updateReriondMillis属性指定的时间,系统会调用onUpdate方法。开发人员可以在该方法中更新Widget中的组件。

for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId=appWidgetIds[i];
//加载对应的布局类
RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.activity_main);
//设置时间转化格式
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
views.setTextViewText(R.id.main_time, sdf.format(new Date()));
appWidgetManager.updateAppWidget(appWidgetId, views);
}

其中,for循环,是数据放进去。但是,SDK1.5之后此方法android:updatePeriodMillis就失效了
,要自己创建service更新。

Timer timer=new Timer();
private TimerTask tt=new TimerTask() {

@Override
public void run() {
Message message=Message.obtain();
myHandler.sendMessage(message);
}
};
private Handler myHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
Log.d("lhm", "appwidget的长度是"+appWidgetIds.length);
for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId=appWidgetIds[i]; //加载对应的布局类 RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.activity_main); //设置时间转化格式 SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss"); views.setTextViewText(R.id.main_time, sdf.format(new Date())); appWidgetManager.updateAppWidget(appWidgetId, views); }
};
};使用schedule方法
//设置定时器,每隔1s发送
timer.schedule(tt, 0, 1000);

4.这是最后一步,也是最关键的一步。就是在AndroidManifest.xml文件中定义一个receiver,以便系统和Widget进行通信,下面是一个典型的receiver。

<receiver
android:name="com.example.clockwidget.TimerService"
android:label="MyUsefulClock" >
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/clockwidget" />
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
</receiver>

整体代码

在drawable-mdpi文件夹添加图片frame.png



时钟布局layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="280dp"
android:layout_height="130dp"
android:background="@drawable/frame"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.clockwidget.MainActivity" >

<TextView
android:id="@+id/main_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="30sp"
android:textColor="#000000" />

</RelativeLayout>

在res/xml的文件夹添加clockwidget.xml

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="300dp"
android:minHeight="150dp"
android:initialLayout="@layout/activity_main"
android:previewImage="@drawable/frame" />

在AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.clockwidget"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver
android:name="com.example.clockwidget.TimerService"
android:label="MyUsefulClock" >
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/clockwidget" />
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
</receiver>
</application>

</manifest>
package com.example.clockwidget;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

public class TimerService extends AppWidgetProvider {
private Context context;
private Timer timer=new Timer();
private int[] appWidgetIds;
private AppWidgetManager appWidgetManager;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
this.context=context;
this.appWidgetIds=appWidgetIds;
this.appWidgetManager=appWidgetManager;
//设置定时器,每隔1s发送 timer.schedule(tt, 0, 1000);}
private TimerTask tt=new TimerTask() {

@Override
public void run() {
Message message=Message.obtain();
myHandler.sendMessage(message);
}
};
private Handler myHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
Log.d("lhm", "appwidget的长度是"+appWidgetIds.length);
for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId=appWidgetIds[i]; //加载对应的布局类 RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.activity_main); //设置时间转化格式 SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss"); views.setTextViewText(R.id.main_time, sdf.format(new Date())); appWidgetManager.updateAppWidget(appWidgetId, views); }
};
};
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: