activity_main.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. tools:context=".MainActivity" >
  10.  
  11. <Button
  12. android:id="@+id/get_data_btn"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:layout_alignParentLeft="true"
  16. android:layout_alignParentTop="true"
  17. android:text="@string/get_data" />
  18.  
  19. <TextView
  20. android:id="@+id/textView1"
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. android:layout_alignLeft="@+id/get_data_btn"
  24. android:layout_below="@+id/get_data_btn"/>
  25.  
  26. </RelativeLayout>

MainActivity.java

  1. /**
  2. * 最近在看天气预报的相关知识,想寻找一个比较合适的API接口,终于找到了这篇文档
  3. * http://blog.csdn.net/lzqwebsoft/article/details/7054045
  4. * 里面详细说明的怎样从中国天气网获取天气信息,可是没用几天发现文中使用的获取城市
  5. * 列表的接口貌似被封了,导致原先的方法不使用,后悔但是没能及时将相关信息保存下来
  6. * ,以前是考虑每次实时的从网络上获取城市列表,以防信息有变,但是这种接口本身就是
  7. * 个不稳定的因素,所以还是得把相关信息下载下来。最后只得自己去分析网页,需找另外
  8. * 的接口,最后终于找到了,那就老老实实把这些数据保存到数据库里面吧。
  9. * 天气网把城市分为了3级
  10. * 1级列表获取地址:http://www.weather.com.cn/data/city3jdata/china.html。通过访问这个地址,天气
  11. * 网会返回一级省(自治区)的名称、ID信息;
  12. * 2级城市城市列表获取地址:http://www.weather.com.cn/data/city3jdata/provshi/10120.html。其中“10120”
  13. * 为一级城市的ID,返回结果是归属于该城市的2级省市的名称、ID;
  14. * 3级城市列表获取地址:http://www.weather.com.cn/data/city3jdata/station/1012002.html。其中“1012002”
  15. * 为2级省市ID,返回结果就是3级城市的名称和ID了。
  16. * 获取到3级城市的名称和ID之后,就可以根据上面那篇博客里的内容获取当地的天气信息了!
  17. * */
  18. package com.ns.getweathercity;
  19.  
  20. import java.io.IOException;
  21.  
  22. import org.apache.http.HttpResponse;
  23. import org.apache.http.HttpStatus;
  24. import org.apache.http.HttpVersion;
  25. import org.apache.http.client.ClientProtocolException;
  26. import org.apache.http.client.HttpClient;
  27. import org.apache.http.client.methods.HttpGet;
  28. import org.apache.http.client.params.HttpClientParams;
  29. import org.apache.http.conn.ClientConnectionManager;
  30. import org.apache.http.conn.params.ConnManagerParams;
  31. import org.apache.http.conn.scheme.PlainSocketFactory;
  32. import org.apache.http.conn.scheme.Scheme;
  33. import org.apache.http.conn.scheme.SchemeRegistry;
  34. import org.apache.http.conn.ssl.SSLSocketFactory;
  35. import org.apache.http.impl.client.DefaultHttpClient;
  36. import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
  37. import org.apache.http.params.BasicHttpParams;
  38. import org.apache.http.params.HttpConnectionParams;
  39. import org.apache.http.params.HttpParams;
  40. import org.apache.http.params.HttpProtocolParams;
  41. import org.apache.http.protocol.HTTP;
  42. import org.apache.http.util.EntityUtils;
  43.  
  44. import android.os.AsyncTask;
  45. import android.os.Bundle;
  46. import android.app.Activity;
  47. import android.content.ContentValues;
  48. import android.util.Log;
  49. import android.view.Menu;
  50. import android.view.View;
  51. import android.view.View.OnClickListener;
  52. import android.widget.Button;
  53. import android.widget.TextView;
  54. import android.widget.Toast;
  55.  
  56. public class MainActivity extends Activity implements OnClickListener{
  57.  
  58. private Button mGetDataButton = null;
  59. private TextView mProgressTextView = null;
  60.  
  61. @Override
  62. protected void onCreate(Bundle savedInstanceState) {
  63. super.onCreate(savedInstanceState);
  64. setContentView(R.layout.activity_main);
  65.  
  66. mGetDataButton = (Button)findViewById(R.id.get_data_btn);
  67. mGetDataButton.setOnClickListener(this);
  68.  
  69. mProgressTextView = (TextView)findViewById(R.id.textView1);
  70. }
  71.  
  72. @Override
  73. public boolean onCreateOptionsMenu(Menu menu) {
  74. // Inflate the menu; this adds items to the action bar if it is present.
  75. getMenuInflater().inflate(R.menu.main, menu);
  76. return true;
  77. }
  78.  
  79. @Override
  80. public void onClick(View v) {
  81. switch (v.getId()) {
  82. case R.id.get_data_btn:
  83. new GetDataTask().execute();
  84. break;
  85.  
  86. default:
  87. break;
  88. }
  89. }
  90.  
  91. private class GetDataTask extends AsyncTask<Void, Integer, Integer> {
  92.  
  93. private HttpClient httpClient = null;
  94.  
  95. @Override
  96. protected void onPreExecute() {
  97. super.onPreExecute();
  98. }
  99.  
  100. @Override
  101. protected Integer doInBackground(Void... params) {
  102. getHttpClient();
  103.  
  104. CityDataHelper.getInstance(MainActivity.this).delete(null, null);
  105.  
  106. //通过递归获取城市列表
  107. try {
  108. getCitys(1, "", "http://www.weather.com.cn/data/city3jdata/china.html");
  109. } catch (ClientProtocolException e) {
  110. Log.e("ns", "error", e);
  111. return -1;
  112. } catch (IOException e) {
  113. Log.e("ns", "error", e);
  114. return -1;
  115. }
  116. return 1;
  117. }
  118.  
  119. /**这个函数的代码,参照http://blog.csdn.net/suiyuansanren/article/details/8663824这篇博文
  120. * 写的不错*/
  121. private synchronized HttpClient getHttpClient() {
  122. if(httpClient == null) {
  123. final HttpParams httpParams = new BasicHttpParams();
  124.  
  125. // timeout: get connections from connection pool
  126. ConnManagerParams.setTimeout(httpParams, 5000);
  127. // timeout: connect to the server
  128. HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
  129. // timeout: transfer data from server
  130. HttpConnectionParams.setSoTimeout(httpParams, 5000);
  131.  
  132. // set max connections per host
  133. //ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(10));
  134. // set max total connections
  135. ConnManagerParams.setMaxTotalConnections(httpParams, 20);
  136.  
  137. // use expect-continue handshake
  138. HttpProtocolParams.setUseExpectContinue(httpParams, true);
  139. // disable stale check
  140. HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
  141.  
  142. HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
  143. HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
  144.  
  145. HttpClientParams.setRedirecting(httpParams, false);
  146.  
  147. // set user agent
  148. String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
  149. HttpProtocolParams.setUserAgent(httpParams, userAgent);
  150.  
  151. // disable Nagle algorithm
  152. HttpConnectionParams.setTcpNoDelay(httpParams, true);
  153.  
  154. HttpConnectionParams.setSocketBufferSize(httpParams, 8*1024);
  155.  
  156. // scheme: http and https
  157. SchemeRegistry schemeRegistry = new SchemeRegistry();
  158. schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
  159. schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
  160.  
  161. ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
  162. httpClient = new DefaultHttpClient(manager, httpParams);
  163. }
  164.  
  165. return httpClient;
  166. }
  167.  
  168. private void getCitys(int level, String pid, String url) throws ClientProtocolException, IOException {
  169. Log.i("ns", "The url is " + url);
  170. HttpGet httpGet = null;
  171.  
  172. HttpResponse httpResponse = null;
  173. String citys = null;
  174. String[] citys1Array = null;
  175. int index = 0;
  176. String cityName = null;
  177. String cityID = null;
  178.  
  179. httpGet = new HttpGet(url);
  180. if (httpClient != null) {
  181. httpResponse = httpClient.execute(httpGet);
  182. if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  183. citys = EntityUtils.toString(httpResponse.getEntity(),
  184. HTTP.UTF_8);
  185. if (citys != null && citys.trim().length() > 0) {
  186. citys1Array = citys.substring(1, citys.length() - 1)
  187. .split(",");
  188. for (int i = 0; i < citys1Array.length; i++) {
  189. index = citys1Array[i].indexOf(":");
  190. //当前城市的ID需要用上一级城市的ID拼接出来,但是有个别的三级城市直接是最终的ID了
  191. //不知道天气网为什么要这么做
  192. cityID = citys1Array[i].substring(1, index - 1);
  193. if (level != 3 || cityID.length() < 9) {
  194. cityID = pid + cityID;
  195. }
  196.  
  197. //这里把当前正在进行的操作提示处理,以确保正在工作
  198. publishProgress(Integer.parseInt(cityID));
  199.  
  200. cityName = citys1Array[i].substring(index + 2,
  201. citys1Array[i].length() - 1);
  202.  
  203. // 插入数据库
  204. ContentValues values = new ContentValues();
  205. values.put(CityContract.City.NAME, cityName);
  206. values.put(CityContract.City.CITY_ID, cityID);
  207. values.put(CityContract.City.LEVEL, level);
  208. values.put(CityContract.City.PARENT_CITY_ID, pid);
  209. CityDataHelper.getInstance(MainActivity.this)
  210. .insert(values);
  211.  
  212. // 递归下一级列表
  213. if (level == 1) {
  214. // 获取二级列表
  215. getCitys(2, cityID,
  216. "http://www.weather.com.cn/data/city3jdata/provshi/"
  217. + cityID + ".html");
  218. } else if (level == 2) {
  219. // 获取三级列表
  220. getCitys(3, cityID,
  221. "http://www.weather.com.cn/data/city3jdata/station/"
  222. + cityID + ".html");
  223. } else if (level == 3) {
  224. continue;
  225. }
  226.  
  227. }
  228. }
  229. }
  230. }
  231.  
  232. }
  233.  
  234. @Override
  235. protected void onProgressUpdate(Integer... values) {
  236. super.onProgressUpdate(values);
  237. mProgressTextView.setText(values[0].intValue() + "");
  238. }
  239.  
  240. @Override
  241. protected void onPostExecute(Integer result) {
  242. super.onPostExecute(result);
  243. Toast.makeText(MainActivity.this, "数据拉取完毕", Toast.LENGTH_SHORT).show();
  244. //到这里,所有城市的名称、ID以及他们之间的关系就存放到数据库里面了,下次直接使用即可
  245. }
  246. }
  247. }

CityContract.java

  1. package com.ns.getweathercity;
  2.  
  3. import android.provider.BaseColumns;
  4.  
  5. public class CityContract {
  6.  
  7. private CityContract() {}
  8.  
  9. public abstract static class City implements BaseColumns {
  10. //数据库表名
  11. public static final String TABLE_NAME = "city";
  12. //城市名称
  13. public static final String NAME = "name";
  14. //城市级别
  15. public static final String LEVEL = "level";
  16. //城市ID
  17. public static final String CITY_ID = "city_id";
  18. //上一级城市ID
  19. public static final String PARENT_CITY_ID = "p_c_id";
  20. }
  21.  
  22. }

CityDataHelper.java

  1. package com.ns.getweathercity;
  2.  
  3. import android.content.ContentValues;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.database.sqlite.SQLiteOpenHelper;
  8.  
  9. public class CityDataHelper extends SQLiteOpenHelper {
  10.  
  11. private static final int DATABASE_VERSION = 1;
  12. private static final String DATABASE_NAME = "city.db";
  13.  
  14. private static final String SQL_CREATE_STUDENT = "create table " +
  15. CityContract.City.TABLE_NAME + " (" +
  16. CityContract.City._ID + " INTEGER PRIMARY KEY, " +
  17. CityContract.City.NAME + " TEXT, " +
  18. CityContract.City.LEVEL + " INTEGER, " +
  19. CityContract.City.CITY_ID + " TEXT, " +
  20. CityContract.City.PARENT_CITY_ID + " TEXT)";
  21.  
  22. private static CityDataHelper mDbHelper = null;
  23.  
  24. public static CityDataHelper getInstance(Context context) {
  25. if (mDbHelper == null) {
  26. mDbHelper = new CityDataHelper(context);
  27. }
  28. return mDbHelper;
  29. }
  30.  
  31. /**
  32. * constructor
  33. *
  34. * @param context
  35. * Context object used for create database
  36. */
  37. private CityDataHelper(Context context) {
  38. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  39. }
  40.  
  41. @Override
  42. public void onCreate(SQLiteDatabase db) {
  43. //创建“city”表
  44. db.execSQL(SQL_CREATE_STUDENT);
  45.  
  46. }
  47.  
  48. @Override
  49. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  50.  
  51. }
  52.  
  53. public synchronized long insert(ContentValues values) {
  54. long id = getWritableDatabase().insert(CityContract.City.TABLE_NAME, null, values);
  55. return id;
  56. }
  57.  
  58. public synchronized long update(ContentValues values, String whereClause, String[] whereArgs) {
  59. long id = getWritableDatabase().update(CityContract.City.TABLE_NAME, values, whereClause, whereArgs);
  60. return id;
  61. }
  62.  
  63. public synchronized int delete(String whereClause, String[] whereArgs) {
  64. int count = getWritableDatabase().delete(CityContract.City.TABLE_NAME, whereClause, whereArgs);
  65. return count;
  66. }
  67.  
  68. public synchronized Cursor query(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
  69. return getReadableDatabase().query(CityContract.City.TABLE_NAME, columns, selection, selectionArgs, groupBy, having, orderBy);
  70. }
  71. }

获取中央气象台API 完整城市列表简单方式的更多相关文章

  1. vue实现城市列表选择

    成果展示 最后的成果就是下面所展示的内容,因为gif图没有做,只能截图所展示,接下来,会带着大家一步一步的完成下面功能,脚手架搭建和node安装在本次案例不会讲解,如果了解,可以在我的博客园找到有详细 ...

  2. C#开发BIMFACE系列25 服务端API之获取模型数据10:获取楼层对应面积分区列表

    系列目录     [已更新最新开发文章,点击查看详细] 在<C#开发BIMFACE系列22 服务端API之获取模型数据7:获取多个模型的楼层信息>中,返回的楼层信息结果中包含了楼层的具体信 ...

  3. java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))

    1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...

  4. Struts2中获取servlet API的几种方式

    struts2是一个全新的MVC框架,如今被广大的企业和开发者所使用,它的功能非常强大.这给我们在使用servlet 纯java代码写项目的时候带来了福音.但是一般来说,我们的项目不到一定规模并不需要 ...

  5. 【python】获取高德地图省市区县列表

    项目中需要用省市区来进行检索,原想高德地图肯定会有API来获得这些数据,结果没有找到,有一个接口好像可以用,但是会附带大量的边界坐标点. 所以就不如自己把高德的省市区列表扒下来,自己写接口来完成这个功 ...

  6. Android例子源码非第三方实现根据字母排序的城市列表

    values 下dimens.xml <resources> <!-- Default screen margins, per the Android Design guidelin ...

  7. 【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘

    原文:[高德地图API]从零开始学高德JS API(七)——定位方式大揭秘 摘要:关于定位,分为GPS定位和网络定位2种.GPS定位,精度较高,可达到10米,但室内不可用,且超级费电.网络定位,分为w ...

  8. Android应用--简、美音乐播放器获取专辑图片(自定义列表适配器)

    Android应用--简.美音乐播放器获取专辑图片(自定义列表适配器) 2013年7月3日简.美音乐播放器开发 第二阶段已增加功能: 1.歌词滚动显示 2.来电监听 3.音量控制 4.左右滑动切换歌词 ...

  9. 剖析Asp.Net Web API路由系统---WebHost部署方式

    上一篇我们剖析了Asp.Net路由系统,今天我们再来简单剖析一下Asp.Net Web API以WebHost方式部署时,Asp.Net Web API的路由系统内部是怎样实现的.还是以一个简单实例开 ...

随机推荐

  1. NOPI导出Excel

    NOPI导出Excel /// <summary> /// 导出的方法 Excel样式 /// </summary> /// <param name="ds&q ...

  2. springmvc结合freemarker,非自定义标签

    参考:http://viralpatel.net/blogs/spring-mvc-freemarker-ftl-example/ 上图: 目录层级: 启动后的访问地址:http://localhos ...

  3. RecyclerView 小记

    RecyclerView,是在v7包加入的,一个灵活的view可以展示巨大的数据集,类似于listview的viewholder复用已经优化好了. 语言是苍白的,代码是最生动的叙说: 布局: < ...

  4. web编程速度大比拼(nodejs go python)(非专业对比)

    C10K问题的解决,涌现出一大批新框架,或者新语言,那么问题来了:到底谁最快呢?非专业程序猿来个非专业对比. 比较程序:输出Hello World! 测试程序:siege –c 100 –r 100 ...

  5. BOM 浏览器对象模型学习

    window对象属性 innerWidth/innerHeight 浏览器窗口的内部宽度与高度 outerWidth/outerHeight 浏览器的外部宽度与高度 length window.fra ...

  6. IOS 特定于设备的开发:获取额外的设备信息

    sysctl()和sysctlbyname()允许获取系统信息.这些标准的UNIX函数用于询问操作系统有关硬件和OS的详细信息. 这些常量使你能够检查核心信息,比如系统的CPU频率,可用的内存量等.它 ...

  7. valgrind用于检测内存泄露

    http://www.thegeekstuff.com/2011/11/valgrind-memcheck/

  8. MySQL 分区表各个分区的行数

    分区的信息是记录在information_schema.partitions 这个表里的.它不能直接定位行所在的分区,但它可查到每个分区中有多少行. 例子: select partition_name ...

  9. 三种客户端访问wcf服务端的方法 C#

    原文 http://blog.csdn.net/zlj002/article/details/7914556 string jsonstr = String.Empty; string url = & ...

  10. yii_CGridView_ajax_pagination_and_ajax_sort

    本文主要内容: 1, 正常情况下 CGridView 实现 Ajax 分页和排序的原理 2, 分页和排序无法Ajax的情况分析 3, 自定义分页(重写CLinkPager)后如何实现 Ajax 分页和 ...