Android開發桌面外掛
阿新 • • 發佈:2018-11-05
前提:公司應用需要開發外掛,奈何我實在沒有塊的開發經驗,查閱了一些資料,花了幾天時間,完成了外掛的開發。
開發桌面外掛需要了解AppWidgetProvider,RemoteViewsService,RemoteViewsFactory,appwidget-provider
外掛的更新主要是AppWidgetProvider,列表性的需要RemoteViewsService,RemoteViewsFactory,介面由appwidget-provider提供
首先是appwidget-provider,這個網上有很多的說明,我就不一一說了,我這裡主要用了
initialLayout:載入我們外掛的佈局
updatePeriodMillis:外掛的更新頻率
previewImage:外掛預覽圖片
configure:當 widget 建立時,會自動啟動該 Activity
然後是AppWidgetProvider
更新操作都在update中進行,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); } }
在onreceive中最後加入這個三行程式碼,外部發出的update操作都會經過onreceive。@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); }
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"/>
到這裡基本都已經完成了外掛的基本開發。具體的操作需要在開發中使用時根據自己的情況在進行處理。