天气应用工事中
再不说点什么可能都忘了我写了些什么了。
折腾了快一个周,只写出了两个处理xml文件的模块。
用的API是新浪的,格式大概是这个样子:
private String city = CharacterProcesser.encodeByGB2312("南昌"); private String password = "DJOYnieT8234jlsK"; private int day = 0; private String link = "http://php.weather.sina.com.cn/xml.php?city=" + city + "&password=" + password + "&day=" + day;
上面那个encode方法就是这两天卡住我的问题之一,不过其实是今天才发现的。
先发代码吧,只有两个模块,完成度还都不高,其实不应该是1.0的。
1 package com.mlxy.xml; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileOutputStream; 6 import java.io.InputStream; 7 import java.io.InputStreamReader; 8 import java.io.OutputStreamWriter; 9 import java.net.MalformedURLException; 10 import java.net.URL; 11 12 import org.dom4j.Document; 13 import org.dom4j.DocumentException; 14 import org.dom4j.Node; 15 import org.dom4j.io.SAXReader; 16 17 import android.content.Context; 18 import android.os.Environment; 19 import android.util.Log; 20 21 import com.mlxy.util.CharacterProcesser; 22 23 /** 24 * XML文件下载器。 25 * 26 * @author mlxy 27 * @version 1.0 28 * */ 29 public class XmlDownloader { 30 private Context parent; 31 32 private String city = CharacterProcesser.encodeByGB2312("南昌"); 33 private String password = "DJOYnieT8234jlsK"; 34 private int day = 0; 35 private String link = "http://php.weather.sina.com.cn/xml.php?city=" + city 36 + "&password=" + password + "&day=" + day; 37 38 public XmlDownloader(Context parent) { 39 this.parent = parent; 40 } 41 42 /** 外部接口,根据设置好的类属性下载xml文件。 43 * 44 * @return 下载成功则返回true,失败则返回false。*/ 45 public boolean download() { 46 return downloadAndVerifyXml(this.link); 47 } 48 49 /** 根据给定的链接下载对应的xml文件。 50 * 51 * @param link API的链接,需要标明网络协议。 52 * @return 下载并验证格式正确则返回true,否则返回false。*/ 53 private boolean downloadAndVerifyXml(String link) { 54 // 用链接字符串new出URL对象 55 URL url = null; 56 try { 57 url = new URL(link); 58 } catch (MalformedURLException e) { 59 e.printStackTrace(); 60 } 61 62 // 获取外部存储路径并创建文件对象。 63 File externalDirectory = Environment.getExternalStorageDirectory(); 64 String fileName = "xml_resource.xml"; 65 File file = new File(externalDirectory, fileName); 66 67 // 写文件。 68 69 // 初始化io流。 70 InputStream in = null; 71 BufferedReader reader = null; 72 FileOutputStream out = null; 73 OutputStreamWriter writer = null; 74 75 try { 76 77 // 建立连接并给io流赋值。 78 in = (InputStream) url.getContent(); 79 reader = new BufferedReader(new InputStreamReader(in, "iso-8859-1")); 80 out = this.parent.openFileOutput(file.getName(), Context.MODE_PRIVATE); 81 writer = new OutputStreamWriter(out, "iso-8859-1"); 82 83 // 读一行写一行 84 String line = null; 85 while ((line = reader.readLine()) != null) { 86 Log.v("mlxy", line); 87 writer.write(line); 88 } 89 90 } catch (Exception e) { 91 e.printStackTrace(); 92 } finally { 93 try { 94 // 释放资源 95 writer.close(); 96 out.close(); 97 reader.close(); 98 in.close(); 99 } catch (Exception e2) { 100 e2.printStackTrace(); 101 } 102 } 103 104 // // 验证信息是否成功获取。 105 // if (isAvailable(file)) { 106 // return true; 107 // } else { 108 // return false; 109 // } 110 Log.v("mlxy", "ok"); 111 return true; 112 } 113 114 /** 验证xml文件是否符合要求。 115 * 116 * @param xmlFile 用以验证合法性的xml文件。 117 * @return 符合需要格式则返回true,否则返回false。*/ 118 private boolean isAvailable(File xmlFile) { 119 if (!xmlFile.exists()) { 120 return false; 121 } 122 123 SAXReader reader = new SAXReader(); 124 Document doc = null; 125 try { 126 doc = reader.read(xmlFile); 127 } catch (DocumentException e) { 128 e.printStackTrace(); 129 } 130 131 if (doc == null) { 132 return false; 133 } 134 135 // 检查城市节点是否存在,不存在则返回false。 136 Node node = doc.selectSingleNode("//Profiles/Weather/city"); 137 138 if (node == null) { 139 return false; 140 } else { 141 return true; 142 } 143 } 144 145 public XmlDownloader setCity(String city) { 146 this.city = city; 147 return this; 148 } 149 public String getCity() { 150 return this.city; 151 } 152 153 public XmlDownloader setPassword(String password) { 154 this.password = password; 155 return this; 156 } 157 public String getPassword() { 158 return this.password; 159 } 160 161 public XmlDownloader setDay(int day) { 162 this.day = day; 163 return this; 164 } 165 public int getDay() { 166 return this.day; 167 } 168 169 /** 获取API链接。*/ 170 public String getLink() { 171 return this.link; 172 } 173 }
1 package com.mlxy.xml; 2 3 import org.dom4j.Document; 4 import org.dom4j.Node; 5 6 /** 7 * xml的解析器,包含了获取所需节点内容的方法。 8 * 9 * @author mlxy 10 * @version 1.0 11 * */ 12 public class XmlParser { 13 14 /** 根据给定的文档和节点返回节点内容。 15 * 16 * @param doc nodeName 需要解析的Document对象,以及要获取其内容的节点名称。 17 * @return 获取失败则返回空值,否则返回节点内容。*/ 18 private String getNodeText(Document doc, String nodeName) { 19 // 如果传入的文档是空值就返回空值。 20 if (doc == null) { 21 return null; 22 } 23 24 // 获取相应节点。 25 Node node = doc.selectSingleNode("//Profiles/Weather/" + nodeName); 26 27 // 如果节点是空值就返回空值。 28 if (node == null) { 29 return null; 30 } 31 32 // 获取节点内容并返回字符串。 33 String nodeContent = node.getText(); 34 35 return nodeContent; 36 } 37 38 /** 根据输入的Document对象解析xml并返回温度。 39 * 40 * @param doc 需要解析的Document对象。 41 * @return 获取失败返回null,成功则将白天和夜晚的温度格式化为一个字符串并返回*/ 42 public String getTemperature(Document doc) { 43 String temperatureDaytimeString = this.getNodeText(doc, "temperature1"); 44 String temperatureNighttimeString = this.getNodeText(doc, "temperature2"); 45 46 // 温度获取失败则返回空值。 47 // 可能因为文档不存在,也可能因为文档错误导致无法获得相应节点,也可能是节点内容是空值。 48 if (temperatureDaytimeString == null || temperatureNighttimeString == null) { 49 return null; 50 } 51 52 // 获取成功则格式化并返回。 53 return temperatureNighttimeString + "℃ - " + temperatureDaytimeString + "℃"; 54 } 55 56 /** 根据输入的Document对象解析xml并返回天气状况。 57 * 58 * @param doc 需要解析的Document对象。 59 * @return 获取失败返回null,成功则将白天和夜晚的天气状况格式化为一个字符串并返回。*/ 60 public String getWeather(Document doc) { 61 String weatherDaytimeString = this.getNodeText(doc, "status1"); 62 String weatherNighttimeString = this.getNodeText(doc, "status2"); 63 64 // 天气状况获取失败则返回空值。 65 // 可能因为文档不存在,也可能因为文档错误导致无法获得相应节点,也可能是节点内容是空值。 66 if (weatherDaytimeString == null || weatherNighttimeString == null) { 67 return null; 68 } 69 70 // 获取成功则格式化并返回。 71 return "白天:" + weatherNighttimeString + " 夜间:" + weatherDaytimeString; 72 } 73 }
因为写这篇博文的时候我还在敲代码,所以上面的代码里可能有做到一半的东西,总之是不太能用。
具体问题还是单独发博吧。