您的位置:首页 > 移动开发 > Android开发

Android开发Widget之提高篇

2016-04-19 22:01 639 查看
在上一篇博客Android开发Widget之入门篇我们已经介绍了创建一个widget的流程。但是像这样的widget没什么实际用途,widget主要是为了显示一些信息,这样很方便,不用我们专门去启动应用查看信息,那么现在教大家做一个显示时间的widget。

效果如下:



这个与之前的widget不同的就是,它是启动了一个后台服务,服务注册了广播监听时间变化,当发生变化时就接受到广播然后更新时间。像之前的流程一样还是分三步。

一.建一个widget的布局。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/widget_marginTop"
android:paddingBottom="@dimen/widget_marginBottom" >

<TextView
android:id="@+id/appwidget_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:contentDescription="@string/appwidget_text"
android:textColor="@color/appwidget_view_time"
android:textSize="@dimen/appwidget_view_time"/>

</RelativeLayout>
二.在xml目录下新建一个 widget的配置文件。
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

android:initialLayout="@layout/time_widget"
android:minHeight="72dp"
android:minWidth="142dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal"
android:updatePeriodMillis="86400000" >

</appwidget-provider>
三.编写代码

新建一个TimeApplication继承自Application,调用TimeUpdateService的onReceive方法,在widget一启动就接受时间更新时间,然后启动TimeUpdateService.

public class TimeApplication extends Application {
@Override
public void onCreate() {

TimeUpdateService.mTimeTickReceiver.onReceive(getApplicationContext(),
null);
getApplicationContext().startService(
new Intent(getApplicationContext(), TimeUpdateService.class));
}
}
TimeUpdateService里注册广播,接受广播就更新时间.
public class TimeUpdateService extends Service {
//获取Calendar对象
private static Calendar mCalendar = Calendar.getInstance(TimeZone.getDefault());

//时间广播接收者
public static BroadcastReceiver mTimeTickReceiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
//时区改变则重新获取Calendar
if (intent != null) {
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
String tz = intent.getStringExtra("time-zone");
mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));
}
}
//设置当前时间
mCalendar.setTimeInMillis(System.currentTimeMillis());
//设置时间格式
boolean is24 = DateFormat.is24HourFormat(context);
SimpleDateFormat format = new SimpleDateFormat(is24 ? "H:mm" : "h:mm", Locale.getDefault());
String time = format.format(mCalendar.getTime());
//更新时间
TimeWidget.updateAppWidget(context, time);
}
};

@Override
public IBinder onBind(Intent intent) {

return null;
}

@Override
public void onCreate() {
super.onCreate();
//注册这个广播,当系统时间改变时就会发送广播
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getApplicationContext().registerReceiver(mTimeTickReceiver, filter);
}

@Override
public void onDestroy() {
super.onDestroy();
//注销广播
if (null != mTimeTickReceiver) {
getApplicationContext().unregisterReceiver(mTimeTickReceiver);
}
}
}
最后新建TimeWidget继承自AppWidgetProvider.
public class TimeWidget extends AppWidgetProvider {

//时间
private static String  mTime;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
//如果时间不为空,那么更新时间
if (mTime!=null) {
TimeWidget.updateAppWidget(context, mTime);
}
}

@Override
public void onEnabled(final Context context) {
super.onEnabled(context);
//启动后台服务检测时间变化
context.startService(new Intent(context, TimeUpdateService.class));
}

@Override
public void onDisabled(Context context) {
//当最后一个widget被移除时停止服务
context.stopService(new Intent(context, TimeUpdateService.class));
}

//更新widget
static void updateAppWidget(Context context, String time) {
//给mTime赋值
mTime = time;
//如果time不为null则更新
if (null != time) {
//widget管理者
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//远程view视图
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.time_widget);
//设置视图中的显示
views.setTextViewText(R.id.appwidget_time, time);
//指定要启动的组件
ComponentName mComponentName = new ComponentName(context, TimeWidget.class);
//更新
appWidgetManager.updateAppWidget(mComponentName, views);
}
}

}


这样就完成了时间widget,很简单的。如果你要做一个界面很复杂的widget你就要注意了,widget只支持部分View,像Button,AnalogClock,TextView,ImageView等,那么那些复杂,酷炫的widget是怎么实现的呢,这就要在framework层下去修改了,位置在frameworks/base/core/java/android/widget里面,资源文件存放在frameworks/base/core/res/res
里,感兴趣的朋友可以自己研究下。

最后附上Demo地址:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: