最近项目不太忙,就抽空看了看天气预报,做个玩玩,上图:

转载请注明出处:

http://blog.csdn.net/dany1202/archive/2011/05/17/6426064.aspx

1.知识基础:小部件、数据库、SAX解析XML文件

2.实现说明:

google提供了天气预报的开放XML文件

http://www.google.com/ig/api?hl=zh-cn&weather=Beijing

查看如上网址,会看到界面显示一个XML文件,用SAX解析的方式获取XML文件节点内容,并将其存储到一个实体当中。

存储数据到数据库。

显示内容到小部件。

3.窗口小部件时间的实时刷新

Intent.ACTION_TIME_CHANGED 为系统时间每次发生改变的时候,发送的广播,其只能动态注册

所以在小部件的WeatherWidgetProvider.java中的onUpdate()方法中开启service,并在service中进行注册接收的广播

public class UpdateTimeService extends Service { BroadcastReceiver mIntentReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { if(Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction()) || Intent.ACTION_TIME_TICK.equals(intent.getAction()) || Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) WeatherWidgetProvider.UpdateTime(context); } }; @Override public void onDestroy() { unregisterReceiver(mIntentReceiver); super.onDestroy(); } @Override public void onCreate() { IntentFilter commandFilter = new IntentFilter(); commandFilter.addAction(Intent.ACTION_TIME_TICK); commandFilter.addAction(Intent.ACTION_TIME_CHANGED); commandFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED); getBaseContext().registerReceiver(mIntentReceiver, commandFilter); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public IBinder onBind(Intent arg0) { return null; } }

在WeatherWidgetProvider.java中提供静态方法public static void UpdateTime(Context context){。。。}刷新时间。

4.SAX解析,获取current_conditions节点内容

public class XMLHandler extends DefaultHandler { private static final String TAG = "XMLHandler"; private CurrentEntity currentWeather; private boolean currentFlag; public void setCurrentWeather(CurrentEntity currentWeather){ this.currentWeather = currentWeather; } public CurrentEntity getCurrentWeather(){ return currentWeather; } public XMLHandler() { currentFlag = false; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { String tagName = localName.length() != 0 ? localName : qName; tagName = tagName.toLowerCase(); Log.d(TAG,"tagName = "+tagName); if(tagName.equals("current_conditions")){ currentFlag = true; currentWeather = new CurrentEntity(); } if(currentFlag){ if(tagName.equals("condition")){ Log.d(TAG,"condition = "+attributes.getValue("data")); currentWeather.setCondition(attributes.getValue("data")); }else if(tagName.equals("temp_c")){ Log.d(TAG,"temp_c--------"); currentWeather.setTempc(attributes.getValue("data")); }else if(tagName.equals("humidity")){ currentWeather.setHumidity(attributes.getValue("data")); }else if(tagName.equals("icon")){ currentWeather.setIcon(attributes.getValue("data")); }else if(tagName.equals("wind_condition")){ currentWeather.setWindcondition(attributes.getValue("data")); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { String tagName = localName.length() != 0 ? localName : qName; tagName = tagName.toLowerCase(); if(tagName.equals("current_conditions")) { currentFlag = false; } } }

将节点对应的内容存放到CurrentEntity实体类中。

5.在天气的service中,开启线程,刷新小部件中的天气内容

public class UpdateForecastService extends Service implements Runnable { private static final String TAG = "UpdateForecastService"; private Uri currentUri = null; private String city = "Beijing"; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); currentUri = intent.getData(); Cursor cur = getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null); if(cur!=null && cur.getCount()>0){ cur.moveToFirst(); city = cur.getString(2); } Log.d(TAG,"-----------city = "+city); new Thread(this).start(); } public void run(){ Log.d(TAG,"----------------run --------------"); SAXParserFactory spf = SAXParserFactory.newInstance(); try { SAXParser sp = spf.newSAXParser(); XMLReader reader = sp.getXMLReader(); XMLHandler handler = new XMLHandler(); reader.setContentHandler(handler); URL url = new URL(Weathers.WEB_URI + URLEncoder.encode(city)); InputStream is = url.openStream(); InputStreamReader isr = new InputStreamReader(is,"GBK"); InputSource source = new InputSource(isr); reader.parse(source); CurrentEntity currentWeather = handler.getCurrentWeather(); Log.d(TAG,"------tempc = "+currentWeather.getTempc()+" condition = "+currentWeather.getCondition()); ContentValues values = new ContentValues(); values.put(Weathers.CONDITION, currentWeather.getCondition()); values.put(Weathers.TEMPC,currentWeather.getTempc()); values.put(Weathers.HUMIDITY,currentWeather.getHumidity()); values.put(Weathers.ICON,currentWeather.getIcon()); values.put(Weathers.WINDCONDITION,currentWeather.getWindcondition()); getContentResolver().update(currentUri, values, null, null); WeatherWidgetProvider.UpdateWeather(this,currentUri); } catch (Exception e) { e.printStackTrace(); Log.d(TAG,"not complete the parser"); } stopSelf(); } }

6小部件对应appwidgetprovider

public class WeatherWidgetProvider extends AppWidgetProvider{ private static final String TAG = "WeatherWidgetProvider"; private static int flagsDate = DateUtils.FORMAT_SHOW_DATE; private static int flagsWeek = DateUtils.FORMAT_SHOW_WEEKDAY; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { UpdateTime(context); Intent intent=new Intent(context ,UpdateTimeService.class); context.startService(intent); for(int i=0;i<appWidgetIds.length;i++){ Cursor cur = context.getContentResolver().query(Weathers.CONTENT_URI,null,Weathers.WIDGETID+"="+appWidgetIds[i],null,null); if(cur!=null&& cur.getCount()>0){ cur.moveToFirst(); String uri = Weathers.CONTENT_URI+"/"+String.valueOf(cur.getString(0)); Intent intentForcast = new Intent(context,UpdateForecastService.class); intentForcast.setData(Uri.parse(uri)); context.startService(intentForcast); } cur.close(); } super.onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onDeleted(Context context, int[] appWidgetIds) { if(0 == appWidgetIds.length){ Intent intent = new Intent(context ,UpdateTimeService.class); context.stopService(intent); } super.onDeleted(context, appWidgetIds); } private final static String M12 = "h:mm"; private final static String M24 = "kk:mm"; public static void UpdateTime(Context context){ RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget); String dateStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsDate); String smPmStr = DateUtils.getAMPMString(Calendar.getInstance().get(Calendar.AM_PM)); String formatTime; if(android.text.format.DateFormat.is24HourFormat(context)){ formatTime = M24; views.setViewVisibility(R.id.widget_am_pm,View.GONE); }else{ formatTime = M12; views.setViewVisibility(R.id.widget_am_pm,View.VISIBLE); views.setTextViewText(R.id.widget_am_pm, smPmStr); } String timeStr = (String) DateFormat.format(formatTime,System.currentTimeMillis()); String weekStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsWeek); views.setTextViewText(R.id.widget_date,dateStr+" "+weekStr); views.setTextViewText(R.id.widget_time,timeStr); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int[] appWidgetIds=appWidgetManager.getAppWidgetIds(new ComponentName(context, WeatherWidgetProvider.class)); appWidgetManager.updateAppWidget(appWidgetIds, views); } public static void UpdateWeather(Context context, Uri currentUri) { Cursor curCurrent = context.getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null); if(curCurrent!=null && curCurrent.getCount()>0){ curCurrent.moveToFirst(); Log.d(TAG,"curCurrent.getInt(1) = "+curCurrent.getInt(1)); Intent configIntent = new Intent(context, WeatherWidgetProvider.class); configIntent.setAction(currentUri.toString()); configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,curCurrent.getInt(1)); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,configIntent, 0); RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget); views.setTextViewText(R.id.city,curCurrent.getString(2)); views.setTextViewText(R.id.condition,curCurrent.getString(3)); views.setTextViewText(R.id.tempc, curCurrent.getString(4)+"°"); views.setTextViewText(R.id.humidity,curCurrent.getString(5)); views.setImageViewResource(R.id.icon, WeatherUtil .getForecastImage(curCurrent.getString(6))); views.setOnClickPendingIntent(R.id.icon, pendingIntent); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.updateAppWidget(curCurrent.getInt(1), views); } curCurrent.close(); } @Override public void onReceive(Context context, Intent intent) { Log.d(TAG,"intent.getAction() = "+intent.getAction()); if(intent.getAction().startsWith(Weathers.CONTENT_URI.toString())){ int mAppWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); Uri uri = Uri.parse(intent.getAction()); Log.d(TAG,"mAppWidgetId = "+mAppWidgetId+" uri = "+uri); Intent i = new Intent(context,UpdateForecastService.class); i.setData(uri); context.startService(i); } super.onReceive(context, intent); } }

在onUpdate中开启两个service,一个刷新时间,一个刷新天气。定义了一个Icon的点击事件,继续起到刷新天气的功能。

onReceive中接收点击事件,找到是哪一个小部件被点击了,根据小部件的Id进行区分。

当然此小部件是需要一个配置活动的,获取用户输入的城市名,不再多帖代码了,网上例子还是蛮多的

备注:搜狐天气api接口

http://sms.sohu.com/weatherfore/getformobile.php?city=北京

更多相关文章

  1. Android窗口小部件开发
  2. 如何刷新Android的ListView的UI界面
  3. Android视图加载流程(3)之ViewRootImpl的UI刷新机制
  4. 004. Android界面刷新没有调用OnMeasure
  5. Android(安卓)AppWidget的一些用法和注意事项
  6. Android(安卓)天气预报 完整案例详解
  7. Materal风格之recycleView下拉刷新以及上拉加载更多
  8. 5.3.2 开源Android-PullToRefresh下拉刷新源码分析
  9. 可以显示九天天气情况的天气预报哦-LINUX下JAVA自制服务器端,申请

随机推荐

  1. android调用matlab中的函数方法
  2. android launcher客制化——将自己的apk
  3. Android(安卓)Service启动方式总结
  4. Android Studio 安装后无法运行
  5. android学习任务
  6. Android网络状态相关
  7. Android实现View的任意拖动
  8. [zz]android框架示意图
  9. Mac通过Android aapt解析apk包名、版本号
  10. Volley的基本使用