android开发之widget初步--2


上一节已经写了一个可以在桌面显示的widget,但是还有一些问题是没有解决的,主要包括以下:

1.widget最小更新的时间也是半个小时,那么如何让它实时的进行更行来完成与用户的交互?

2.widget上如果有点击事件或其他,如何响应其点击事件,与用户进行交互?


要解决这两个问题,就要回到MyWidget这个类,这个类继承了AppWidgetManager,一切从这里入手,便可以进行分析了。

在AppWidgetManager中,重写以下几个方法:

1)

只要对widget操作,就会回调这个方法


2) 

当appWidget更新时会回调,也就是说最少半个小时调用一次。

以上两个方法都用不太到,主要介绍后两种方法:


3)

AppWidget第一次被拉入到桌面时调用,appWidget可以被多次拖入到桌面,但是只有第一次被拖入到桌面时会回调,其他时候都是不会回调的。


4)

AppWidget最后一次从桌面删除时调用。


了解了以上的几个基本方法,我们解决第一个问题的思路就是:

1.在第一次将widget拖入到桌面时,开启一个服务,在服务中定时的更新widget控件。当最后一个widget从桌面删除后,关闭这个服务。

因此要在onEnable中开启注册一个服务,在onDisable中停止这个服务.而在这个服务中用来进行定时的更新widget操作,代码如下:

	@Override
public void onEnabled(Context context) {
startUpdateService(context);
//第一次把widget加入到桌面时
super.onEnabled(context);
//第一次拖过来时开启

Log.d(TAG, "onEnabled");
}

/**
 * 开启更新widget服务
 */
private void startUpdateService(Context context) {

 Intent intents = new Intent(context,UpdateWidgetService.class);

context.startService(intents);
Log.d(TAG, "intent.."+intents);
}

@Override
public void onDisabled(Context context) {
 Intent intents = new Intent(context,UpdateWidgetService.class);

context.stopService(intents);
//最后一次把widget删除桌面
super.onDisabled(context);
Log.d(TAG, "onDisabled intent.."+intents);

//	intent = null;
Log.d(TAG, "onDisabled");
}


2.那么我们就需要一个服务,在服务中进行相应的操作,因此要定义一个类UpdateWidgetService继承Service,并在清单文件注册。

那么如何在服务中进行定时更新呢?我们不用去考虑什么更新widget操作,只需要抽象的去考虑如何可以做到定期更新就好了,有许多种方式,在这里我们选用timer,timerTask.

在服务调用onCreate()方法时,调用timer.scheduleAtFixedRate(timerTask, 0, 3*1000),就开启了循环的timerTask的服务。

在服务回调onDestory时,进行timer.cancel(),task.cancel();

如下所示:

A.


B.

C.

D.

.

3.到上面已经解决了第一个问题,如何解决widget最短更新时间的问题,思路就是在widget第一次被拖入桌面时开启一个服务,在服务中利用Timer定时更新。那么接下来的问题是如何控制widget控件?

这里面的难点是widget是在桌面上显示的,不再我们的程序中,如何远程控制这个控件呢?

android的api给我们提供了一个类,叫做AppWidgetManager,通过调用它的方法就可以了。

AppWidgetManager awm = AppWidgetManager.getInstance(this);//这个方法是实例化这个对象

awm.updateAppWidget(componentName,RemotoViews);//利用这个方法可以更新widget,在timerTask中调用此即可。

这个方法有两个参数,第一个是ComponentName,代表的是继承了AppWidgetProvider的那个类,也就是MyWidget.java.

第二个参数是remoteViews,这个view是一个远程view,专门用来显示在其他process中的,在更新widget的操作中,它取代view,成为我们操作的对象。


4.生成的代码如下:

实例化ComponentName和RemoteViews.

ComponenetName(上下文,关联的appWidgetProvider.class);

RemoteViews("包名",“widget在桌面显示的布局文件”);

5.得到了RemoteViews,就可以得到布局文件中的各个控件,进行各种操作了。不过操作的方式与普通的view有些不一样,看下:

第一个参数是要操作的空间的id,第二个参数是内容,相当于findViewById(R.id.process_count).setText(list.toString);但由于是远程操控,只能用上述,其实上述也是通过内部反射来实现的。


6.那么到这里只剩最后一步了,如何点击Widet中的button后可以响应点击事件呢?代码如下:

定义一个PendingIntent,使它延迟发送一个广播,第二个参数随便写。那么既然是延迟发送,延迟到何时呢?应该是BUTTON被点击后,因此:

这样就响应了点击widget中的按钮后发送广播,在广播中处理点击事件。

那根据上述我们也得定义一个发送广播的Intent,放到PendingIntent的第三个参数去:

设置一个Action,以便广播接收者接收过滤,注意:不用写sendBroadCast(),因为在PendIngIntent中已经封装好了。


7.那么最后一步就是定义一个广播接收者,用来处理想要的点击事件了。代码就不写了。


第一次写,以前认为很简单的东西没想到操作起来很困难,写的一片浆糊,有些博客功能还不会,希望再接再厉吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值