Android开发桌面插件

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

开发桌面插件需要了解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"/>

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






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值