Android开发桌面插件

来源:互联网 发布:java实现图文混排 编辑:程序博客网 时间:2024/04/30 16:26

前提:公司应用需要开发插件,奈何我实在没有块的开发经验,查阅了一些资料,花了几天时间,完成了插件的开发。

开发桌面插件需要了解AppWidgetProvider,RemoteViewsService,RemoteViewsFactory,appwidget-provider

插件的更新主要是AppWidgetProvider,列表性的需要RemoteViewsService,RemoteViewsFactory,界面由appwidget-provider提供

首先是appwidget-provider,这个网上有很多的说明,我就不一一说了,我这里主要用了

initialLayout:加载我们插件的布局

updatePeriodMillis:插件的更新频率

previewImage:插件预览图片

configure:当 widget 创建时,会自动启动该 Activity

然后是AppWidgetProvider

public class MyAppWidgetProvider extends AppWidgetProvider {    /**     * 当第1个 widget 的实例被创建时触发。     */    @Override    public void onEnabled(Context context) {        super.onEnabled(context);    }    /**     * 接收到任意广播时触发,并且会在上述的方法之前被调用。     */    @Override    public void onReceive(Context context, Intent intent) {        super.onReceive(context, intent);        /**         *  如果你的Widget要求并不是很特殊,一般情况下,在此接收广播,即可处理相应事务,但在此就放弃该方法了。         */    }    /**     * 当 widget 更新时被执行。每次创建Widget,或者刚开机等情况下,都会被执行。     */    @Override    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {        /**         *  由于Widget本身不支持执行太过耗时的操作,所以,为了实现开机刷新和每次添加的时候刷新数据,开启服务,         *  让数据在后台下载,等下载完成之后,在进行更新Widget的操作。         *         */        Intent intent = new Intent(context, MyService.class);        intent.putExtra("appWidgetIds", appWidgetIds);        context.startService(intent);    }    /**     * 当 widget 被删除时被触发。     */    @Override    public void onDeleted(Context context, int[] appWidgetIds) {        super.onDeleted(context, appWidgetIds);    }    /**     * 当最后1个 widget 的实例被删除时触发。     */    @Override    public void onDisabled(Context context) {        super.onDisabled(context);    }}
更新操作都在update中进行,

 @Override    public void onReceive(Context context, Intent intent) {        super.onReceive(context, intent);            //将界面应用到插件中            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);            int[] ids = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetA.class));            onUpdate(context, appWidgetManager, ids);            }
在onreceive中最后加入这个三行代码,外部发出的update操作都会经过onreceive。

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);Bundle extras = new Bundle();intent.putExtras(extras);sendBroadcast(intent);
其他文件中使用该代码就会更新插件。

如果你有在插件中使用listview,gridview这类控件,就需要RemoteViewsService,RemoteViewsFactory进行数据更新,和adapter一样

public class WidgetGridService extends RemoteViewsService {    @Override    public RemoteViewsFactory onGetViewFactory(Intent intent) {        return new GridRemoteViewFactory(this, intent);    }    private class GridRemoteViewFactory implements RemoteViewsFactory {        private Context context;        private int appWidgetId;        private List<WidgetEntity.NewslistBean> newslist = new ArrayList<>();        public GridRemoteViewFactory(Context context, Intent intent) {            this.context = context;            this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,                    AppWidgetManager.INVALID_APPWIDGET_ID);        }        /**         * 首次执行,初始化数据时执行onCreate();数据是从数据库里拿的。         */        @Override        public void onCreate() {            try {                newslist = MyApplication.getMyApp().getDbUtils().findAll(WidgetEntity.NewslistBean.class);            } catch (DbException e) {                e.printStackTrace();            }        }        /**         * 当数据源发生变化时,AppWidgetManager调用了 notifyAppWidgetViewDataChanged();方法时执行         */        @Override        public void onDataSetChanged() {            try {                newslist = MyApplication.getMyApp().getDbUtils().findAll(WidgetEntity.NewslistBean.class);            } catch (DbException e) {                e.printStackTrace();            }        }        /**         * 销毁数据源         */        @Override        public void onDestroy() {            newslist.clear();        }        /**         * 返回Gridview的Item条目数         */        @Override        public int getCount() {            return newslist.size();        }        /**         * 给Gridview设置数据         */        @Override        public RemoteViews getViewAt(int position) {            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.item_grid);            if (newslist != null) {//item的xml文件                remoteViews.setTextViewText(R.id.item_text, newslistBean.getTitle());                //给item设置响应事件                Intent intent = new Intent();                intent.putExtra("url", newslistBean.getUrl());                remoteViews.setOnClickFillInIntent(R.id.item_widget, intent);            }            return remoteViews;        }        @Override        public RemoteViews getLoadingView() {            return null;        }        /**         * 无特殊要求,返回的View类型数 ==1;         */        @Override        public int getViewTypeCount() {            return 1;        }        /**         * 返回item的id         */        @Override        public long getItemId(int position) {            return position;        }        @Override        public boolean hasStableIds() {            return true;        }    }}

然后在mainfest注册改插件

<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/widget_main" /></receiver>

<service            android:name=".WidgetGridService"            android:exported="false"            android:permission="android.permission.BIND_REMOTEVIEWS"/>

到这里基本都已经完成了插件的基本开发。具体的操作需要在开发中使用时根据自己的情况在进行处理。






0 0
原创粉丝点击