您的位置:首页 > 移动开发

AppWidgetProvider使用介绍

2015-05-11 19:53 477 查看

一 介绍

AppWidgetProvider是android中提供的用于实现桌面小工具的类,其本质是一个广播,即BroadcastReceiver。下面是类的继承关系。



所以,在实际的使用中,把AppWidgetProvider当成一个BroadcastReceiver就可以了,这样许多功能就很好理解了。

二 开发一个桌面小工具的步骤


1 定义小工具界面:在res/layout/下新建一个xml文件,名为widget.xml,名称和内容可以自定义,看你的小工具要做成什么样子。

[html] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>  

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="fill_parent"  

    android:layout_height="fill_parent" >  

  

    <ImageView  

        android:id="@+id/imageView1"  

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content"  

        android:layout_alignParentLeft="true"  

        android:layout_alignParentTop="true"  

        android:src="@drawable/clear_cover" />  

  

</RelativeLayout>  


2 定义小工具配置信息:在res/xml/下新建appwidget_provider_info.xml,名称随意选,添加如下内容

[html] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>  

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  

    android:initialLayout="@layout/widget"  

    android:minHeight="84dp"  

    android:minWidth="84dp"  

    android:updatePeriodMillis="86400000" >  

  

</appwidget-provider>  

上面几个参数意义很明确,initialLayout就是指小工具所使用的初始化布局,minHeight和minWidth定义小工具的最小尺寸,updatePeriodMillis定义了小工具的自动更新周期,毫秒为单位,每隔一个周期,小工具的自动更新就会触发。


3 定义小工具类,继承AppWidgetProvider:

[java] view
plaincopy





public class MyAppWidgetProvider extends AppWidgetProvider {  

  

    public static final String TAG = "MyAppWidgetProvider";  

    public static final String CLICK_ACTION = "com.example.action.CLICK";  

    private static RemoteViews mRemoteViews;  

  

    /** 

     * 每删除一次窗口小部件就调用一次 

     */  

    @Override  

    public void onDeleted(Context context, int[] appWidgetIds) {  

        super.onDeleted(context, appWidgetIds);  

        Log.i(TAG, "onDeleted");  

    }  

  

    /** 

     * 当最后一个该窗口小部件删除时调用该方法,注意是最后一个 

     */  

    @Override  

    public void onDisabled(Context context) {  

        super.onDisabled(context);  

        Log.i(TAG, "onDisabled");  

    }  

  

    /** 

     * 当该窗口小部件第一次添加到桌面时调用该方法,可添加多次但只第一次调用 

     */  

    @Override  

    public void onEnabled(Context context) {  

        super.onEnabled(context);  

        Log.i(TAG, "onEnabled");  

    }  

  

    /** 

     * 接收窗口小部件点击时发送的广播 

     */  

    @Override  

    public void onReceive(final Context context, Intent intent) {  

        super.onReceive(context, intent);  

        Log.i(TAG, "onReceive : action = " + intent.getAction());  

  

        //这里判断是自己的action,做自己的事情,比如小工具被点击了要干啥,这里是做来一个动画效果  

        if (intent.getAction().equals(CLICK_ACTION)) {  

            Toast.makeText(context, "clicked it", Toast.LENGTH_SHORT).show();  

              

            new Thread(new Runnable() {  

                @Override  

                public void run() {  

                    Bitmap srcbBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.clear_fan);  

                    for (int i = 0; i < 20; i++) {  

                        float degree = (i * 90)%360;  

                        mRemoteViews.setImageViewBitmap(R.id.imageView1, rotateBitmap(context, srcbBitmap, degree));  

                        Intent intentClick = new Intent();  

                        intentClick.setAction(CLICK_ACTION);  

                        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);  

                        mRemoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent);  

                        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);  

                        appWidgetManager.updateAppWidget(  

                                new ComponentName(context, MyAppWidgetProvider.class), mRemoteViews);  

                        try {  

                            Thread.sleep(100);  

                        } catch (InterruptedException e) {  

                            e.printStackTrace();  

                        }  

                    }  

                      

                }  

            }).start();  

              

        }  

          

    }  

  

    /** 

     * 每次窗口小部件被点击更新都调用一次该方法 

     */  

    @Override  

    public void onUpdate(Context context, AppWidgetManager appWidgetManager,  

            int[] appWidgetIds) {  

        super.onUpdate(context, appWidgetManager, appWidgetIds);  

        Log.i(TAG, "onUpdate");  

  

        final int counter = appWidgetIds.length;  

        Log.i(TAG, "counter = " + counter);  

        for (int i = 0; i < counter; i++) {  

            int appWidgetId = appWidgetIds[i];  

            onWidgetUpdate(context, appWidgetManager, appWidgetId);  

        }  

  

    }  

  

    /** 

     * 窗口小部件更新 

     *  

     * @param context 

     * @param appWidgeManger 

     * @param appWidgetId 

     */  

    private void onWidgetUpdate(Context context,  

            AppWidgetManager appWidgeManger, int appWidgetId) {  

  

        Log.i(TAG, "appWidgetId = " + appWidgetId);  

        mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);  

  

        // "窗口小部件"点击事件发送的Intent广播  

        Intent intentClick = new Intent();  

        intentClick.setAction(CLICK_ACTION);  

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);  

        mRemoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent);  

        appWidgeManger.updateAppWidget(appWidgetId, mRemoteViews);  

    }  

  

    private Bitmap rotateBitmap(Context context, Bitmap srcbBitmap, float degree) {  

        Matrix matrix = new Matrix();  

        matrix.reset();  

        matrix.setRotate(degree);  

        Bitmap tmpBitmap = Bitmap.createBitmap(srcbBitmap, 0, 0, srcbBitmap.getWidth(),  

                srcbBitmap.getHeight(), matrix, true);  

        return tmpBitmap;  

    }  

  

}  


4 最后一步,在AndroidManifest.xml中声明小工具类:

[html] view
plaincopy





<receiver  

    android:name=".MyAppWidgetProvider"  

    android:icon="@drawable/df_fan_slow" >  

    <meta-data  

        android:name="android.appwidget.provider"  

        android:resource="@xml/appwidget_provider_info" >  

    </meta-data>  

  

    <intent-filter>  

        <action android:name="com.example.action.CLICK" />  

        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />  

    </intent-filter>  

</receiver>  

说明:根据我调研的结果,大家都说android.appwidget.action.APPWIDGET_UPDATE是必须要提供的,我试了下,如果不加,就无法出现在手机小工具列表中。其他action可以根据需要自行添加。

其中AppWidgetProvider中的几个回调方法:onEnabled,onDisabled,onDeleted,onUpdated会自动被其onReceive方法在合适的时间调用,确切来说是,当广播到来以后,AppWidgetProvider会自动根据广播的action通过onReceive方法来自动派发广播,也就是调用上述几个方法。android源码里说的很清楚:

[java] view
plaincopy





// BEGIN_INCLUDE(onReceive)  

public void onReceive(Context context, Intent intent) {  

    // Protect against rogue update broadcasts (not really a security issue,  

    // just filter bad broacasts out so subclasses are less likely to crash).  

    String action = intent.getAction();  

    if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {  

        Bundle extras = intent.getExtras();  

        if (extras != null) {  

            int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);  

            if (appWidgetIds != null && appWidgetIds.length > 0) {  

                this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);  

            }  

        }  

    }  

    else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {  

        Bundle extras = intent.getExtras();  

        if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {  

            final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);  

            this.onDeleted(context, new int[] { appWidgetId });  

        }  

    }  

    else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {  

        Bundle extras = intent.getExtras();  

        if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)  

                && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {  

            int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);  

            Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);  

            this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),  

                    appWidgetId, widgetExtras);  

        }  

    }  

    else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {  

        this.onEnabled(context);  

    }  

    else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {  

        this.onDisabled(context);  

    }  

}  

// END_INCLUDE(onReceive)  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息