安卓開發之 App Widget
一、什麼是App Widget
Android平臺上在桌面上所放置的一種小控制元件
與App Widget相關的類/物件:
AppWidgetProviderInfo物件:
定義App Widget的一些資訊,為App Widget提供後設資料,包括App Widget佈局檔案的指定,更新頻率等資料。 這個物件被定義在XML檔案當中,其相對於一個Config配置“檔案”.
AppWidgetProvider:
繼承自BroadcastReicever廣播接收器。 定義了App Widget的基本生命週期的回撥函式.
二、建立一個App Widget的步驟
一、定義AppWidgetProviderInfo:
在res/xml資料夾當中定義描述AppWidgetProviderInfo的xml檔案。
例:…\res\xml\appwidget_info.xml
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minHeight="60dp" android:minWidth="200dp" android:previewImage="@drawable/default_img" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="40000" android:initialLayout="@layout/appwidget_layout" > </appwidget-provider>
updatePeriodMillis為更新的毫秒數、initialLayout為初始化的widget佈局;
previewImage為該app widget的預覽圖,在桌面小部件選擇時顯示;
resizeMode:app widget 在水平和垂直方向是否可以調整大小。
二、為App Widget指定佈局:
定義App Widget展示時的佈局檔案appwidget_layout
例:…\res\layout\appwidget_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00000000" > <TextView android:id="@+id/widget_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="widget text" /> <Button android:id="@+id/widget_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="widget button" /> </LinearLayout>
三、實現AppWidgetProvider
onUpdate:在到達指定的更新時間之後或者當使用者向桌面新增App Widget時會呼叫該方法
onDeleted:在App Widget被刪除時,會呼叫該方法
onEnable:當一個App Widget的例項第一次被建立時,會呼叫該方法
onDisable:當最後一個App Widget例項被刪除後,會呼叫該方法
onReceive:監聽/接收廣播事件,可用於處理控制元件的點選事件等
(桌面上可以有多個同樣的app widget)
例:
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
}
因AppWidgetProvider又繼承自BroadcastReceiver,所以需要在AndroidManifest中註冊:
<receiver android:name=".MyAppWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info"/>
</receiver>
其中action是引用android自定義的action,meta-data為後設資料:resource為說明該App Widget 的配置資訊的xml檔案,name必須是android.appwidget.provider。
三、使用App Widget佈局中的控制元件
>使用App Widget佈局中的控制元件其中涉及到了PendingIntent,RemoteViews..
一、PendingIntent
Pending:待處理的。PendingIntent 可以看作為一種“留待日後處理”的意圖,是對Intent的一種包裝,建立之後並不馬上使用,一旦某種觸發事件的發生,意圖才馬上執行。
- App Widget和應用程式並不是在同一程式當中。
建立PendingIntent物件的三個靜態方法:
- getActivity(Context context, int requestCode, Intent intent, int flags)
- getBroadcast(Context context, int requestCode, Intent intent, int flags)
- getService(Context context, int requestCode, Intent intent, int flags)
根據PeningIntent具體傳送/啟動(廣播/Activity/服務)來選擇對應的一個靜態方法來建立PendingIntent物件。
二、RemoteViews的作用
RemoteViews:遠端控制元件。App Widget裡的控制元件和主程式不在同一程式中,所以App Widget裡的控制元件相對於一種遠端控制元件。
- RemoteViews物件表示了一系列的View物件。
- RemoteViews所表示的物件執行在另外的程式中。
- App Widget當中的View執行在Home Screen程式當中。
三、操作AppWidget的Button
由於AppWidget的Button不與主程式在同一程式中,所以無法按照之前慣用的方法給Button繫結監聽器。
為AppWidget的Button繫結監聽器:
新方法:remoteViews.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
第一個引數為AppWidget的Button的id,第二引數為PendingIntent物件。
當Button被點選時,會引起pendingIntent的執行。
例:重新實現AppWidgetProvider:點選Button時啟動Activity
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.i("z","onReceive");
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// appWidgetMahager:管理app widget
// appWidgetIds : appWidget的id陣列(桌面可放置多個同樣的小部件)
for (int i= 0;i< appWidgetIds.length;i++){
//給每一個小部件的按鈕繫結監聽器
Log.i("z",appWidgetIds[i]+" ");
//建立一個Intent物件
Intent intent = new Intent(context,MainActivity.class);
//包裝成一個PendingIntent物件
PendingIntent pendingIntent = PendingIntent.getActivity(context,0,intent,0);
//得到RemoteViews物件
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//給app widget中的Button繫結監聽器
remoteViews.setOnClickPendingIntent(R.id.widget_button,pendingIntent);
//更新app widget
appWidgetManager.updateAppWidget(appWidgetIds[i],remoteViews);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
Log.i("z","onDeleted");
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.i("z","onEnabled");
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.i("z","onDisabled");
}
}
四、接收來自AppWidget的廣播和更新控制元件的狀態
在AndroidManifest當中為AppWidgetProvider註冊新的intent-filter,配置所要接收的廣播行為。AppWidgetProvider本質上是一個廣播接收器。
使用getBroadcast(…)方法建立一個傳送廣播PendingIntent。
為AppWidget當中的控制元件註冊處理器,用來觸發傳送廣播的行為。
在onReceive方法當中接收來自AppWidget傳送的廣播訊息,並執行自己的業務邏輯,使用RemoteViews物件更新App Widget當中的控制元件狀態。
AppWidgetProvider的執行機制:通過onReceive來接收廣播,接收到特定的系統內建廣播時來呼叫onUpdate(..)等生命週期的回撥方法,由onReceive來呼叫生命週期函式。
例:重新在AndroidMainfest註冊AppWidgerProvider:
<receiver android:name=".MyAppWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<intent-filter>
<action android:name="my.appwidget.Text_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info"/>
</receiver>
“android.appwidget.action.APPWIDGET_UPDATE”:系統自帶廣播,用來接收後回撥宣告周期函式。
“my.appwidget.Text_UPDATE”:自定義廣播,用來接收後進行對TextView的操作。
重新實現AppWidgetProvider:
public class MyAppWidgetProvider extends AppWidgetProvider {
private static final String TEXT_UPDATE = "my.appwidget.Text_UPDATE";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent!=null&& TextUtils.equals(TEXT_UPDATE,intent.getAction())){
Log.i("z","onReceiveTextUpdate");
//獲取app widget的所有控制元件
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//設定TextView的文字
remoteViews.setTextViewText(R.id.widget_text,"Changed Text");
//獲取app widget的管理器
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//獲取app widget的物件
ComponentName componentName = new ComponentName(context,MyAppWidgetProvider.class);
//管理器更新app widget
appWidgetManager.updateAppWidget(componentName,remoteViews);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// appWidgetMahager:管理app widget
// appWidgetIds : appWidget的id陣列(桌面小部件可重複放置多個小部件)
for (int i= 0;i< appWidgetIds.length;i++){
Log.i("z",appWidgetIds[i]+" ");
//建立一個傳送廣播的Intent物件,並設定action
Intent intent = new Intent();
intent.setAction(TEXT_UPDATE);
//包裝成一個PendingIntent物件,執行時會傳送一個廣播。
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,0);
//得到RemoteViews物件
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//給app widget中的Button繫結監聽器
remoteViews.setOnClickPendingIntent(R.id.widget_button,pendingIntent);
//更新app widget
appWidgetManager.updateAppWidget(appWidgetIds[i],remoteViews);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
Log.i("z","onDeleted");
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.i("z","onEnabled");
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.i("z","onDisabled");
}
}
相關文章
- 自學安卓app開發(一)安卓APP
- iOS開發之構建WidgetiOS
- 【Flutter】開發之基礎Widget(二)Flutter
- 【Flutter】開發之進階Widget(三)Flutter
- 【Flutter】開發之實戰Widget(四)Flutter
- 【Flutter】開發之進階Widget(五)Flutter
- iOS之widget開發(Today Extension)iOS
- 【安卓筆記】Widget安卓筆記
- 安卓APP開發優勢和概述安卓APP
- 安卓開發之服務Service安卓
- 多端開發之uniapp開發appAPP
- 安卓APP開發日記1——名為Another的日記APP開發安卓APP
- 【2021/12/31】uniapp之安卓原生外掛開發教程APP安卓
- 安卓app開發-01-開發工具及環境配置安卓APP
- App WidgetAPP
- 安卓開發之呼叫攝像頭安卓
- 安卓旅途之——開發數獨(一)安卓
- 安卓旅途之——開發數獨(二)安卓
- 用lazarus瞬間開發自己的安卓APP安卓APP
- 使用uniapp開發APP時的除錯/安卓打包等APP除錯安卓
- 安卓開發之Volley的基本使用安卓
- 安卓開發之資料儲存方式安卓
- 安卓旅途之——開發數獨(總結)安卓
- 安卓微信小程式開發之“藍芽”安卓微信小程式藍芽
- MIT App Inventor安卓圖形化開發入門MITAPP安卓
- iOS 使用Swift開發WidgetiOSSwift
- Flex Viewer 開發教程(5)Widget與Widget互動FlexView
- 安卓開發之網路請求HttpURLConnection安卓HTTP
- 安卓開發之Fragment的使用與通訊安卓Fragment
- 安卓開發之廣播接收器BroadcastReceiver安卓AST
- 安卓開發之Activity的4種啟動模式安卓模式
- iOS之widgetiOS
- 安卓中高階開發面試知識點之——快取安卓面試快取
- QT之安卓開發——生成APK以及真機測試QT安卓APK
- Python可以開發IOS或安卓APP嗎?Python入門!PythoniOS安卓APP
- 安卓開發框架系列開篇安卓框架
- Google Play ASO之安卓APP頁面優化Go安卓APP優化
- 安卓中高階開發工程師之——未來的路安卓工程師