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));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章