- 浏览: 426895 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
yehuiyan8002:
支持中文查询
快熟查找联系人 -
lehehe:
现成的接口,免费试用,http://www.haoservic ...
天气Widget -
D.Z:
android:focusable="false&q ...
CheckBox在ListView 而导致其OnItemClickListener不会被触发 -
freecode:
碰到该问题,CheckBox的android:focusabl ...
CheckBox在ListView 而导致其OnItemClickListener不会被触发 -
echohfut:
哥们,新博客是不是在墙外啊?不能访问。还有你怎么进行博客迁移的 ...
博客 迁移
天气Widget : 负责显示 当天 未来几天 天气信息
还是一步步从头说吧:
[代码 步骤]
1. 定义widget所需界面: weatherlayout.xml 包括以下几个View
* ImageView 用于显示:天气图片 * TextView 用于描述天气信息 比如:温度 湿度 紫外线指数 紫外线强度 * ImageView 相当于Button 负责查询明天天气情况
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text" android:textSize="12px" android:textStyle="bold|italic" android:textColor="#008800" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
2. 定义 weathersetting.xml 用于定义widget相关各属性
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" //widget最小宽度 android:minWidth="246dip" //widget最小高度 android:minHeight="22dip" //刷新率 因为该widget要求从网络获取信息 导致运行时间较长 而该单位偏大 故使其为0 至于数据刷新 通过别的方法 具体见下文 android:updatePeriodMillis="0" //widget使用的布局 android:initialLayout="@layout/weatherlayout" />
3. 定义一些后续用到的字串
public class WeatherColumn { //HK 地区天气查询 相关地址 public final static String WeatherHttpHead = "http://202.140.96.134:8080/FS-RSS/"; public final static String WeatherLocal = WeatherHttpHead + "ftpfile/local_weather.xml"; public final static String WeatherForcast = WeatherHttpHead + "ftpfile/forecast_weather.xml"; //broadcast definition public final static String BroadcastWidget = "BroadcastWidget"; public final static String BroadcastMoniterNext = "BroadcastMoniterNext"; //天气信息数据 比如:哪里 时间 温度 湿度 紫外线指数 紫外线强度 或 所有信息一起 public final static String WeatherLocation = "WeatherLocation"; public final static String WeatherTime = "WeatherTime"; public final static String WeatherTemporary = "WeatherTemporary"; public final static String WeatherHumidity = "WeatherHumidity"; public final static String WeatherUvIndext = "WeatherUvIndext"; public final static String WeatherUvIntensity = "WeatherUvIntensity"; public final static String WeatherIco = "WeatherIco"; //用于标记查询哪天天气 public final static String DayInfo_Widget = "DayInfo_Widget"; public final static String DayInfo_Activity = "DayInfo_Activity"; public final static String DayNow = "DayNow"; public final static String DayNext = "DayNext"; }
4. 定义2 Service 作用:
* WidgetUpdate 用于执行AppWidgetProvider 天气信息显示 及其他事情 * WeatherMoniter 用于执行与天气查询有关事情
5. WidgetUpdate 定义如下:
//负责具体数据查询 显示 public static class WidgetUpdate extends Service { Context context; RemoteViews rView; public void onStart(Intent intent, int startId) { rView = new RemoteViews(getPackageName(), R.layout.weatherlayout); WidgetInfoListenerHelper helper = new WidgetInfoListenerHelper(this); helper.registerAction(WeatherColumn.BroadcastWidget); setViewBroadcastClickListener(rView,R.id.next,WeatherColumn.BroadcastMoniterNext); rView.setTextViewText(R.id.text, "Hi,WeatherWidget!"); rView.setImageViewResource(R.id.next,R.drawable.next); //setViewActivityClickListener(rView, R.id.image, // new Intent(this, WeatherActivity.class)); notifyViewChanged(); } public void notifyViewChanged(){ // Push update for this widget to the home screen ComponentName batteryWidget = new ComponentName(this, WeatherWidget.class); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(batteryWidget, rView); } //refer- startActivity(Intent) public void setViewActivityClickListener(RemoteViews remte,int id,Intent i){ PendingIntent pi = PendingIntent.getActivity(this,1,i,0); remte.setOnClickPendingIntent(id, pi); } //refer- sendBroadcast(Intent) public void setViewBroadcastClickListener(RemoteViews remte,int id,String filter){ Intent i = new Intent(filter); PendingIntent pi = PendingIntent.getBroadcast(this,1,i,0); remte.setOnClickPendingIntent(id, pi); } //显示 天气数据 public void displayText(String s){ rView.setTextViewText(R.id.text, s); notifyViewChanged(); } //显示 天气图片 public void displayImage(Bitmap bp){ rView.setImageViewBitmap(R.id.image,bp); notifyViewChanged(); } //下载 目标地址 网络图片 public Bitmap queryImageByURI(String iu){ try{ URL imgURL = new URL(iu); URLConnection conn = imgURL.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); Bitmap bm = BitmapFactory.decodeStream(bis); bis.close(); is.close(); return bm; }catch(Exception e){ return null; } }
6. 在WidgetUpdate 里面定义BroadcastReceiver 用于接收天气数据 并显示之
//负责接收天气数据 public class WidgetInfoListenerHelper extends BroadcastReceiver { Context context; WidgetInfoListenerHelper listener; //construct public WidgetInfoListenerHelper(Context c){ context = c; //to instance it listener = this; } public void registerAction(String action){ IntentFilter filter = new IntentFilter(); filter.addAction(action); context.registerReceiver(listener,filter); } @Override public void onReceive(Context arg0, Intent arg1) { // TODO Auto-generated method stub Bundle b = arg1.getExtras(); if(b.containsKey(WeatherColumn.DayInfo_Widget)){ String string = b.getString(WeatherColumn.DayInfo_Widget); //区分该Bundle是 今天/明天 if(string.equals(WeatherColumn.DayNow)){ //Log.d("TAG","[Widget: retutn Weather - now]"); } else { //Log.d("TAG","[Widget: retutn Weather - forcast]"); } } String weather_info = ""; /* 忽略一些查询到的信息 if(b.containsKey(WeatherColumn.WeatherLocation)){ weather_info += b.getString(WeatherColumn.WeatherLocation); } if(b.containsKey(WeatherColumn.WeatherTime)){ weather_info += b.getString(WeatherColumn.WeatherTime); } */ if(b.containsKey(WeatherColumn.WeatherTemporary)){ weather_info +="温度:"+ b.getString(WeatherColumn.WeatherTemporary); displayText(weather_info); } if(b.containsKey(WeatherColumn.WeatherHumidity)){ weather_info += "\n" + "湿度:"+b.getString(WeatherColumn.WeatherHumidity); displayText(weather_info); } if(b.containsKey(WeatherColumn.WeatherIco)){ Bitmap bmp = queryImageByURI(WeatherColumn.WeatherHttpHead + b.getString(WeatherColumn.WeatherIco)); displayImage(bmp); } } }
7. WeatherMoniter 定义2 Bundle 一个用于存放当天天气数据 一个用于存放明天数据
8. 定义2个用于查询天气的函数 因为这2个*.xml的节点不同 所以需要分别定义
* 查询今天
public void queryWeatherLocal(String s){ try { URL url = new URL(s); URLConnection connection = url.openConnection(); HttpURLConnection httpConnection = (HttpURLConnection)connection; InputStream in = httpConnection.getInputStream(); int responseCode = httpConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbfactory.newDocumentBuilder(); //解析目标 Document dom = db.parse(in); //得到其所有子Element Element docEle = dom.getDocumentElement(); //得到指定的列 NodeList nl = docEle.getElementsByTagName("channel"); if (nl != null && nl.getLength() > 0) { for (int i = 0 ; i < nl.getLength(); i++) { //得到某行数据 Element entry = (Element)nl.item(i); Element info = (Element)entry.getElementsByTagName("item").item(0); //从该行中取出目标 方法:键值 Key-Value Element eTitle = (Element)info.getElementsByTagName("title").item(0); Element eDay = (Element)info.getElementsByTagName("pubDate").item(0); Element eDescription = (Element)info.getElementsByTagName("description").item(0); //取出其内容 String scity = eTitle.getFirstChild().getNodeValue(); String stime = eDay.getFirstChild().getNodeValue(); String sdescription = eDescription.getFirstChild().getNodeValue(); //遍历目标 以指定字符分割 然后按顺序放入String[] String[] string = sdescription.split("<br>"); String temporary = string[0]; String temp = temporary.split("=")[1]; String humidity = string[1]; String hum = humidity.split("=")[1]; String uIndex = string[2]; String uv_Index = uIndex.split("=")[1]; String uIntensity = string[3]; String uv_Intensity = uIntensity.split("=")[1]; //String uIntensity = string[3]; String icoName = string[5]; String address = icoName.split(" ")[1]; String address1 = address.split("=")[1]; //去除两边的"\"" String address2 = address1.replaceAll("\"", ""); //Log.d("TAG","location:"+scity); //Log.d("TAG","time:"+stime); //Log.d("TAG","temporary:"+temp); //Log.d("TAG","humidity:"+hum); //Log.d("TAG","uv index:"+uv_Index); //Log.d("TAG","uv intension:"+uv_Intensity); //image.setImageBitmap(queryImageByURI(ico_preface+address2)); //Bundle bundle = new Bundle(); wLocal.clear(); wLocal.putString(WeatherColumn.WeatherLocation, scity); wLocal.putString(WeatherColumn.WeatherTime, stime); wLocal.putString(WeatherColumn.WeatherTemporary, temp); wLocal.putString(WeatherColumn.WeatherHumidity, hum); wLocal.putString(WeatherColumn.WeatherUvIndext, uv_Index); wLocal.putString(WeatherColumn.WeatherUvIntensity, uv_Intensity); wLocal.putString(WeatherColumn.WeatherIco, address2); //标记此Bundle为 local_weather 数据 wLocal.putString(WeatherColumn.DayInfo_Widget, WeatherColumn.DayNow); } } } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (ParserConfigurationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }catch (SAXException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }
如何调用:
String local = WeatherColumn.WeatherLocal; queryWeatherLocal(local);
* 查询明天 因为目标会提供后4天天气信息 所以只选择第一天 并显示之
public void queryWeatherForcast(String s){ try { URL url = new URL(s); URLConnection connection = url.openConnection(); HttpURLConnection httpConnection = (HttpURLConnection)connection; InputStream in = httpConnection.getInputStream(); int responseCode = httpConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbfactory.newDocumentBuilder(); //解析目标 Document dom = db.parse(in); /* 步骤: * 1. 得到解析后目标:Document dom * 2. 在Document基础上做getDocumentElement()以得到最基本处理单位:Element e * 3. 再在Element基础上做getElementsByTagName() */ Element docEle = dom.getDocumentElement(); //得到指定的列 NodeList item = (NodeList)docEle.getElementsByTagName("item"); if (item != null && item.getLength() > 0) { for (int i = 0 ; i < item.getLength(); i++) { Element entry = (Element)item.item(0); //从该行中取出目标 方法:键值 Key-Value //取出 <title>....</title> Element eTitle = (Element)entry.getElementsByTagName("title").item(0); String title = eTitle.getFirstChild().getNodeValue(); //取出 <pubDate>....</pubDate> Element eData = (Element)entry.getElementsByTagName("title").item(0); String data = eTitle.getFirstChild().getNodeValue(); //取出 <description>....</description> Element eDescription = (Element)entry.getElementsByTagName("description").item(0); String description = eDescription.getFirstChild().getNodeValue(); //一次记录所有天气数据 以"\n"代替<br> //String all = description.replace("<br>", "\n"); //wForcast.putString(WeatherColumn.WeatherAll, all); String[] string = description.split("<br>"); String lTemp = string[0].split("=")[1]; String hTemp = string[1].split("=")[1]; String lHumidity = string[2].split("=")[1]; String hHumidity = string[3].split("=")[1]; String icoName = string[5]; String address = icoName.split(" ")[1]; String address1 = address.split("=")[1]; //去除两边的"\"" String ico = address1.replaceAll("\"", ""); wForcast.clear(); wForcast.putString(WeatherColumn.WeatherTemporary, lTemp+"-"+hTemp); wForcast.putString(WeatherColumn.WeatherHumidity, lHumidity+"-"+hHumidity); wForcast.putString(WeatherColumn.WeatherIco, ico); } } } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (ParserConfigurationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }catch (SAXException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }
如何调用:
String forcast = WeatherColumn.WeatherForcast; queryWeatherForcast(forcast);
9. 何时查询 查询哪天
1. WeatherMoniter 启动以后 会查询当天天气 并把查询结果返回给WeatherWidget 由其负责显示 2. 收到WeatherWidget的命令后 查询明天天气 并返回结果
10. 最上面提到的数据刷新问题 我的办法:开辟Thread 计时 时间到就重新查询数据 并返回结果给WeatherWidget 与WeatherMoniter 一同启动之
//创建Thread 用于计时 public void startLoop(){ Thread loop = new Thread(new TimeCounter()); loop.start(); } public class TimeCounter implements Runnable { @Override public void run() { // TODO Auto-generated method stub while(true){ loop(100000000); Log.d("TAG","[WeatherMoniter: Time to refresh!]"); //刷新天气数据 requeryWeatherInfo(); sendWeatherInfo(WeatherColumn.BroadcastWidget,wLocal); } } public void loop(long i){ long l = i; while(l>0){ l--; } } }
11. emulator 运行截图 对了 别忘记权限
* 当天:
* 明天:
结束!
发表评论
-
滑动抽屉 另一种解决办法
2010-07-09 17:43 0滑动抽屉 -
Spinner 定制化 增强版
2010-07-09 14:34 2571Spinner 作为下拉选 ... -
ListView 内容之分批显示
2010-06-25 20:38 5861ListView 内容循环显示 大家试想 假如 ... -
MediaScanner 研究
2010-06-23 15:21 3104MediaScanner 之所以拿MediaSc ... -
CheckBox在ListView 而导致其OnItemClickListener不会被触发
2010-06-22 20:55 18878CheckBox在ListView 而导致其OnItemCli ... -
获取Launcher 启动列表
2010-06-22 10:09 3097获取Launcher 启动列表 即 列出所有Launc ... -
PreferenceActivity 全接触
2010-06-19 12:53 9389PreferenceActivity 为了引入 ... -
android src 下载 编译 安装 全接触
2010-06-12 14:44 0android src - download install ... -
Intent.createChooser() 妙用
2010-06-12 11:14 5917Intent.createChooser(ntent targ ... -
SMS管理:收信箱 发信息 编写新信息
2010-06-07 08:14 14364SMS管理 [功能] 1. 收信箱:显示 ... -
求 android 手机 帮忙测试sms服务系统 谢谢
2010-06-05 08:25 1409Hi guys, 最近一段时间没有更新blog 因为一 ... -
流媒体 播放 理论篇
2010-05-28 14:42 2122流媒体播放 之所以为理论篇 因为该篇仅实现了播放功能 ... -
NDK 搭建与HelloWorld
2010-05-19 09:48 3152NDK [前提] 1. Cygwin 用于安装 ... -
自定义字体
2010-05-15 10:49 1162自定义字体: []代码 步骤] 1 ... -
模糊查找 再深入
2010-05-15 09:41 3096模糊查找 再深入 应某位大哥要求 再次对 SQLite ... -
快捷方式Bar + ViewGroup - 自定义
2010-05-09 09:20 2379TabActivity - 自定义 其实 这篇感觉极鸡 ... -
View 拖动&插入 研究
2010-05-09 07:14 3928View 拖动&插入 即: ... -
带图标 快捷键 Menu - 终极版
2010-05-04 20:23 1784Menu 改头换面 扩展如下: 1. 图标化文字 2 ... -
*.gif 解码 - 实践
2010-05-02 18:58 1650*.gif decode 前面已经说过 今天不打算再说了 ... -
*.gif 解码 - 理论
2010-05-01 21:11 1484我们知道Android 默认是不支持*.gif 的 但是 ...
相关推荐
类似 墨迹天气widget翻页时钟 动画效果 非帧动画实现。
android桌面天气widget+GPS
一个安卓桌面widget的应用,可以设置全国天气,查看6天天气,星期,同步更新时间,有初夏秋天四季对应四种图片
最近在研究桌面widget,弄到了一个天气预报,所以和大家一起分享
很不错的天气预报源码,UI也很不错,注释很清楚。
第4章 天气预报WIDGET的设计 19 4.1 网络功能实现 19 4.1.1 标准Java接口 19 4.1.2 Apache接口 20 4.1.3 使用Java接口连接网络 23 4.2 XML解析的实现 23 4.3 制作WIDGET应用程序 27 4.3.1 源文件组织 29 4.3.2 类...
学习mate flex actionscript 的好资源。源代码.
天气预报加widget源码.zip
个人开发的android天气预报widget源码 类似点心桌面那个 上面还带有时间显示 对于新手学习很有帮助! 如果有不懂, 可以Q我 413156542
本项目是一个天气预报项目源码,javaapk.com之前也发布过很多关于天气预报的项目源码,可以直接在站内搜索“天气”就可以找到,可以设置城市、可以更换应用内背景图片、自带天气widget小组件等,天气信息由m.weather...
Android 天气预报加widget源码
android天气时钟,待机界面的的widget显示时间和天气
雅虎天气预报WIDGET代码,可搜索世界各大城市,用于android 手机,整体可以运行,还有问题,高手们多指教指教啊。
Android 天气预报加widget源码,做的很漂亮值得学习 。
Android+天气预报加widget源码
Android平台天气预报widget的的设计和实现20.docAndroid平台天气预报widget的的设计和实现20.docAndroid平台天气预报widget的的设计和实现20.docAndroid平台天气预报widget的的设计和实现20.docAndroid平台天气预报...
android 天气widget 桌面显示天气
android天气时钟,待机界面显示的widget
Android 天气预报加widget源码.rar
Android平台天气预报widget的设计与实现毕业论文 目 录 第1章 绪论 1 1.1 项目背景 1 1.2 研究现状 1 1.3 论文组织 2 第2章 ANDROID开发环境 3 2.1 ANDROID开发环境搭建流程 3 2.1.1 安装Eclipse ADT Plugin插件 3 ...