桌面小组件实现过程

Widget桌面小组件实现

      1)要更新Widget中的内容,一般都是写在onUpdate方法里面,但是更新的时候,要把Widget当做一个RemoteViews来处理。利用Service更新Widget中的内容。
      2)Widget中:在onEnable方法中启动Service,在onDisable方法中停止Service,在onUpdate方法中为按钮绑定一个监听器,但是此时不能利用传统的方式进行绑定。
                       (传统方式:Button btn = view.findViewById(id);             btn.setOnClickListener(listener);)
       3)在Widget中绑定监听器必须利用RemoteViews提供的相关API才可以:   view.setOnClickPendingIntent(id,pendingIntent);
             当id对应的按钮点击的时候,会触发PendingIntent,随着PendingIntent的触发,就会发送广播。 该广播被Service中的广播接收器接收,执行对应的代码逻辑。

Step1  res/layout下面,写Widget的布局文件(一个Button,点击获取一个随机数字,显示到TextView上)



    
	
	

Step2    res/xml,要写一个xml文件,该文件用来向系统描述widget的一些特性,res下新建xml文件夹,新建xml文件

            1)minWidth/minHeight:用来指定widget的最小尺寸, 尺寸的经验公式:70*n-30(例:n取值为4*1中的4)。

            2)android:updatePeriodMillis="86400000"   ,毫秒值,告诉系统间隔多长时间调用一下Widget中更新Widget界面显示的方法,这个值不能低于30分钟(1800000毫秒),然后低于该长度的时间值均无效,系统会按照默认的30分钟来进行更新,一般写一天的毫秒值。
            3)android:initialLayout="@layout/widget_layout"   告诉系统,当widget拖动到桌面上显示的时候,使用的布局文件。



                                   

Step3   写MyService类


/**
 * 用来与widget进行交互的Service 提供Widget中显示的数字
 */

public class MyService extends Service {
	MyReceiver receiver;
	@Override
	public void onCreate() {
		super.onCreate();
		//动态注册广播接收器
		receiver = new MyReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction("ACTION_MAKE_NUMBER");
		registerReceiver(receiver, filter);
	}
	@Override
	public void onDestroy() {
		//注销广播接收器
		unregisterReceiver(receiver);
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	/**
	 * 广播接收器
	 */
	private class MyReceiver extends BroadcastReceiver {
		// 接收到Widget发送的广播
		@Override
		public void onReceive(Context context, Intent intent) {
			if ("ACTION_MAKE_NUMBER".equals(intent.getAction())) {
				// 生成一个随机数字,以系统广播的形式将这个数字提交到
				AppWidgetManager manager = AppWidgetManager.getInstance(context);
				ComponentName provider = new ComponentName(context,MyWidget.class);
				RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
				//设置要显示的TextView,及显示的内容
				views.setTextViewText(R.id.tv_widget_number, new Random().nextInt(2000)+"");
				// 发送一个系统广播
				manager.updateAppWidget(provider, views);
			}
		}

	}

}



Step4   要真正去写Widget类。写的时候需要继承自AppWidgetProvider!

1)去重写AppWidgetProvider中的若干方法,选择性重写AppWidgetProvider的:onEnable,onDisable,onUpdate,onDelete,onReceive方法

2)同一个Widget可以被多次拖动放到桌面上,每一个桌面上的widget,就相当于该Widget类的一个对象。当且仅当第一个Widget被拖动到

面上的时候,会调用onEnable方法和onUpdate方法,随后再次拖动第二个第三个...Widget到桌面上,仅仅会调用,widget的onUpdate

了,再删除桌面上的Widget的时候,当且仅当删除最后一个Widget对象的时候,会调用该widget的onDelete方法和onDisable方法,删除

数第二个第三个...Widget的时候,仅仅会调用Widget的,onDelete方法。随着onEnable,onUpdate,onDelete,onDisable方法的调用

都会产生系统广播,从而让Widget的onReceive方法被调用

           

                                                  

public class MyWidget extends AppWidgetProvider{

	@Override
	public void onReceive(Context context, Intent intent) {
		super.onReceive(context, intent);
		Log.d("TAG","onReceive方法调用了");
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		Log.d("TAG","onUpdate方法调用了");
		//给Button绑定一个PendingIntent,当点击按钮是发送给Service发广播
		//当点击Button时,触发PendingIntent,发广播给MyService
		AppWidgetManager manager = AppWidgetManager.getInstance(context);
		ComponentName provider = new ComponentName(context,MyWidget.class);
		RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
		
		Intent numberIntent = new Intent("ACTION_MAKE_NUMBER");
		views.setOnClickPendingIntent(R.id.btn_widget_button, PendingIntent.getBroadcast(context, 0, numberIntent , PendingIntent.FLAG_UPDATE_CURRENT));
		
		
		manager.updateAppWidget(provider, views);
	}

	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		super.onDeleted(context, appWidgetIds);
		Log.d("TAG","onDeleted方法调用了");
	}

	@Override
	public void onEnabled(Context context) {
		super.onEnabled(context);
		Log.d("TAG","onEnabled方法调用了");
		//启动MyService
		Intent intent = new Intent(context,MyService.class);
		context.startService(intent);
	}

	@Override
	public void onDisabled(Context context) {
		super.onDisabled(context);
		Log.d("TAG","onDisabled方法调用了");
		//停止MyService
		Intent intent = new Intent(context,MyService.class);
		context.stopService(intent);
	}
	
}

Step5  注册

           在AndroidManifest中注册该Widget,在application标签下,activity标签外 

           其中节点中写Widget接收的广播Action类型,widget是一个特殊的"广播接收器",还必须要添加一个节点   

       
            
                
                
            

            
        

            在AndroidManifest中注册MyService,在application标签下,activity标签外

        
        

至此,功能实现!!!


你可能感兴趣的:(Android,android,widget)