前言
最近有需要做一个获取天气的功能,比较之下选择了较为方便的和风天气。但是最新的和风天气接口的返回数据的格式发生变化,所以网上很多教程都不再适用。而一些比较新的教程对于接口中的属性的使用也没有详细的说明,于是打算自己写一个,也算方便后来人。
本文适合2019最新和风天气的接口获取与返回Json格式的处理。以下内容为真机调试,在虚拟机上获取位置会报错。
效果图
正文
首先登陆和风天气控制台:https://console.heweather.com/app/index
如果没有账号的小伙伴请先注册一个账号,已有账号的小伙伴则创建一个新应用(点击左侧应用管理,右侧新建应用)
此时的界面应该是这样的:
此处的PackageName则是你创建应用中AndroidMainfeist.xml
完成后会得到
这里的Username和Key与你的包名绑定,即下文代码中我所注释的,需要填入你自己的username与key的地方。否则就会报{"status":"bad bind"}的错。
接着就下载最新的jar包:
https://dev.heweather.com/docs/sdk/android
在AndroidStudio的左上方选择Project结构,将下载好的jar包复制粘贴到libs目录下。
右击粘贴后的jar包,选择下方的Add As Library,等待下载资源文件。然后点击左上方选择Android结构。
在Manifest.xml文件中设置权限,Android 6.0以上要动态添加权限
在这里我们在手机系统中设置允许应用获取位置权限就好了
在build.gradle文件下的dependencies中添加引用库,点击右上方Sync Now等待引入。
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="location"
android:textSize="18sp" />
<TextView
android:id="@+id/weather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="city"
android:textSize="18sp" />
<TextView
android:id="@+id/temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tempeture"
android:textSize="20sp" />
<TextView
android:id="@+id/suggestion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Suggestion"
android:textSize="15sp" />
</LinearLayout>
主要代码如下:
package com.example.myweather;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import androidx.appcompat.app.AppCompatActivity;
import interfaces.heweather.com.interfacesmodule.bean.weather.lifestyle.Lifestyle;
import interfaces.heweather.com.interfacesmodule.bean.weather.now.Now;
import interfaces.heweather.com.interfacesmodule.view.HeConfig;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
/**
* @Description:
* @Author: chenciu
* @Time: 2019/10/24
*/
public class MainActivity extends AppCompatActivity {
String TAG = "Test";
TextView tv_weather, tv_location, tv_temperature, tv_suggestion;
String cityID = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//此处分别输入你申请的Username与Key
HeConfig.init("HE1910222249591768", "3d5dec0fe50e411694fa015423231988");
//个人开发者需要切换到免费服务域名,默认使用中国付费节点服务域名会报错
HeConfig.switchToFreeServerNode();
tv_weather = (TextView) findViewById(R.id.weather);
tv_location = (TextView) findViewById(R.id.location);
tv_temperature = (TextView) findViewById(R.id.temperature);
tv_suggestion = (TextView) findViewById(R.id.suggestion);
}
@Override
protected void onStart() {
super.onStart();
getWether();
}
private void getWether() {
/**
* 实况天气
* 实况天气即为当前时间点的天气状况
* @param context 上下文
* @param listener 网络访问回调接口
* 通过getWeatherNow和监听器OnResultWeatherNowBeanListener来监听返回的数据
*/
HeWeather.getWeatherNow(MainActivity.this, new HeWeather.OnResultWeatherNowBeanListener() {
public static final String TAG = "HeWeather_getWeatherNow";
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError:", e);
System.out.println("Weather Now Error:" + new Gson());
}
@Override
public void onSuccess(Now dataObject) {
Log.i(TAG, " Weather Now onSuccess:" + new Gson().toJson(dataObject));
String weather = null, temperature = null, city = null, district = null, cid = null;
if (dataObject.getStatus().equals("ok")) {
String JsonNow = new Gson().toJson(dataObject.getNow());
String JsonBasic = new Gson().toJson(dataObject.getBasic());
JSONObject jsonObject = null;
JSONObject jsonObject1 = null;
try {
jsonObject = new JSONObject(JsonNow);
jsonObject1 = new JSONObject(JsonBasic);
city = jsonObject1.getString("parent_city");
district = jsonObject1.getString("location");
cid = jsonObject1.getString("cid");
weather = jsonObject.getString("cond_txt");
temperature = jsonObject.getString("tmp");
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "Mistakes...", Toast.LENGTH_SHORT).show();
return;
}
String temperature2 = temperature + "℃";
String city2 = city + "市 " + district;
cityID = cid;
tv_location.setText(city2);
tv_weather.setText(weather);
tv_temperature.setText(temperature2);
/**
* 生活指数
* 在这里只显示生活指数中的运动指数
* @param context 上下文
* @param listener 网络访问回调接口
*/
HeWeather.getWeatherLifeStyle(MainActivity.this, new HeWeather.OnResultWeatherLifeStyleBeanListener() {
public static final String TAG2 = "HeWeather_getSuggesion";
@Override
public void onError(Throwable throwable) {
Log.i(TAG2, "ERROR IS:", throwable);
}
@Override
public void onSuccess(Lifestyle lifestyle) {
Log.i(TAG2, "LifeStyle onSuccess:" + new Gson().toJson(lifestyle));
String sport = null;
String suggestion = null;
if (lifestyle.getStatus().equals("ok")) {
String JsonLifestyle = new Gson().toJson(lifestyle.getLifestyle());
JSONObject jsonObject = null;
try {
JSONArray jsonArray = new JSONArray(JsonLifestyle);
sport = jsonArray.getString(3);
jsonObject = new JSONObject(sport);
suggestion = jsonObject.getString("txt");
tv_suggestion.setText(suggestion);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "Mistakes...", Toast.LENGTH_SHORT).show();
return;
}
}
});
}
});
}
}
在代码中调用了getWeatherNow和getWeatherLifeStyle两个接口,分别展示不同格式json数据的处理方法。
getWeatherNow获取到的数据:
{
"now": {
"cloud": "91",
"cond_code": "101",
"cond_txt": "多云",
"fl": "28",
"hum": "58",
"pcpn": "0.0",
"pres": "1008",
"tmp": "27",
"vis": "16",
"wind_deg": "85",
"wind_dir": "东风",
"wind_sc": "2",
"wind_spd": "6"
},
"basic": {
"admin_area": "广东",
"cid": "CN101280604",
"cnty": "中国",
"lat": "22.53122139",
"location": "南山",
"lon": "113.9294281",
"parent_city": "深圳",
"tz": "+8.00"
},
"status": "ok",
"update": {
"loc": "2019-10-24 11:51",
"utc": "2019-10-24 03:51"
}
}
getWeatherLifeStyle获取到的数据:
{
"lifestyle": [{
"brf": "舒适",
"txt": "白天不太热也不太冷,风力不大,相信您在这样的天气条件下,应会感到比较清爽和舒适。",
"type": "comf"
}, {
"brf": "热",
"txt": "天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。",
"type": "drsg"
}, {
"brf": "少发",
"txt": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。",
"type": "flu"
}, {
"brf": "较适宜",
"txt": "天气较好,较适宜进行各种运动,但因天气热,请适当减少运动时间,降低运动强度。",
"type": "sport"
}, {
"brf": "适宜",
"txt": "天气较好,但丝毫不会影响您出行的心情。温度适宜又有微风相伴,适宜旅游。",
"type": "trav"
}, {
"brf": "弱",
"txt": "紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。",
"type": "uv"
}, {
"brf": "适宜",
"txt": "适宜洗车,未来持续两天无雨天气较好,适合擦洗汽车,蓝天白云、风和日丽将伴您的车子连日洁净。",
"type": "cw"
}, {
"brf": "中",
"txt": "气象条件对空气污染物稀释、扩散和清除无明显影响。",
"type": "air"
}],
"basic": {
"admin_area": "广东",
"cid": "CN101280604",
"cnty": "中国",
"lat": "22.53122139",
"location": "南山",
"lon": "113.9294281",
"parent_city": "深圳",
"tz": "+8.00"
},
"status": "ok",
"update": {
"loc": "2019-10-24 10:55",
"utc": "2019-10-24 02:55"
}
}
建议对照官方文档的实体类属性来比较代码中不同返回Json格式的处理方法
https://dev.heweather.com/docs/sdk/android-entity
至此,接入和风天气SDK已经全部完成。有什么疑问可以评论留言。