AppWidget 可在桌面顯示動態內容。本文以數位時鐘為例,完整展示 Manifest 配置、Layout 佈局、Provider 與 Service 協作實現每秒更新。
<receiver android:name=".TimeWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/timewidget_info" />
</receiver>
<service android:name=".TimerService" />
<appwidget-provider xmlns:android="https://schemas.android.com/apk/res/android"
android:initialLayout="@layout/time_appwidget"
android:minHeight="40dp"
android:minWidth="180dp"
android:updatePeriodMillis="0" />
<!-- updatePeriodMillis=0 表示不依賴系統自動更新,改由 Service 推送 -->
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/rectangle"
android:padding="8dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="#000"
android:text="00:00:00" />
</LinearLayout>
<shape xmlns:android="https://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="12dp" />
<gradient
android:angle="270"
android:startColor="#B3F0FF"
android:endColor="#5EADF4" />
<stroke android:width="2dp" android:color="#0000FF" />
</shape>
public class TimeWidgetProvider extends AppWidgetProvider {
@Override
public void onEnabled(Context context) {
// 首次添加啟動 Service
context.startService(new Intent(context, TimerService.class));
}
@Override
public void onDisabled(Context context) {
// 最後一個移除停止 Service
context.stopService(new Intent(context, TimerService.class));
}
@Override
public void onUpdate(Context context, AppWidgetManager manager, int[] ids) {
// 系統定期回調(此處不做事,由 Service 推送)
}
}
public class TimerService extends Service {
private Timer timer = new Timer();
@Override
public void onCreate() {
super.onCreate();
// 每秒執行一次
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
updateWidget();
}
}, 0, 1000);
}
private void updateWidget() {
String time = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date());
RemoteViews views = new RemoteViews(getPackageName(), R.layout.time_appwidget);
views.setTextViewText(R.id.textView, time);
ComponentName cn = new ComponentName(this, TimeWidgetProvider.class);
AppWidgetManager.getInstance(this).updateAppWidget(cn, views);
}
@Override public void onDestroy() {
timer.cancel();
super.onDestroy();
}
@Override public IBinder onBind(Intent intent) { return null; }
}
AlarmManager + BroadcastReceiver 替代 Timer,更省電且系統休眠也能喚醒。NotificationChannel 若 Service 前台運行。timewidget_info 宣告 android:resizeMode="horizontal|vertical"。