您的位置:首页 > 其它

weather

2015-12-18 19:57 363 查看
对于大多数的Android手机,天气app都是系统必备的,对于预测天气的功能的实现,博主最近也做了研究,其实也不是太复杂,主要用到了网络请求以及数据解析方面的内容。下面就来详细介绍下如何在android中实现天气appj基本功能的开发。

1.网络请求,在android系统中,网络请求主要有两种实现方式,URLConnection和httpClient,这两种方式都可以实现网络请求。

(1).URLConnection,先给出一个例子

<span>	</span>    URL url = new URL(path);
URLConnection conn = url.openConnection();
conn.connect();
InputStream in = conn.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
String list = buffer.readLine();
while (list != null) {
xml += list;
list = buffer.readLine();
}


这里的path就是我们要访问的网址,这样我们就可以将网页上的内容按照字符形式读取下来。存到list这个字符串中。(别忘了还要在注册文件中添加访问网络权限)

(2).httpClient

<span>	</span>    HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(path);
HttpResponse response = client.execute(get);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream reader = response.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(reader));
String list = buffer.readLine();
while (list != null) {
xml += list;
list = buffer.readLine();
}
}


这里的path同样是网络地址,code是服务器给我们返回的一个值,如果是200,就说明访问成功,404就表示客户端异常,505就表示服务器端异常。不过用这种方式请求的话需要导入两个包httpclient和httpcore,这两个包都在studio文件夹的bin目录下,复制到你项目的libs目录下,还要进行导入,File-project structure-app-dependencies-'+'-File dependency,按照顺序然后选中你要导入的包,确认,就可以了。在导入这两个包后可能还要在build-grade目录下加入以下内容

packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
}


我当初在写的时候没有这些内容,结果一直出错,还是在前辈的帮助下,加上以后就神奇般的成功了,(具体原因我也不清楚,还有待研究)。

这样我们就可以访问网络上的资源了。对于免费的天气api,网上有很多,我用的是这个:http://www.k780.com/api/weather.future,很好用,提供的数据也很全面,实时天气,未来5-7天的,PM2.5和空气指数都有提供,我们只需要对需要的数据进行访问然后获取,接下来就是取出我们所需要的数据了,也就是JSON解析。

2.JSON解析

JSON类型数据是很常见的数据类型,它比起XML来方便很多,它是以键值对的形式来存储数据的,所以很常用。解析起来非常容易,实例化一个JSONObject类,读取到网页上的内容,也就是上边的list传进去,即JSONObject json = new JSONObject(list),然后直接调用getString()把你需要的信息的键传进去,就能得到对应的值了,很容易。这就是我们实现天气预报的基本过程。下面是博主的一个小小的例子。

public class MainActivity extends Activity {

private TextView temperature;
private TextView weather;
private TextView aqi;
private TextView humidity;
private TextView degree;
private TextView location;
private Button add;
private Message msg;
public  static Handler handler;
public  static String position = "";
public  static  boolean start = false;
LocationClient locationClient = null;
BDLocationListener myListener = new MyLocationListener();
SwipeRefreshLayout swipeRefreshLayout;
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);

add = (Button) findViewById(R.id.buttonId);
temperature = (TextView) findViewById(R.id.tempId);
weather = (TextView) findViewById(R.id.weatherId);
aqi = (TextView) findViewById(R.id.aqiId);
humidity = (TextView) findViewById(R.id.humidityId);
degree = (TextView) findViewById(R.id.degreeId);
location = (TextView) findViewById(R.id.city);
add.setOnClickListener(new ButtonListener());
handler = new Myhandler();

swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);		<span>	</span>//下拉刷新(系统控件)
swipeRefreshLayout.setColorSchemeColors(android.R.color.background_light);
swipeRefreshLayout.setSize(10);
swipeRefreshLayout.setProgressBackgroundColor(android.R.color.white);
swipeRefreshLayout.setOnRefreshListener(new reFreshListener());
getLocationThread g = new getLocationThread();
thread t = new thread();
Thread T = new Thread(t, "Refresh");
T.start();
}
public static String getURLConnection(String path) {<span style="white-space:pre">			//获取API对应的数据
String xml = "";
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(path);
HttpResponse response = client.execute(get);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream reader = response.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(reader));
String list = buffer.readLine();
while (list != null) {
xml += list;
list = buffer.readLine();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return xml;
}

public class reFreshListener implements SwipeRefreshLayout.OnRefreshListener {<span>				</span>	//下拉刷新监听器

@Override
public void onRefresh() {
thread t = new thread();
Thread T = new Thread(t, "Refresh");
T.start();<span style="white-space:pre">									//下拉时启动线程刷新天气数据
}
}

private class thread implements Runnable {                                                      		<span>	</span>//获取当天天气线程

@Override
public void run() {
String todayXML = "http://api.k780.com:88/?app=weather.today&weaid=";                   			//实时天气API前缀
String aqiXMl = "http://api.k780.com:88/?app=weather.pm25&weaid=";                    		        //空气指数API前缀
String futureXML = "http://api.k780.com:88/?app=weather.future&weaid=";                	         	 //未来天气API前缀
String suffixXML = "&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";<span>			</span>//后缀
String todayWeather = getURLConnection(todayXML + position + suffixXML);
String todayAqi = getURLConnection(aqiXMl + position + suffixXML);
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("todayWeather", todayWeather);
bundle.putString("todayAqi", todayAqi);
msg.setData(bundle);
try {
Thread.sleep(1000);
handler.sendMessage(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class Myhandler extends Handler {                                                        					//接受数据更改UI

public void handleMessage(Message msg) {
swipeRefreshLayout.setRefreshing(false);
String todayWeather = msg.getData().getString("todayWeather");
if (todayWeather != null) {
try {
todayWeather = String.valueOf(new JSONObject(todayWeather).getJSONObject("result"));
JSONObject json = new JSONObject(todayWeather);
location.setText(json.getString("citynm"));
String temp = json.getString("temp_curr");
final float scale = getApplicationContext().getResources().getDisplayMetrics().density;
if (temp.length() == 2) {
temperature.setWidth((int) (84 * scale + 0.5f));
System.out.println((int) (84 * scale + 0.5f));
} else if (temp.length() == 3) {
temperature.setWidth((int) (140 * scale + 0.5f));
}
temperature.setText(temp);
degree.setText("o");
weather.setText(json.getString("weather"));
humidity.setText("湿度" + json.getString("humidity") + " " + json.getString("wind") + json.getString("winp"));
} catch (Exception e) {
e.printStackTrace();
}
}
String todayAqi = msg.getData().getString("todayAqi");
if (todayAqi != null) {
try {
todayAqi = String.valueOf(new JSONObject(todayAqi).getJSONObject("result"));
JSONObject json = new JSONObject(todayAqi);
aqi.setText("空气指数" + json.getString("aqi") + " " + json.getString("aqi_levnm") + "  " + json.getString("aqi_remark"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}


上面就是实现获取实时天气的主要内容,其实很容易,但是要想实现更全面的功能就比较复杂了,本来我还想做一下定位功能,结果由于阅码能力太渣,读不懂大神们的代码,所以暂时没有实现这个功能,后续会跟进。不过关于定位大家可以用百度地图API,http://developer.baidu.com/map/index.php?title=android-locsdk。上面有详细介绍,也可以下载它的Demo来仔细研读。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: