Android开发Widget之提高篇

        在上一篇博客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 {
	@Override
	public 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() {

		@Override
		public void onReceive(Context context, Intent intent) {
			 //时区改变则重新获取Calendar
			if (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);
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		
		return null;
	}
	
	@Override
	public 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);		
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
        //注销广播
		if (null != mTimeTickReceiver) {
			getApplicationContext().unregisterReceiver(mTimeTickReceiver);
		}
	}
}
      最后新建TimeWidget继承自AppWidgetProvider.
public class TimeWidget extends AppWidgetProvider {
	 
	//时间
	private static String  mTime;
	 
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);		 
		//如果时间不为空,那么更新时间
		if (mTime!=null) {
			TimeWidget.updateAppWidget(context, mTime);
		}
	}

	@Override
	public void onEnabled(final Context context) {
		super.onEnabled(context);	  	
		//启动后台服务检测时间变化
		context.startService(new Intent(context, TimeUpdateService.class));
	}

	@Override
	public void onDisabled(Context context) {
		//当最后一个widget被移除时停止服务 		
		context.stopService(new Intent(context, TimeUpdateService.class));
	}
    
	//更新widget
	static 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值