实时更新widget
来源:互联网 发布:淘宝卖家强制取消订单 编辑:程序博客网 时间:2024/06/15 20:04
widget注意事项:
widget是个特殊的receiver
它重写了onReceiver方法
当发送广播到widget中时 不会响应
只有当接收到
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
widget的生命周期:
1.onEnabled方法:此方法在Widget第一次被创建的时候调用,并且只调用一次,此方法中常放入初始化数据,服务的操作。
2.onReceive方法:通BroadcastReceiver的OnReceive方法,但是这里有所不同的是,当接收到Widget操作时首先调用的是OnReceive方法,然后才是相关的操作方法。这也很好理解,Widget的是运行在桌面运用程序中的小控件,当自己的应用程序需要调用Widget是,就需要发送广播事件去调用。
3.onUpdate:Widget在固定的时间里更新时调用的方法。
4.onDeleted:Widget被删除时调用的方法。
5.onDisabled:所用Widget被删除是调用的方法,同onEnabled方法相对。
这里做下说明 测试机是android4.0.3
onEnabled onDisabled 发现从来没有调用过 不知道是什么问题
而.onUpdate在onReceive之前被调用了
AppWidgetManager.ACTION_APPWIDGET_UPDATE不会调用onUpdate方法
可以看源码
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { Bundle <span style="color:#ff0000;">extras = intent.getExtras();</span> if (extras != null) { int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (<span style="color:#ff0000;">appWidgetIds != null && appWidgetIds.length > 0</span>) { this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds); } } }明白了吧 我们发的intent没有extra
结合这次做的音乐播放器 分析一下
需求是 在activity中改变播放状态 同时让widget更新状态(文字 图片等) 需要从activity中获取信息
本来的想法是在activity中发送广播到widget 通过intent的传递信息
可发现widget比较特殊 只有接收到那4大广播才会响应onReceiver
尝试这一个intent设置了两个action(脑袋错乱了 intent只能有一个action 后者会覆盖前者)
所以这条路失败
然后去看了下系统自带音乐播放器源码 它是通过得到一个Widget对象 来实现更新内容的
这里说明一下我的更新方式
我是用了remoteView来实现自定义widget视图的
它的更新方式如下:
AppWidgetManager instance = AppWidgetManager.getInstance(this.context);rv = new RemoteViews(context.getPackageName(), R.layout.widget);String title = mp3Info.getTitle();String artist =mp3Info.getArtist();rv.setTextViewText(R.id.tv_name, title);rv.setTextViewText(R.id.tv_musician, artist);if(!pause){rv.setImageViewResource(R.id.iv_stop, R.drawable.btn_playback_pause);}else {rv.setImageViewResource(R.id.iv_stop, R.drawable.btn_playback_play);}instance.updateAppWidget(this.appWidgetIds[0], rv);
因为无法通过广播来实时更新 所以想着通过一个widget对象来更新
context,appWIdgetIds则由自己来传入
一开始 传入了是MainActivity.this 和appWidgetManager.getAppWidgetIds(name)结果不行
然后 开始找问题 先从context下手
这里先说一下 widgetManager管理widget 每当接受到一个广播都会创建一个新的widget对象
但是每个对象中传入的context都是同一个
于是尝试这把这个context保存起来 再调用更新方法 结果还是不行
那么肯定是appWIdgetIds也有问题了
打印了一下appWidgetManager.getAppWidgetIds(name) 和一开始 onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 传入的appWidgetIds
结果发现 不是一个对象 好吧问题解决了
把系统创建widget对象传入的context和appWidgetIds保存起来 再调用更新方法就好了
贴一下源码
public class Widget extends AppWidgetProvider {private RemoteViews rv;private AppWidgetManager appWidgetManager;private int[] appWidgetIds;private static Widget instance;public Context context;static synchronized Widget getInstance() {if (instance == null) {instance = new Widget();}return instance;}@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);this.context = context;}public void update(Mp3Info mp3Info,boolean pause, Context con){AppWidgetManager instance = AppWidgetManager.getInstance(this.context);rv = new RemoteViews(context.getPackageName(), R.layout.widget);String title = mp3Info.getTitle();String artist =mp3Info.getArtist();rv.setTextViewText(R.id.tv_name, title);rv.setTextViewText(R.id.tv_musician, artist);if(!pause){rv.setImageViewResource(R.id.iv_stop, R.drawable.btn_playback_pause);}else {rv.setImageViewResource(R.id.iv_stop, R.drawable.btn_playback_play);}instance.updateAppWidget(this.appWidgetIds[0], rv);}@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds);if (instance == null) {instance = new Widget();}if (rv == null) {this.appWidgetManager = appWidgetManager;<span style="color:#ff0000;">instance.appWidgetIds = appWidgetIds;instance.context=context;</span>init(context, appWidgetManager, appWidgetIds);}}/** * 初始化 * * @param context * @param appWidgetManager * @param appWidgetIds */protected void init(final Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {new Thread(new Runnable() {@Overridepublic void run() {ActivityManager am = (ActivityManager) context.getSystemService("activity");List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();for (RunningAppProcessInfo i : runningAppProcesses) {if (context.getPackageName().equals(i.processName))return;}Intent intent = new Intent(context, MainActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}}).start();rv = new RemoteViews(context.getPackageName(), R.layout.widget);CharSequence title = "";CharSequence artist = "";rv.setTextViewText(R.id.tv_name, title);rv.setTextViewText(R.id.tv_musician, artist);Intent playIntent = new Intent("com.dlj.musicplayer.MainActivity.ComplateBoardcast.play");Intent nextIntent = new Intent("com.dlj.musicplayer.MainActivity.ComplateBoardcast.playNext");Intent openIntent = new Intent(context, MainActivity.class);PendingIntent stopPIntent = PendingIntent.getBroadcast(context, 0, playIntent, 0);PendingIntent nextPIntent = PendingIntent.getBroadcast(context, 0, nextIntent, 0);PendingIntent openPIntent = PendingIntent.getBroadcast(context, 0, openIntent, 0);rv.setOnClickPendingIntent(R.id.iv_stop, stopPIntent);rv.setOnClickPendingIntent(R.id.iv_next, nextPIntent);rv.setOnClickPendingIntent(R.id.rl_notify, openPIntent);appWidgetManager.updateAppWidget(appWidgetIds[0], rv);}}精华是这两个
把这两个保存起来 再用他们来更新数据就行了
<span style="color:#ff0000;">instance.appWidgetIds = appWidgetIds;instance.context=context;</span>
尼玛 研究了半天才弄出来的 结果看了老师的源码 发现个更简洁的
appWidgetManager.updateAppWidget(
new ComponentName(getApplicationContext(), TimeWidgetProvider.class), remoteView);
吐血身亡
又碰到一个怪问题
当响应widget的remoteView的点击事件时 或者onUpdate或onDelete时
如果当前系统中没有widget对应的进程 则会创建一个进程
而这个进程中存放的activity 就是入口activity(MainActivity)
重点!!!!!!但此时的activity 比较特殊 它没有调用oncreate方法 没有界面 就是一个空壳而已
- 实时更新widget
- Android 开发之实时更新 App Widget
- Android 开发之实时更新 App Widget
- Android 开发之实时更新 App Widget
- 实时数据类Widget更新问题
- 更新widget中的背景
- Android widget更新 监听
- android widget不更新
- android widget简单开发三之实时刷新widget
- Android实现widget定时更新
- Android实现widget定时更新
- 【Android】widget不能及时更新
- android service 更新widget UI
- lucene的实时更新
- 时间实时更新
- E文(实时更新)
- 实时更新异地数据库
- 实时更新 (网络数据)
- Filter
- 第二周 项目三 时间类(1)
- python 字典(dict)按键和值排序
- 多益网络2015校园招聘第二次笔试题
- 欧拉函数以部分性质
- 实时更新widget
- redmine 导出中文乱码
- 编译原理之DFA自动机的
- 使用Xcode自带的单元测试
- Beautiful Soup(三)--搜索文档树
- hdu5050(Java大数 + 二进制 + 最大公约数)
- ubuntu12.04安装图文(非虚拟机)
- HEVC编码流程解读
- HashMap 源码分析