android launcher桌面数字时钟及appwidget更新问题

代码下载http://download.csdn.net/detail/ldinvicible/5010177

一、桌面数字时钟控件效果图

 

二、

1、准备好一个Widget的显示布局文件 layout/widget.xml 内容如下


  
  
      
    
      
  
      
  
          
 
        
	           
		           
		
		             
		     
  
      
  
  

2、准备好一个Widget的配置文件xml/provider_info.xml,该文件配置了widget可以占用的屏幕长宽、更新频率,所显示的布局文件(就是上面的那个布局文件)等.


  
  


3、准备好一个处理widget请求的Java文件,继承了AppWidgetProvider类


package com.example.digitalclock;

import java.util.Calendar;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.RemoteViews;

public class ClockAppWidgetProvider extends AppWidgetProvider {
	private Context context;  
	private AppWidgetManager appWidgetManager;  
	private Timer timer;  
	  
	
	//月份  
	private String[] months = new String[]{"1 /", "2 /", "3 /", "4 /", "5 /", "6 /", "7 /", "8 /", "9 /", "10 /", "11 /", "12 /"};  
	//星期  
	private String[] weeks = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};  
	  

	

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		super.onReceive(context, intent);
		
	}

	@Override  
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
	        int[] appWidgetIds) {  
		
	    //创建定时器  
	    timer = new Timer();  
	      
	    this.context = context;  
	    this.appWidgetManager = appWidgetManager;  
	      
	    //进行周期性调度: 1s更新一次界面  
	    timer.schedule(new TimerTask() {  
	          
	        @Override  
	        public void run() {  
	            //通知更新界面  
	            handler.sendEmptyMessage(0x123);  
	        }  
	    }, 0, 10);  
	}  
	  
	private Handler handler = new Handler()  
	{  
	  
	    @Override  
	    public void handleMessage(Message msg) {  
	        super.handleMessage(msg);  
	          
	        if(msg.what == 0x123)  
	        {  
	            //构造RemoteViews对象  
	            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_clock);  
	              
	            //构造显示时间日期  
	            Calendar calendar = Calendar.getInstance(Locale.CHINA);  
	            calendar.setTimeInMillis(System.currentTimeMillis());  
	              
	            //构造当期显示时间  
	            StringBuffer currentTime = new StringBuffer("");  
	            int temp = calendar.get(Calendar.HOUR_OF_DAY);  
	            if(temp < 10)  
	            {  
	                currentTime.append("0").append(temp);  
	            }  
	            else  
	            {  
	                currentTime.append(temp);  
	            }  
	            temp = calendar.get(Calendar.MINUTE);  
	            if(temp < 10)  
	            {  
	                currentTime.append(" : ").append("0").append(temp);  
	            }  
	            else  
	            {  
	                currentTime.append(" : ").append(temp);  
	            }  
	            /*temp = calendar.get(Calendar.SECOND);  
	            if(temp < 10)  
	            {  
	                currentTime.append(":").append("0").append(temp);  
	            }  
	            else  
	            {  
	                currentTime.append(":").append(temp);  
	            }  */
	              
	              
	            //设置显示当前时间  
	            views.setTextViewText(R.id.txt_time, currentTime.toString());  
	            
	          //设置显示当前时间  AM PM
	            String ampmValues; 
	            if(DateFormat.is24HourFormat(context)){
	            	ampmValues = "";
	            }
	            else{
	                if(calendar.get(Calendar.AM_PM) == 0){  
	                    ampmValues = "AM";  
	                }else{  
	                    ampmValues = "PM";  
	                }   
	            }  
	            views.setTextViewText(R.id.txt_APM, ampmValues); 
	            
	            //设置显示当前月份  
	            views.setTextViewText(R.id.txt_month, months[calendar.get(Calendar.MONTH)]);  
	            //设置显示当前星期  
	            views.setTextViewText(R.id.txt_week, weeks[calendar.get(Calendar.WEEK_OF_MONTH)]);  
	            //设置显示当前日期  
	            views.setTextViewText(R.id.txt_day, String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));  
	              
	            //将当前的ClockAppWidgetProvider包装成ComponentName对象  
	            ComponentName componentName = new ComponentName(context, ClockAppWidgetProvider.class);  
	              
	            //更新App Widget  
	            appWidgetManager.updateAppWidget(componentName, views);  
	        }  
	    }  
	      
	};  
}

4、androidMainfest文件




    

    
        
            
                
                
                
            
        
  
          
              
              
                  
              
              
              
          
    



以上桌面数字时钟控件就已经完成

参考http://blog.csdn.net/huliang7777/article/details/8448417


关于以上数字时钟有几个bug

1、到一定时间后,时间不在走,即停止更新

2、按setting中的设置时间选项,先使用12小时制,在反复按am、pm按钮,在返回到home界面,时间停止更新。

猜测:1、可能是handle message有性能问题()---也不是很清楚。

2、后来我使用了timer定时器直接更新界面appwidget,可是还是有问题,时间不走。

3、在后来使用了timer定时器在加上注册广播机制,可是很奇怪,依然不行。

4、最后使用了启动一个服务,在注册广播更新appwidget,代码见如下:

AndroidManifest.xml




    
    

    

          
    	  
        	  
    	  
		  
        
  
          
              
              
                  
                
                
                
                
              
              
              
          
        
    


ClockAppWidgetProvider.java 有很多已经注释掉了,请注意!

package com.example.digitalclock;

import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.RemoteViews;

public class ClockAppWidgetProvider extends AppWidgetProvider {
	private Context context;
	private AppWidgetManager WidgetManager;
	private Timer timer;
	static String TAG = "ClockAppWidgetProvider";
	private RemoteViews views;
	int[] appWidgetIds;

	private static Timer myTimer;
	// 定义我们要发送的事件
	private final String broadCastString = "com.wd.appWidgetUpdate";

	// 月份
	// 星期
	private String[] months = new String[] { "01/", "02/", "03/", "04/", "05/",
			"06/", "07/", "08/", "09/", "10/", "11/", "12/" };
	private String[] weeks = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
			"Fri", "Sat" };
	// private String[] weeksid = new String[]{"Minggu", "Senin", "Selasa",
	// "Rabu", "Kamis", "Jumat", "Sabtu"};
	private String[] weeksid = new String[] { "Min", "Sen", "Sel", "Rab",
			"Kam", "Jum", "Sab" };
	private String[] days = new String[] { "0", "01", "02", "03", "04", "05",
			"06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16",
			"17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
			"28", "29", "29", "30", "31" };

	public void updateAppWidget(Context context) {
		// 构造RemoteViews对象
		views = new RemoteViews(context.getPackageName(),
				R.layout.appwidget_provider_clock);

		// 构造显示时间日期
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTimeInMillis(System.currentTimeMillis());

		// 构造当期显示时间
		StringBuffer currentTime = new StringBuffer("");
		int temp = calendar.get(Calendar.HOUR_OF_DAY);

		// 设置显示当前时间
		if (DateFormat.is24HourFormat(context)) {
			if (temp < 10) {
				currentTime.append("0").append(temp);
			} else {
				currentTime.append(temp);
			}
		} else// 12小时制
		{
			Log.i(TAG, "00000000  temp ==" + temp);
			if (calendar.get(Calendar.AM_PM) == 0 && temp == 0) {
				currentTime.append(temp + 12);
				Log.i(TAG, "1111111111111111");
			} else {

				Log.i(TAG, "2222222222222222222");
				if (temp < 13) {
					if (temp < 10) {
						currentTime.append("0").append(temp);
					} else {
						currentTime.append(temp);
					}
				} else {
					temp -= 12;
					if (temp < 10) {
						currentTime.append("0").append(temp);
					} else {
						currentTime.append(temp);
					}
				}
			}

		}

		temp = calendar.get(Calendar.MINUTE);
		if (temp < 10) {
			currentTime.append(":").append("0").append(temp);
		} else {
			currentTime.append(":").append(temp);
		}
		Log.i(TAG, "currentTime.toString()" + currentTime.toString());
		views.setTextViewText(R.id.txt_time, currentTime.toString());

		// 设置显示当前时间 AM PM
		String ampmValues;
		if (DateFormat.is24HourFormat(context)) {
			ampmValues = "";
		} else {
			if (calendar.get(Calendar.AM_PM) == 0) {
				ampmValues = "AM";
			} else {
				ampmValues = "PM";
			}
		}
		views.setTextViewText(R.id.txt_APM, ampmValues);

		// 设置显示当前月份
		views.setTextViewText(R.id.txt_month,
				months[calendar.get(Calendar.MONTH)]);
		// 设置显示当前星期

		// Locale locale = getResources().getConfiguration().locale;
		String language = Locale.getDefault().getLanguage();
		if (language.endsWith("in")) {
			views.setTextViewText(R.id.txt_week,
					weeksid[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
		} else {
			views.setTextViewText(R.id.txt_week,
					weeks[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
		}

		// views.setTextViewText(R.id.txt_week,
		// String.valueOf(calendar.get(Calendar.DAY_OF_WEEK)));

		// 设置显示当前日期
		if (calendar.get(Calendar.DAY_OF_MONTH) < 10) {
			views.setTextViewText(R.id.txt_day,
					days[calendar.get(Calendar.DAY_OF_MONTH)]);
		} else {
			views.setTextViewText(R.id.txt_day,
					String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
		}

		/*
		 * final int N = appWidgetIds.length; for(int i = 0; i < N; i++){ int
		 * appWidgetId = appWidgetIds[i];
		 * WidgetManager.updateAppWidget(appWidgetIds, views); }
		 * 
		 * final AppWidgetManager gm = AppWidgetManager.getInstance(context); if
		 * (appWidgetIds != null) { Log.i(TAG, "appWidgetIds != null");
		 * gm.updateAppWidget(appWidgetIds, views); } else { Log.i(TAG,
		 * "appWidgetIds == null"); gm.updateAppWidget(new
		 * ComponentName(context, this.getClass()), views); }
		 */
		// 将当前的ClockAppWidgetProvider包装成ComponentName对象
		// ComponentName componentName = new ComponentName(context,
		// ClockAppWidgetProvider.class);

		// 更新App Widget
		// AppWidgetManager.updateAppWidget(componentName, views);

		// 将该界面显示到插件中
		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(context);
		ComponentName componentName = new ComponentName(context,
				ClockAppWidgetProvider.class);
		appWidgetManager.updateAppWidget(componentName, views);

	}

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		// 当判断到是该事件发过来时, 我们就获取插件的界面, 然后将index自加后传入到textview中
		// System.out.println("onReceive");
		Log.i(TAG, "onReceive");
		Log.i(TAG, "intent.getAction()" + intent.getAction());
		if (intent.getAction().equals(broadCastString)
				|| intent.getAction().equals(
						"android.intent.action.TIME_CHANGED")
				|| intent.getAction().equals("android.intent.action.TIME_TICK")
				|| intent.getAction().equals("android.intent.action.TIME_SET")) {
			{
			//	updateAppWidget(context);
			}
		}

		super.onReceive(context, intent);
	}

	@Override
	public void onEnabled(Context context) {
		// TODO Auto-generated method stub
		//super.onEnabled(context);
		// 在插件被创建的时候这里会被调用, 所以我们在这里开启一个timer 每秒执行一次
		//MyTask mMyTask = new MyTask(context);
		//myTimer = new Timer();
		//myTimer.schedule(mMyTask, 1000, 1000);
		//System.out.println("onEnabled2");
		context.startService(new Intent(context, TimeService.class));
	}

	class MyTask extends TimerTask {

		private Context mcontext = null;
		private Intent intent = null;

		public MyTask(Context context) {

			// 新建一个要发送的Intent
			mcontext = context;
			intent = new Intent();
			intent.setAction(broadCastString);
			intent.setAction("android.intent.action.TIME_CHANGED");
			intent.setAction("android.intent.action.TIME_TICK");
			intent.setAction("android.intent.action.TIME_SET");
		}

		@Override
		public void run() {
			System.out.println("2");
			// 发送广播(由onReceive来接收)
			mcontext.sendBroadcast(intent);

		}

	}

	@Override
	public void onDisabled(Context context) {
		// TODO Auto-generated method stub
		context.startService(new Intent(context, TimeService.class));
	}

	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		// TODO Auto-generated method stub

		super.onDeleted(context, appWidgetIds);
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		
		context.startService(new Intent(context, TimeService.class));
		
		// 创建定时器
		timer = new Timer();

		this.context = context;
		WidgetManager = appWidgetManager;
		this.appWidgetIds = appWidgetIds;

		// 在插件被创建的时候这里会被调用, 所以我们在这里开启一个timer 每秒执行一次
		// MyTask mMyTask = new MyTask(context);
		// myTimer = new Timer();
		// myTimer.schedule(mMyTask, 1000, 1000);

		// 进行周期性调度: 1s更新一次界面
		/*TimerTask task = new TimerTask(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				updateAppWidget(ClockAppWidgetProvider.this.context);
			}
			
		};
		timer.schedule(task, 1000, 1000);
		*/
	/*	
		timer.schedule(new TimerTask() {

			public void run() { // 通知更新界面
				//handler.sendEmptyMessage(0x123);
				updateAppWidget(ClockAppWidgetProvider.this.context);
			}
		}, 0, 1000);*/
/*
		handler.post(new Runnable() {

			@Override
			public void run() { // TODO Auto-generated method stub
				handler.sendEmptyMessage(0x123);
				handler.postDelayed(this, 1000);
			}
		});
*/
	}

	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			if (msg.what == 0x123) { // 构造RemoteViews对象 views = new
				updateAppWidget(context);
			}
		}
	};

}


TimeService.java

package com.example.digitalclock;

import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.RemoteViews;

public class TimeService extends Service {
	static String TAG = "ClockAppWidgetProvider";
	private RemoteViews views;
	
	// 月份
	// 星期
	private String[] months = new String[] { "01/", "02/", "03/", "04/", "05/",
			"06/", "07/", "08/", "09/", "10/", "11/", "12/" };
	private String[] weeks = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
			"Fri", "Sat" };
	// private String[] weeksid = new String[]{"Minggu", "Senin", "Selasa",
	// "Rabu", "Kamis", "Jumat", "Sabtu"};
	private String[] weeksid = new String[] { "Min", "Sen", "Sel", "Rab",
			"Kam", "Jum", "Sab" };
	private String[] days = new String[] { "0", "01", "02", "03", "04", "05",
			"06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16",
			"17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
			"28", "29", "29", "30", "31" };
	
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onCreate");
		startClockListener();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		unregisterReceiver(this.timeReceiver);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
	}

	  private BroadcastReceiver timeReceiver = new BroadcastReceiver()
	  {
	    public void onReceive(Context context, Intent intent)
	    {
	    	Log.i(TAG, "onReceive 11111 intent.getAction()"+intent.getAction());
	      if ("android.intent.action.TIMEZONE_CHANGED".equals(intent.getAction())
	    		  ||"android.intent.action.TIME_TICK".equals(intent.getAction())
	    			||"android.intent.action.TIME_CHANGED".equals(intent.getAction())
	    			||"android.intent.action.TIME_SET".equals(intent.getAction()))
	    			{
	    			  updateAppWidget();  
	    		  }
	    	  
	    }
	  };
	
	  public void startClockListener()
	  {
		  Log.i(TAG, "startClockListener");
	    IntentFilter localIntentFilter = new IntentFilter();
	    localIntentFilter.addAction("android.intent.action.TIME_TICK");
	    localIntentFilter.addAction("android.intent.action.TIME_CHANGED");
	    localIntentFilter.addAction("android.intent.action.TIMEZONE_CHANGED");
	    localIntentFilter.addAction("android.intent.action.TIME_SET");
	    registerReceiver(this.timeReceiver, localIntentFilter);
	  }

	public void updateAppWidget() {
		Log.i(TAG, "updateAppWidget");
		// 构造RemoteViews对象
		views = new RemoteViews(getApplicationContext().getPackageName(),
				R.layout.appwidget_provider_clock);

		// 构造显示时间日期
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTimeInMillis(System.currentTimeMillis());

		// 构造当期显示时间
		StringBuffer currentTime = new StringBuffer("");
		int temp = calendar.get(Calendar.HOUR_OF_DAY);

		// 设置显示当前时间
		if (DateFormat.is24HourFormat(getApplicationContext())) {
			if (temp < 10) {
				currentTime.append("0").append(temp);
			} else {
				currentTime.append(temp);
			}
		} else// 12小时制
		{
			Log.i(TAG, "00000000  temp ==" + temp);
			if (calendar.get(Calendar.AM_PM) == 0 && temp == 0) {
				currentTime.append(temp + 12);
				Log.i(TAG, "1111111111111111");
			} else {

				Log.i(TAG, "2222222222222222222");
				if (temp < 13) {
					if (temp < 10) {
						currentTime.append("0").append(temp);
					} else {
						currentTime.append(temp);
					}
				} else {
					temp -= 12;
					if (temp < 10) {
						currentTime.append("0").append(temp);
					} else {
						currentTime.append(temp);
					}
				}
			}

		}

		temp = calendar.get(Calendar.MINUTE);
		if (temp < 10) {
			currentTime.append(":").append("0").append(temp);
		} else {
			currentTime.append(":").append(temp);
		}
		Log.i(TAG, "currentTime.toString()" + currentTime.toString());
		views.setTextViewText(R.id.txt_time, currentTime.toString());

		// 设置显示当前时间 AM PM
		String ampmValues;
		if (DateFormat.is24HourFormat(getApplicationContext())) {
			ampmValues = "";
		} else {
			if (calendar.get(Calendar.AM_PM) == 0) {
				ampmValues = "AM";
			} else {
				ampmValues = "PM";
			}
		}
		views.setTextViewText(R.id.txt_APM, ampmValues);

		// 设置显示当前月份
		views.setTextViewText(R.id.txt_month,
				months[calendar.get(Calendar.MONTH)]);
		// 设置显示当前星期

		// Locale locale = getResources().getConfiguration().locale;
		String language = Locale.getDefault().getLanguage();
		if (language.endsWith("in")) {
			views.setTextViewText(R.id.txt_week,
					weeksid[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
		} else {
			views.setTextViewText(R.id.txt_week,
					weeks[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
		}

		// views.setTextViewText(R.id.txt_week,
		// String.valueOf(calendar.get(Calendar.DAY_OF_WEEK)));

		// 设置显示当前日期
		if (calendar.get(Calendar.DAY_OF_MONTH) < 10) {
			views.setTextViewText(R.id.txt_day,
					days[calendar.get(Calendar.DAY_OF_MONTH)]);
		} else {
			views.setTextViewText(R.id.txt_day,
					String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
		}

		/*
		 * final int N = appWidgetIds.length; for(int i = 0; i < N; i++){ int
		 * appWidgetId = appWidgetIds[i];
		 * WidgetManager.updateAppWidget(appWidgetIds, views); }
		 * 
		 * final AppWidgetManager gm = AppWidgetManager.getInstance(context); if
		 * (appWidgetIds != null) { Log.i(TAG, "appWidgetIds != null");
		 * gm.updateAppWidget(appWidgetIds, views); } else { Log.i(TAG,
		 * "appWidgetIds == null"); gm.updateAppWidget(new
		 * ComponentName(context, this.getClass()), views); }
		 */
		// 将当前的ClockAppWidgetProvider包装成ComponentName对象
		// ComponentName componentName = new ComponentName(context,
		// ClockAppWidgetProvider.class);

		// 更新App Widget
		// AppWidgetManager.updateAppWidget(componentName, views);

		// 将该界面显示到插件中
		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(getApplicationContext());
		ComponentName componentName = new ComponentName(getApplicationContext(),
				ClockAppWidgetProvider.class);
		appWidgetManager.updateAppWidget(componentName, views);

	}
	
}


其他地方更以前一样




你可能感兴趣的:(android)