在上一篇博客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地址:點擊打開鏈接