博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AppWidgetProvider使用介绍
阅读量:6855 次
发布时间:2019-06-26

本文共 7194 字,大约阅读时间需要 23 分钟。

hot3.png

一 介绍

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

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

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

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

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

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

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

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中声明小工具类:

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

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

// 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)

转载于:https://my.oschina.net/u/2336511/blog/392362

你可能感兴趣的文章
阿里云希望和合作伙伴一起飞
查看>>
利用显卡运行的恶意软件“水母”又有了Windows版本
查看>>
工信部正制定大数据产业十三五发展规划
查看>>
信息化为五万教学点带来“优质教师”
查看>>
马达加斯加政府对光伏系统采取重大财政激励举措
查看>>
《数据虚拟化:商务智能系统的数据架构与管理》一 1.9 数据虚拟化服务器概述...
查看>>
《中国人工智能学会通讯》——8.13 强化学习
查看>>
9个实战及面试常用Shell脚本编写
查看>>
网能行业产品命名的中国风
查看>>
如何在Linux中找出所有在线主机的IP地址
查看>>
如何在web范围内实现微服务负载均衡
查看>>
信息安全的“无间道” 如何严防内鬼?
查看>>
云计算容器服务该何去何从
查看>>
Python操作MySQL基本环境搭建及增删改查实现
查看>>
Hacking Team事件导致一名韩国情报官员死亡
查看>>
高通肯花300亿美元收购恩智浦吗?
查看>>
英国Ofcom确定物联网频段 充分利用VHF甚高频部分频段
查看>>
《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #6 使用localmodconfig缩短编译时间...
查看>>
CNCC 2016 | 南京大学黄宜华教授 50 张 PPT 剖析 Alluxio 及其应用
查看>>
盘点:视频监控行业的潜在商机
查看>>