小白一个,项目需要获取一个位置坐标(经纬度)后然后输出天气数据给用户,网上找了很久,大神们都是轻描淡写,感觉没有切中要害,无赖只好自己手敲,小小一个功能硬生生敲了一天,所有实现如下:
声明:本人使用的编译器是IDEA。
一、直接在控制台输出天气
1、首先去百度获取AK密钥,方法自己百度,申请地址:
http://lbsyun.baidu.com/apiconsole/key
2、创建项目后创建包创建类,如下图所示:(数字处为接下来使用方法,粘贴代码时需要去除数字)
public class GetLocation{
1、
2、
3、
4、
5、
}
3、各个方法如下所示:
方法一:主方法,测试使用
public static void main(String[] args) {
weatherDate();
}
方法二:给定坐标值,调用getAdd()方法获得城市的json数据
public static void weatherDate(){
//location是给定的坐标值
String log = "113.22079";
String lat = "28.46718";
//data 通过调用jsonData方法获取的json数据
String data;
data = getAdd(log,lat);
System.out.println(data);
}
方法三:传入坐标数据后获得城市数据的json格式
public static String getAdd(String log, String lat ){
//lat 小 log 大
//参数解释: 纬度,经度 type 001 (100代表道路,010代表POI,001代表门址,111可以同时显示前三项)
String urlString = "http://gc.ditu.aliyun.com/regeocoding?l="+lat+","+log+"&type=010";
String res = "";
try {
URL url = new URL(urlString);
java.net.HttpURLConnection conn = (java.net.HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream(),"UTF-8"));
String line;
while ((line = in.readLine()) != null) {
res += line+"\n";
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(res);
return cityData(res);
}
输出的json格式如下(部分图片):
3、调用cityData方法,进行json数据的解析,获得城市名称,我需要获得的是县城一级的城市的名称,如果有区别,循环数组的时候自己取值,如下:
public static String cityData(String rdata){
JSONObject jsonObject3 = JSONObject.fromObject(rdata);
JSONArray jsonArray3 = JSONArray.fromObject(jsonObject3.getString("addrList"));
JSONObject j_21 = JSONObject.fromObject(jsonArray3.get(0));
String allAdd = j_21.getString("admName");
String arr[] = allAdd.split(",");
System.out.println("省:"+arr[0]+"\n市:"+arr[1]+"\n区:"+arr[2]);
String city=arr[2];
String weatherData = jsonData(city);
return String.valueOf(weatherData(weatherData));//TODO
}
这里面有一个JSONObject,这个需要导入相应的jar包,自己去找,网上也挺多的
4、将城市名称传入jsonData方法,这个方法是根据城市名称获得天气的json数据。
在yourAK处填写你自己的获得的AK
说明:
百度天气支持通过坐标直接获取天气,也就是说上面两步基本可以省略,将这个方法参数改为坐标值,然后再baiduUrl中更改一下请求的方式是通过坐标。
但是这只能获得市一级的天气,因为我是要获得的是县一级的,所以先解析坐标获得城市,然后获得天气。
public static String jsonData(String cityName){
String baiduUrl = null;
StringBuffer strBuf;
try {
//通过浏览器直接访问http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=youAk;
//百度ak申请地址:http://lbsyun.baidu.com/apiconsole/key
//要访问的地址URL,通过URLEncoder.encode()函数对于中文进行转码
baiduUrl = "http://api.map.baidu.com/telematics/v3/weather?location="+ URLEncoder.encode(cityName, "utf-8")+"&output=json&ak=yourAK";
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
strBuf = new StringBuffer();
try{
URL url = new URL(baiduUrl);
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));//转码。
String line = null;
while ((line = reader.readLine()) != null)
strBuf.append(line + " ");
reader.close();
}catch(MalformedURLException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
return strBuf.toString();
}
5、将获得的天气json数据传入weatherData方法中,然后获得自己想要的数据。
public static List<String> weatherData(String cityname){
String date;
String weather;
String wind;
String temperature;
String city;
List <String> weatherDate=new ArrayList<String>();
JSONObject jsonObject = JSONObject.fromObject(cityname);
JSONArray jsonArray = JSONArray.fromObject(jsonObject.getString("results"));
JSONObject j_2 = JSONObject.fromObject(jsonArray.getString(0));
JSONObject jsonObject1 = JSONObject.fromObject(j_2);
city = jsonObject1.getString("currentCity");
System.out.println("city:"+city);
JSONArray jsonArray1 = JSONArray.fromObject(jsonObject1.getString("weather_data"));
for(int i=0;i<jsonArray1.size();i++){
JSONObject j_3 = JSONObject.fromObject(jsonArray1.getString(i));
date = j_3.getString("date");
weather =j_3.getString("weather");
wind =j_3.getString("wind");
temperature = j_3.getString("temperature");
weatherDate.add( "date:"+date+
"\nweather:"+weather+"\nwind:"+wind+"\ntempratrue:"+temperature+"\n\n");
}
return weatherDate;
}
最后打印数据如下图所示