1. 程式人生 > >AppWidget(桌面小控制元件詳解)

AppWidget(桌面小控制元件詳解)

介紹

Android widget
也稱為桌面外掛,其是android系統應用開發層面的一部分,但是又有特殊用途,而且會成為整個android系統的亮點。Android中的AppWidget與google
widget和中移動的widget並不是一個概念,這裡的AppWidget只是把一個程序的控制元件嵌入到別外一個程序的窗口裡的一種方法。(複製貼上都懂^_^)

廢話不多說上來就是幹,直接上一個widget

1、新建一個繼承AppWidgetProvider類

public class NewAppWidget extends AppWidgetProvider
{
private static String TAG = "NewAppWidget"; public static final String CLICK_ACTION = "com.example.action.CLICK";//自己定義的action private static RemoteViews views; static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { Intent intentClick = new
Intent(context, NewAppWidget.class); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); CharSequence widgetText = context.getString(R.string.appwidget_text);//文字:狀態很棒哦! // Construct the RemoteViews object
views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); // "視窗小部件"整個點選事件註冊,只要點選了就會發送相應的廣播 views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, pendingIntent); views.setTextViewText(R.id.appwidget_text, widgetText);//設定文字 Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.xiao);//笑的圖片 views.setImageViewBitmap(R.id.appwidget_image, bitmap);//設定圖片 ComponentName name = new ComponentName(context, NewAppWidget.class); appWidgetManager.updateAppWidget(name, views);//更新widget } //接受到相應的廣播 @Override public void onReceive(final Context context, Intent intent) { super.onReceive(context, intent); Log.e(TAG, "onReceive : action = " + intent.getAction()); //這裡判斷是自己的action,做自己的事情 if (intent.getAction().equals(CLICK_ACTION)) { Intent intent1 = new Intent(context, ControlActivity.class); intent1.setFlags(FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent1); } } // 重新整理的時候執行 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } // 第一個新增到螢幕上執行 @Override public void onEnabled(Context context) { //我這是開啟一個服務 context.startService(new Intent(context, ConnectService.class)); } // 最後一個widget從螢幕移除執行 @Override public void onDisabled(Context context) { } // 從螢幕移除執行 @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); } }

2、新建一個new_app_widget檔案

相信看完上面的程式碼你就發現還需要一個佈局檔案,然後我們就做一個佈局檔案唄
程式碼我就不想貼了直接上圖,自己寫佈局去
這裡寫圖片描述
就是一個這樣的樣式了一個背景一個imageview一個textview

3在Manifest檔案中宣告

<receiver android:name=".NewAppWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.example.action.CLICK" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/new_app_widget_info" />
        </receiver>

然後你就會發現這就是一個receiver,沒錯這就是一個receiver,AppWidgetProvider 就是繼承的BroadcastReceiver
這裡寫圖片描述

新增Widget配置資訊

看到清單檔案是不是還少了一個叫new_app_widget_info的xml檔案,沒錯,這個是widget的配置檔案。

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/new_app_widget"
    android:initialLayout="@layout/new_app_widget"
    android:minHeight="40dp"
    android:minWidth="250dp"
    android:previewImage="@drawable/example_appwidget_preview"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="86400000"
    android:widgetCategory="home_screen"></appwidget-provider>

好了到了這裡你就會發現可以建立一個widget了。但是怎麼更新widget呢?

更新widget

呼叫一下程式碼

//使用RemoteViews 
 RemoteViews views = new RemoteViews(getPackageName(), R.layout.new_app_widget);
//獲取AppWidgetManager
 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cry);//哭的圖片
//相當於找id設定圖片
views.setImageViewBitmap(R.id.appwidget_image, bitmap);
views.setTextViewText(R.id.appwidget_text, "狀態不好哦!");
//更新widget
appWidgetManager.updateAppWidget(new ComponentName(context, NewAppWidget.class), views);

然後你就會發現換了一張圖片,換了幾個字

開發中的一些坑

1、appWidgetManager更新的兩個方法

updateAppWidget(int[] appWidgetIds, RemoteViews views)
updateAppWidget(ComponentName provider, RemoteViews views)
我們使用的是第二個方法如圖
這裡寫圖片描述
但是我當時使用的是第一個方法如圖
這裡寫圖片描述

當你使用第二張圖的方法時,你會發現一個問題在應用退出後,或是被第三方軟體殺死,點選桌面widget就不會更新了。原因是updateid是用一個數組儲存的,應用退出後,這個陣列就被清空了,後面又換成了updateAppWidget(ComponentName)方法後就好了。

2、new_app_widget_info裡的android:configure屬性

一開始的時候照著官方文件在new_app_widget_info.xml檔案裡設定了這個屬性,在新增到桌面上的時候總是不成功,將這個屬性去掉就可以了,不知道這個屬性具體怎麼用,有知道的麻煩留個言,謝謝

3、在用setOnClickPendingIntent()方法設定點選事件傳送Broadcast時,不能直接new Intent(acton)

Intent intentClick = new Intent(CLICK_ACTION);
views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, PendingIntent.getBroadcast(context, 0, intent, 0));

上面這種寫法在應用退出後在有些手機上收不到廣播,然後換成下面這種寫法

Intent intentClick = new Intent(context, NewAppWidget.class);
intentClick.setAction(CLICK_ACTION);
views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, PendingIntent.getBroadcast(context, 0, intent, 0));