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

转载请注明出处:

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=北京

android天气预报----google开源天气API,SAX解析相关推荐

  1. Google离线地图API概要解析

    Google离线地图API概要解析 发布时间:2018-01-17 版权: 1.说明 离线地图发布有多种方式均可以实现,可以利用ArcGis Server.GeoServer等构建地图Web服务器,还 ...

  2. Android调用新版百度天气api,解决地理编码问题

    我在学习制作天气预报app的时候,先调用新版百度地图api时发现,百度取消了原有api链接的city参数,反倒是改为了district_id,看到这个的时候我一脸蒙蔽,全国那么多地区,我要怎么一一获取 ...

  3. Android实现-心知天气API接口开发(天气预报app)

    自己开发app之心知天气APP程序代码粘贴即可用.完整代码附最后. 一.环境配置和素材准备 第一步:去知心天气注册开发者账号查看自己的token.注册好登录进去--控制台---免费版--秘钥.这里的秘 ...

  4. JSON之三:获取JSON文本并解释(以google的天气API为例)

    google提供了天气的api,以广州天气为例,地址为: http://api.openweathermap.org/data/2.5/weather?q=guangzhou 返回的结果为: { &q ...

  5. 抖音小程序|基于天气API实现天气预报功能

    文章目录 一.前言 包含了功能 UI展示 二.开发前的准备 三.开发步骤 1.app.js 配置 2.pages/index.js 演示二维码 源码在百度网盘下载 一.前言 参考老版iPhone自带的 ...

  6. google weather api 谷歌天气api

    用Google的天气api查询中国大陆地区的天气 1.使用经纬度坐标作为参数才能执行 Google Weather API, 例如: http://www.google.com/ig/api?hl=z ...

  7. CORE-ESP32C3|eink|墨水屏日历|天气API|LuatOS公共接口|气象要素数据V1|collectgarbage|LuatOS-SOC接口|官方demo|学习(13):墨水屏动态日历

    目录 参考博文 项目官方地址 显示效果: 硬件准备 软件版本 日志及soc下载工具 软件使用 接线示意图 硬件接线 一.Elink驱动管脚适配 二.天气信息获取 API使用方式: 接口格式(注意需不需 ...

  8. android天气预报项目总结报告,Android项目:天气预报App

    一 介绍 该项目是在Android Studio的环境下实现的,主要是仿照了小米10手机上的天气预报App. 二 效果图 三 页面介绍 1.主界面                            ...

  9. 使用易客运提供的天气API开发IOS应用天气APP

    目录 一.天气API官网 二.开发工具Xcode 三.教程开始(本片文章只介绍如何使用易客运API请求天气数据,演示项目仅一个获取天气功能) 3.1 注册登陆天气API后台(新用户会有2000个测试豆 ...

最新文章

  1. 全网最火的Nacos源码构建,你找不到第二个有我仔细的!!
  2. 利用任务调度特性检测Android模拟器
  3. AD16 SCH原理图打开正常,PCB图纸打开为空白或仍是上一个界面的解决方法
  4. TAAL在加拿大阿尔伯塔省工厂开启区块链基础设施运营
  5. Struts2的模型驱动封装方法获取页面提交的表单数据(接收表单数据的最常用的方法)
  6. 2021年最新超火外卖侠cps小程序,三级分销返利外卖领劵小程序源码,带电影票分销积分商城
  7. python实现通讯录代码
  8. win7使用命令提示符怎么运行C语言,Win7如何打开命令行窗口?Win7打开命令提示符的多种方法...
  9. 力天创见人脸识别分析客流量
  10. 【历史上的今天】10 月 24 日:1024 程序员节;中文维基百科上线;iPad mini 诞生十周年
  11. 【离散数学】命题逻辑
  12. python连接数据库mysql失败_python连接mysql失败怎么解决
  13. 目前最新android处理器排行榜,2017年最新安卓处理器排行榜 骁龙竟然输给了他
  14. 计算机二级考过律,计算机二级考试考完后的这些事情你知道吗?
  15. 【如何学习CAN总线测试】——OSEK网络管理测试
  16. 2022年5月编程语言排行看看学什么吃香?
  17. 如何做好项目管理,实现高效的项目管理?
  18. android 麻将布局,android麻将小项目1:第一天的一些收获
  19. 单波段彩色变换(伪彩色密度分割)
  20. php7 css样式不支持,div错位/解决IE6、IE7、IE8样式不兼容问题_html/css_WEB-ITnose

热门文章

  1. linux上用selenium登录新浪微博,获取用户关注的用户id
  2. Java千百问_05面向对象(004)_java接口到底是什么
  3. 关于WEB集群中文件服务器的讨论
  4. Linux Kobject
  5. cisco 密码重置
  6. 无法识别的属性“decompressionEnabled”处理方法
  7. tab和TabHost
  8. 实时计算Flink 快速入门 —— 步骤二:注册上下游存储
  9. 解决logstash启动过慢的问题
  10. 学习gSOAP从这个网址开始