获取中央气象台API 完整城市列表简单方式
activity_main.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity" >
- <Button
- android:id="@+id/get_data_btn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:text="@string/get_data" />
- <TextView
- android:id="@+id/textView1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/get_data_btn"
- android:layout_below="@+id/get_data_btn"/>
- </RelativeLayout>
MainActivity.java
- /**
- * 最近在看天气预报的相关知识,想寻找一个比较合适的API接口,终于找到了这篇文档
- * http://blog.csdn.net/lzqwebsoft/article/details/7054045
- * 里面详细说明的怎样从中国天气网获取天气信息,可是没用几天发现文中使用的获取城市
- * 列表的接口貌似被封了,导致原先的方法不使用,后悔但是没能及时将相关信息保存下来
- * ,以前是考虑每次实时的从网络上获取城市列表,以防信息有变,但是这种接口本身就是
- * 个不稳定的因素,所以还是得把相关信息下载下来。最后只得自己去分析网页,需找另外
- * 的接口,最后终于找到了,那就老老实实把这些数据保存到数据库里面吧。
- * 天气网把城市分为了3级
- * 1级列表获取地址:http://www.weather.com.cn/data/city3jdata/china.html。通过访问这个地址,天气
- * 网会返回一级省(自治区)的名称、ID信息;
- * 2级城市城市列表获取地址:http://www.weather.com.cn/data/city3jdata/provshi/10120.html。其中“10120”
- * 为一级城市的ID,返回结果是归属于该城市的2级省市的名称、ID;
- * 3级城市列表获取地址:http://www.weather.com.cn/data/city3jdata/station/1012002.html。其中“1012002”
- * 为2级省市ID,返回结果就是3级城市的名称和ID了。
- * 获取到3级城市的名称和ID之后,就可以根据上面那篇博客里的内容获取当地的天气信息了!
- * */
- package com.ns.getweathercity;
- import java.io.IOException;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.HttpVersion;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.params.HttpClientParams;
- import org.apache.http.conn.ClientConnectionManager;
- import org.apache.http.conn.params.ConnManagerParams;
- import org.apache.http.conn.scheme.PlainSocketFactory;
- import org.apache.http.conn.scheme.Scheme;
- import org.apache.http.conn.scheme.SchemeRegistry;
- import org.apache.http.conn.ssl.SSLSocketFactory;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.HttpConnectionParams;
- import org.apache.http.params.HttpParams;
- import org.apache.http.params.HttpProtocolParams;
- import org.apache.http.protocol.HTTP;
- import org.apache.http.util.EntityUtils;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.app.Activity;
- import android.content.ContentValues;
- import android.util.Log;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MainActivity extends Activity implements OnClickListener{
- private Button mGetDataButton = null;
- private TextView mProgressTextView = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mGetDataButton = (Button)findViewById(R.id.get_data_btn);
- mGetDataButton.setOnClickListener(this);
- mProgressTextView = (TextView)findViewById(R.id.textView1);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.get_data_btn:
- new GetDataTask().execute();
- break;
- default:
- break;
- }
- }
- private class GetDataTask extends AsyncTask<Void, Integer, Integer> {
- private HttpClient httpClient = null;
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
- @Override
- protected Integer doInBackground(Void... params) {
- getHttpClient();
- CityDataHelper.getInstance(MainActivity.this).delete(null, null);
- //通过递归获取城市列表
- try {
- getCitys(1, "", "http://www.weather.com.cn/data/city3jdata/china.html");
- } catch (ClientProtocolException e) {
- Log.e("ns", "error", e);
- return -1;
- } catch (IOException e) {
- Log.e("ns", "error", e);
- return -1;
- }
- return 1;
- }
- /**这个函数的代码,参照http://blog.csdn.net/suiyuansanren/article/details/8663824这篇博文
- * 写的不错*/
- private synchronized HttpClient getHttpClient() {
- if(httpClient == null) {
- final HttpParams httpParams = new BasicHttpParams();
- // timeout: get connections from connection pool
- ConnManagerParams.setTimeout(httpParams, 5000);
- // timeout: connect to the server
- HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
- // timeout: transfer data from server
- HttpConnectionParams.setSoTimeout(httpParams, 5000);
- // set max connections per host
- //ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(10));
- // set max total connections
- ConnManagerParams.setMaxTotalConnections(httpParams, 20);
- // use expect-continue handshake
- HttpProtocolParams.setUseExpectContinue(httpParams, true);
- // disable stale check
- HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
- HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
- HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
- HttpClientParams.setRedirecting(httpParams, false);
- // set user agent
- String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
- HttpProtocolParams.setUserAgent(httpParams, userAgent);
- // disable Nagle algorithm
- HttpConnectionParams.setTcpNoDelay(httpParams, true);
- HttpConnectionParams.setSocketBufferSize(httpParams, 8*1024);
- // scheme: http and https
- SchemeRegistry schemeRegistry = new SchemeRegistry();
- schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
- ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
- httpClient = new DefaultHttpClient(manager, httpParams);
- }
- return httpClient;
- }
- private void getCitys(int level, String pid, String url) throws ClientProtocolException, IOException {
- Log.i("ns", "The url is " + url);
- HttpGet httpGet = null;
- HttpResponse httpResponse = null;
- String citys = null;
- String[] citys1Array = null;
- int index = 0;
- String cityName = null;
- String cityID = null;
- httpGet = new HttpGet(url);
- if (httpClient != null) {
- httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- citys = EntityUtils.toString(httpResponse.getEntity(),
- HTTP.UTF_8);
- if (citys != null && citys.trim().length() > 0) {
- citys1Array = citys.substring(1, citys.length() - 1)
- .split(",");
- for (int i = 0; i < citys1Array.length; i++) {
- index = citys1Array[i].indexOf(":");
- //当前城市的ID需要用上一级城市的ID拼接出来,但是有个别的三级城市直接是最终的ID了
- //不知道天气网为什么要这么做
- cityID = citys1Array[i].substring(1, index - 1);
- if (level != 3 || cityID.length() < 9) {
- cityID = pid + cityID;
- }
- //这里把当前正在进行的操作提示处理,以确保正在工作
- publishProgress(Integer.parseInt(cityID));
- cityName = citys1Array[i].substring(index + 2,
- citys1Array[i].length() - 1);
- // 插入数据库
- ContentValues values = new ContentValues();
- values.put(CityContract.City.NAME, cityName);
- values.put(CityContract.City.CITY_ID, cityID);
- values.put(CityContract.City.LEVEL, level);
- values.put(CityContract.City.PARENT_CITY_ID, pid);
- CityDataHelper.getInstance(MainActivity.this)
- .insert(values);
- // 递归下一级列表
- if (level == 1) {
- // 获取二级列表
- getCitys(2, cityID,
- "http://www.weather.com.cn/data/city3jdata/provshi/"
- + cityID + ".html");
- } else if (level == 2) {
- // 获取三级列表
- getCitys(3, cityID,
- "http://www.weather.com.cn/data/city3jdata/station/"
- + cityID + ".html");
- } else if (level == 3) {
- continue;
- }
- }
- }
- }
- }
- }
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- mProgressTextView.setText(values[0].intValue() + "");
- }
- @Override
- protected void onPostExecute(Integer result) {
- super.onPostExecute(result);
- Toast.makeText(MainActivity.this, "数据拉取完毕", Toast.LENGTH_SHORT).show();
- //到这里,所有城市的名称、ID以及他们之间的关系就存放到数据库里面了,下次直接使用即可
- }
- }
- }
CityContract.java
- package com.ns.getweathercity;
- import android.provider.BaseColumns;
- public class CityContract {
- private CityContract() {}
- public abstract static class City implements BaseColumns {
- //数据库表名
- public static final String TABLE_NAME = "city";
- //城市名称
- public static final String NAME = "name";
- //城市级别
- public static final String LEVEL = "level";
- //城市ID
- public static final String CITY_ID = "city_id";
- //上一级城市ID
- public static final String PARENT_CITY_ID = "p_c_id";
- }
- }
CityDataHelper.java
- package com.ns.getweathercity;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- public class CityDataHelper extends SQLiteOpenHelper {
- private static final int DATABASE_VERSION = 1;
- private static final String DATABASE_NAME = "city.db";
- private static final String SQL_CREATE_STUDENT = "create table " +
- CityContract.City.TABLE_NAME + " (" +
- CityContract.City._ID + " INTEGER PRIMARY KEY, " +
- CityContract.City.NAME + " TEXT, " +
- CityContract.City.LEVEL + " INTEGER, " +
- CityContract.City.CITY_ID + " TEXT, " +
- CityContract.City.PARENT_CITY_ID + " TEXT)";
- private static CityDataHelper mDbHelper = null;
- public static CityDataHelper getInstance(Context context) {
- if (mDbHelper == null) {
- mDbHelper = new CityDataHelper(context);
- }
- return mDbHelper;
- }
- /**
- * constructor
- *
- * @param context
- * Context object used for create database
- */
- private CityDataHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- //创建“city”表
- db.execSQL(SQL_CREATE_STUDENT);
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
- public synchronized long insert(ContentValues values) {
- long id = getWritableDatabase().insert(CityContract.City.TABLE_NAME, null, values);
- return id;
- }
- public synchronized long update(ContentValues values, String whereClause, String[] whereArgs) {
- long id = getWritableDatabase().update(CityContract.City.TABLE_NAME, values, whereClause, whereArgs);
- return id;
- }
- public synchronized int delete(String whereClause, String[] whereArgs) {
- int count = getWritableDatabase().delete(CityContract.City.TABLE_NAME, whereClause, whereArgs);
- return count;
- }
- public synchronized Cursor query(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
- return getReadableDatabase().query(CityContract.City.TABLE_NAME, columns, selection, selectionArgs, groupBy, having, orderBy);
- }
- }
获取中央气象台API 完整城市列表简单方式的更多相关文章
- vue实现城市列表选择
成果展示 最后的成果就是下面所展示的内容,因为gif图没有做,只能截图所展示,接下来,会带着大家一步一步的完成下面功能,脚手架搭建和node安装在本次案例不会讲解,如果了解,可以在我的博客园找到有详细 ...
- C#开发BIMFACE系列25 服务端API之获取模型数据10:获取楼层对应面积分区列表
系列目录 [已更新最新开发文章,点击查看详细] 在<C#开发BIMFACE系列22 服务端API之获取模型数据7:获取多个模型的楼层信息>中,返回的楼层信息结果中包含了楼层的具体信 ...
- java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))
1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...
- Struts2中获取servlet API的几种方式
struts2是一个全新的MVC框架,如今被广大的企业和开发者所使用,它的功能非常强大.这给我们在使用servlet 纯java代码写项目的时候带来了福音.但是一般来说,我们的项目不到一定规模并不需要 ...
- 【python】获取高德地图省市区县列表
项目中需要用省市区来进行检索,原想高德地图肯定会有API来获得这些数据,结果没有找到,有一个接口好像可以用,但是会附带大量的边界坐标点. 所以就不如自己把高德的省市区列表扒下来,自己写接口来完成这个功 ...
- Android例子源码非第三方实现根据字母排序的城市列表
values 下dimens.xml <resources> <!-- Default screen margins, per the Android Design guidelin ...
- 【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘
原文:[高德地图API]从零开始学高德JS API(七)——定位方式大揭秘 摘要:关于定位,分为GPS定位和网络定位2种.GPS定位,精度较高,可达到10米,但室内不可用,且超级费电.网络定位,分为w ...
- Android应用--简、美音乐播放器获取专辑图片(自定义列表适配器)
Android应用--简.美音乐播放器获取专辑图片(自定义列表适配器) 2013年7月3日简.美音乐播放器开发 第二阶段已增加功能: 1.歌词滚动显示 2.来电监听 3.音量控制 4.左右滑动切换歌词 ...
- 剖析Asp.Net Web API路由系统---WebHost部署方式
上一篇我们剖析了Asp.Net路由系统,今天我们再来简单剖析一下Asp.Net Web API以WebHost方式部署时,Asp.Net Web API的路由系统内部是怎样实现的.还是以一个简单实例开 ...
随机推荐
- NOPI导出Excel
NOPI导出Excel /// <summary> /// 导出的方法 Excel样式 /// </summary> /// <param name="ds&q ...
- springmvc结合freemarker,非自定义标签
参考:http://viralpatel.net/blogs/spring-mvc-freemarker-ftl-example/ 上图: 目录层级: 启动后的访问地址:http://localhos ...
- RecyclerView 小记
RecyclerView,是在v7包加入的,一个灵活的view可以展示巨大的数据集,类似于listview的viewholder复用已经优化好了. 语言是苍白的,代码是最生动的叙说: 布局: < ...
- web编程速度大比拼(nodejs go python)(非专业对比)
C10K问题的解决,涌现出一大批新框架,或者新语言,那么问题来了:到底谁最快呢?非专业程序猿来个非专业对比. 比较程序:输出Hello World! 测试程序:siege –c 100 –r 100 ...
- BOM 浏览器对象模型学习
window对象属性 innerWidth/innerHeight 浏览器窗口的内部宽度与高度 outerWidth/outerHeight 浏览器的外部宽度与高度 length window.fra ...
- IOS 特定于设备的开发:获取额外的设备信息
sysctl()和sysctlbyname()允许获取系统信息.这些标准的UNIX函数用于询问操作系统有关硬件和OS的详细信息. 这些常量使你能够检查核心信息,比如系统的CPU频率,可用的内存量等.它 ...
- valgrind用于检测内存泄露
http://www.thegeekstuff.com/2011/11/valgrind-memcheck/
- MySQL 分区表各个分区的行数
分区的信息是记录在information_schema.partitions 这个表里的.它不能直接定位行所在的分区,但它可查到每个分区中有多少行. 例子: select partition_name ...
- 三种客户端访问wcf服务端的方法 C#
原文 http://blog.csdn.net/zlj002/article/details/7914556 string jsonstr = String.Empty; string url = & ...
- yii_CGridView_ajax_pagination_and_ajax_sort
本文主要内容: 1, 正常情况下 CGridView 实现 Ajax 分页和排序的原理 2, 分页和排序无法Ajax的情况分析 3, 自定义分页(重写CLinkPager)后如何实现 Ajax 分页和 ...