如何实现一个桌面小部件(一)
来源:互联网 发布:加强网络舆情监管 编辑:程序博客网 时间:2024/06/16 06:25
实现一个桌面小部件,分为三个步骤:
1、继承一个AppWidgetProvider或者一个BoardcastReceiver,用来实现自己的小部件更新接收广播。
建议使用AppWidgetProvider,这样也可以在AppWidgetProvider中添加新的action,用来使小部件根据其他的广播更新信息。
在AppWidgetProvider代码中:
public void onReceive(Context context, Intent intent) { 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); } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) { Bundle extras = intent.getExtras(); if (extras != null) { int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS); int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (oldIds != null && oldIds.length > 0) { this.onRestored(context, oldIds, newIds); this.onUpdate(context, AppWidgetManager.getInstance(context), newIds); } } } }
在代码中,广播接收器根据不同的action执行不同的方法,在AppWidgetProvider中,这些方法都是空方法,所以,我们既可以自己继承BoardcastReceiver
来实现我们的AppWidgetProvider也可以通过继承AppWidgetProvider来实现在父类中的空方法,这些都是可以的!!!
在广播我们需要在manifest进行注册:
这里假设我们的使用< ExampleAppWidgetProvider extends AppWidgetProvider >
public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; <receiver android:name="ExampleAppWidgetProvider" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" /> </receiver>
根据注册的信息,我们的广播只会接收到小部件更新的广播,不明白为什么不一起加上呢!!
这里的meta-data用来描述一个AppWidgetProviderInfo,其实现实在xml中完成的:
res/xml/example_appwidget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="86400000" android:previewImage="@drawable/preview" android:initialLayout="@layout/example_appwidget" android:configure="com.example.android.ExampleAppWidgetConfigure" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen"> </appwidget-provider>
updatePeriodMillis表示的是小部件自动更新的时间间隔,单位是毫秒,这里设置的是24小时,这个值应该是有最小限制的,如果设置为0,你就只能自己发送广播让小部件更新了,
网上说framework自动更新小部件的最小间隔为半个小时,在文档中没有看到!!!不过在任何情况下,我们都可以手动更新我们的小部件(通过定时发送Intent,或者直接监听时间变化的广播)
previewImage属性表示小部件在未添加的时候的预览图,如果不设置的话,默认会使用应用的图标!!!这也是很多自定义的小部件在预览的时候看到都是小机器的缘故!!
initialLayout属性代表的是小部件的真实布局,是一个layout文件!!
widgetCategory属性表示小部件是否允许被现实在主界面或者锁屏界面,在5.0之前的版本,小部件可以显示在锁屏界面,但是在5.0之后,小部件不允许被显示在锁屏在界面!!
configure属性表示在小部件被创建的时候进行的配置Activity,
在AppWidgetHostActivity中,可以看到源代码:
void configureAppWidget(int requestCode, int appWidgetId, ComponentName configure) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.setComponent(configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); SharedPreferences.Editor prefs = getPreferences(0).edit(); prefs.putInt(PENDING_APPWIDGET_ID, appWidgetId); prefs.commit(); startActivityForResult(intent, requestCode); }
从这里就可以看到,我们自己的ConfigureActivity的action已经被确定了,即为:AppWidgetManager.ACTION_APPWIDGET_CONFIGURE
protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case DISCOVER_APPWIDGET_REQUEST: handleAppWidgetPickResult(resultCode, data); break; case CONFIGURE_APPWIDGET_REQUEST: handleAppWidgetConfigureResult(resultCode, data); } } void handleAppWidgetConfigureResult(int resultCode, Intent data) { int appWidgetId = getPreferences(0).getInt(PENDING_APPWIDGET_ID, -1); Log.d(TAG, "resultCode=" + resultCode + " appWidgetId=" + appWidgetId); if (appWidgetId < 0) { Log.w(TAG, "was no preference for PENDING_APPWIDGET_ID"); return; } if (resultCode == RESULT_OK) { AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId); addAppWidgetView(appWidgetId, appWidget); } else { mHost.deleteAppWidgetId(appWidgetId); } }
//如果配置没有完成,在自定义的配置activity中设置结果码不为ok,就不会成功添加小部件了!!
void addAppWidgetView(int appWidgetId, AppWidgetProviderInfo appWidget) { // Inflate the AppWidget's RemoteViews AppWidgetHostView view = mHost.createView(this, appWidgetId, appWidget); // Add it to the list LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); mAppWidgetContainer.addView(view, layoutParams); registerForContextMenu(view); }
小部件布局:
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/widget_margin"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@drawable/my_widget_background"> … </LinearLayout> </FrameLayout>
配置Activity:
<activity android:name=".ExampleAppWidgetConfigure"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/> </intent-filter> </activity>
小部件的点击事件通过使用RemoteView+PendingIntent实现,小部件的更新实现在onUpdate方法中实现
有一点需要特别注意,由于AppWidgetProvider是继承了BoardcastReceiver,所以它的进程生命周期与广播接收器的进程生命周期是一致的。即,只有在广播发生时才会进入AppWidgetProvider中的各个方法。所以在从网络上更新信息时,需要注意,应该从新启动一个service来帮助完场信息的更新。
在下一篇博客中,我将用一个实例,来说明如何实现一个桌面小部件!!!
这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!
- 如何实现一个桌面小部件(一)
- 如何实现Android桌面小部件(二)
- android widget(桌面小部件)实现
- appWidget(桌面小部件)
- 关于RemoteView的一点愚见(实现桌面小部件)
- Android 开发一个天气预报桌面小部件
- android 中的AppWidget(桌面小部件)
- Android桌面小部件AppWidget(1)
- Android桌面小部件AppWidget(2)
- 桌面小部件
- 桌面小部件Widget
- appwidget桌面小部件
- appwidget桌面小部件
- Widget桌面小部件
- android 桌面小部件
- 桌面小部件创建?
- 自定义桌面小部件
- android 桌面小部件(App Widgets)如何显示自定义的view
- JavaScript如何动态生成表格
- 39. Combination Sum 40. Combination Sum II 216. Combination Sum III
- Python学习笔记56(爬虫:煎蛋网上的妹子图)
- mybatis框架,细节处理
- 浅谈React.createElement()方法
- 如何实现一个桌面小部件(一)
- 40个Java多线程问题总结
- hive-redis运行Log日志
- pandas.read_csv to_csv参数详解
- bzoj2243 SDOI2011 染色 树链剖分
- slice
- 0423 行级与块级标签的外边距
- 使用HorizontalScrollView实现侧滑ListView
- NKOJ-4052 糖果盒