Android开发Widget之提高篇

来源:互联网 发布:unity3d 多人游戏实现 编辑:程序博客网 时间:2024/06/05 20:40

        在上一篇博客Android开发Widget之入门篇我们已经介绍了创建一个widget的流程。但是像这样的widget没什么实际用途,widget主要是为了显示一些信息,这样很方便,不用我们专门去启动应用查看信息,那么现在教大家做一个显示时间的widget。

      效果如下:

      

      这个与之前的widget不同的就是,它是启动了一个后台服务,服务注册了广播监听时间变化,当发生变化时就接受到广播然后更新时间。像之前的流程一样还是分三步。

 一.建一个widget的布局。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingTop="@dimen/widget_marginTop"     android:paddingBottom="@dimen/widget_marginBottom" >    <TextView        android:id="@+id/appwidget_time"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:gravity="center"        android:contentDescription="@string/appwidget_text"        android:textColor="@color/appwidget_view_time"        android:textSize="@dimen/appwidget_view_time"/>     </RelativeLayout>
二.在xml目录下新建一个 widget的配置文件。     
<?xml version="1.0" encoding="utf-8"?><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"        android:initialLayout="@layout/time_widget"    android:minHeight="72dp"    android:minWidth="142dp"    android:previewImage="@drawable/example_appwidget_preview"    android:resizeMode="horizontal"    android:updatePeriodMillis="86400000" ></appwidget-provider>
三.编写代码

     新建一个TimeApplication继承自Application,调用TimeUpdateService的onReceive方法,在widget一启动就接受时间更新时间,然后启动TimeUpdateService.

public class TimeApplication extends Application {@Overridepublic void onCreate() {TimeUpdateService.mTimeTickReceiver.onReceive(getApplicationContext(),null);getApplicationContext().startService(new Intent(getApplicationContext(), TimeUpdateService.class));    }}
    TimeUpdateService里注册广播,接受广播就更新时间.  
public class TimeUpdateService extends Service {//获取Calendar对象private static Calendar mCalendar = Calendar.getInstance(TimeZone.getDefault());//时间广播接收者public static BroadcastReceiver mTimeTickReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) { //时区改变则重新获取Calendarif (intent != null) {            if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {                String tz = intent.getStringExtra("time-zone");                mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));            }}            //设置当前时间                       mCalendar.setTimeInMillis(System.currentTimeMillis());//设置时间格式boolean is24 = DateFormat.is24HourFormat(context);SimpleDateFormat format = new SimpleDateFormat(is24 ? "H:mm" : "h:mm", Locale.getDefault());String time = format.format(mCalendar.getTime());    //更新时间TimeWidget.updateAppWidget(context, time);}};@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();        //注册这个广播,当系统时间改变时就会发送广播IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_TIME_TICK);filter.addAction(Intent.ACTION_TIME_CHANGED);filter.addAction(Intent.ACTION_DATE_CHANGED);filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);  getApplicationContext().registerReceiver(mTimeTickReceiver, filter);}@Overridepublic void onDestroy() {super.onDestroy();        //注销广播if (null != mTimeTickReceiver) {getApplicationContext().unregisterReceiver(mTimeTickReceiver);}}}
     最后新建TimeWidget继承自AppWidgetProvider.
public class TimeWidget extends AppWidgetProvider { //时间private static String  mTime; @Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds); //如果时间不为空,那么更新时间if (mTime!=null) {TimeWidget.updateAppWidget(context, mTime);}}@Overridepublic void onEnabled(final Context context) {super.onEnabled(context);  //启动后台服务检测时间变化context.startService(new Intent(context, TimeUpdateService.class));}@Overridepublic void onDisabled(Context context) {//当最后一个widget被移除时停止服务 context.stopService(new Intent(context, TimeUpdateService.class));}    //更新widgetstatic void updateAppWidget(Context context, String time) {//给mTime赋值mTime = time; //如果time不为null则更新if (null != time) {//widget管理者AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);//远程view视图RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.time_widget);   //设置视图中的显示views.setTextViewText(R.id.appwidget_time, time); //指定要启动的组件ComponentName mComponentName = new ComponentName(context, TimeWidget.class); //更新appWidgetManager.updateAppWidget(mComponentName, views);}}}
       

      这样就完成了时间widget,很简单的。如果你要做一个界面很复杂的widget你就要注意了,widget只支持部分View,像Button,AnalogClock,TextView,ImageView等,那么那些复杂,酷炫的widget是怎么实现的呢,这就要在framework层下去修改了,位置在frameworks/base/core/java/android/widget里面,资源文件存放在frameworks/base/core/res/res 里,感兴趣的朋友可以自己研究下。

    最后附上Demo地址:点击打开链接



0 0
原创粉丝点击