Android利用高德天气查询API实现天气查询功能

版权声明:原创文章,未经允许,禁止转载! https://blog.csdn.net/weixin_36512652/article/details/85708443
  主要功能:
  1. 登录、注册(需要有Web端):这个很好写,我使用SpringBoot搭建的Web端,配置好Mybatis,编写Dao层、Service层和Controller层就基本完成了。
  2. 首页显示所在地天气信息:通过网络定位获取所在位置的经纬度,然后调用高德的逆地理编码API将经纬度作为参数传入,解析返回结果,获取adcode(行政区编码),再调用高德天气查询API将adcode作为参数传入,解析返回的结果得到今天、明天、后天的天气信息,通过ListVIew将其显示出来。
  3. 查询其他城市天气信息:在输入框中输入要查询的城市、省份等位置信息,点击查询按钮,调用高德的地理编码API将城市名、省份或其他位置作为参数传入,解析返回结果,获取adcode,剩下的操作同上。
  用到的高德API服务:地理/逆地理编码天气查询
  效果图:
  Web端主要代码实现:
  • 负责用户登录和注册的Controller:
@RestController
public class UserController {

    @Autowired
    UserService userService;

    /**
     * 负责Android端登录请求
     *
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
        // 根据用户名和密码查询该用户是否存在
        User user = new User(null, username, password);
        boolean canLogin = userService.checkLogin(user);
        // 若该用户存在返回登录成功信息
        if (canLogin) {
            return "LOGIN_SUCCESS";
        }
        // 若该用户不存在返回登录失败信息
        return "LOGIN_FAIL";
    }

    /**
     * 负责Android端注册请求
     *
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/register")
    public String register(@RequestParam("username") String username, @RequestParam("password") String password) {
        // 查询该用户名是否存在,若存在返回用户已存在信息
        if (userService.checkExistUserName(username)) {
            return "USER_EXIST";
        }

        // 添加用户
        User user = new User(null, username, password);
        boolean canRegister = userService.checkRegister(user);
        // 添加成功返回成功信息
        if (canRegister) {
            return "REG_SUCCESS";
        }
        // 添加失败返回失败信息
        return "REG_FAIL";
    }
}

  Android端主要代码实现:
  • 在manifest文件中声明权限、Service和apikey:(apikey需要在高德控制台申请,创建应用后,点击添加key,选择服务平台,使用定位服务选择Android平台,使用天气查询API服务和地理编码服务选择Web服务,不要弄混)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.youngpain.weatherf">

    <!--用于访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!--用于访问GPS定位-->
    <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
    <!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/weather"
        android:label="@string/app_name"
        android:roundIcon="@drawable/weather"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".activity.Login">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--application标签中声明service组件,每个app拥有自己单独的定位service-->
        <service android:name="com.amap.api.location.APSService" />
        <!--设置apikey-->
        <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="你在高德控制台申请的Android平台服务的apikey" />

        <activity android:name=".activity.ShowWeather" />
        <activity android:name=".activity.SearchWeather" />
        <activity android:name=".activity.Register" />
    </application>
</manifest>
  • 用户登录:
public class Login extends AppCompatActivity {

    //控件
    private EditText nameEdit;
    private EditText pwdEdit;
    private Button loginButton;
    private Button notLoginButton;
    private Button registerButton;
    //定义状态码
    private final int ERROR = 0;
    private final int LOGIN_FAIL = 1;
    private final int LOGIN_SUCCESS = 2;
    //保存用户信息
    private String username;
    private String password;

    //构建Web端登录请求URL
    private final String url = "http://192.168.0.101:8080/user/login";

    //使用OkHttpClient进行网络请求
    private OkHttpClient httpClient = new OkHttpClient();

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case ERROR:
                    //获取Message中的内容
                    String message0 = (String) msg.obj;
                    //Toast弹出错误
                    Toast.makeText(Login.this, message0, Toast.LENGTH_SHORT).show();
                    break;
                case LOGIN_FAIL:
                    //获取Message中的内容
                    String message1 = (String) msg.obj;
                    //Toast弹出登录失败
                    Toast.makeText(Login.this, message1, Toast.LENGTH_SHORT).show();
                    break;
                case LOGIN_SUCCESS:
                    //获取Message中的内容
                    String message2 = (String) msg.obj;
                    //Toast弹出登录成功
                    Toast.makeText(Login.this, message2, Toast.LENGTH_SHORT).show();
                    //登录成功跳转到个人信息页面
                    startActivity(new Intent(Login.this, ShowWeather.class));
                    finish();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //去除标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.login);
        //初始化
        init();
    }

    private void init() {
        //获取控件
        nameEdit = findViewById(R.id.login_et_user);
        pwdEdit = findViewById(R.id.login_et_password);
        loginButton = findViewById(R.id.bt_login);
        //绑定监听事件
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //获取用户名和密码
                username = nameEdit.getText().toString().trim();
                password = pwdEdit.getText().toString().trim();
                if ("".equals(username) || "".equals(password)) {
                    Toast.makeText(Login.this, "用户名或密码不能为空"
                            , Toast.LENGTH_SHORT).show();
                } else {
                    //调用login()方法请求Web端
                    login(username, password);
                }
            }
        });
        notLoginButton = findViewById(R.id.not_login);
        notLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Login.this, ShowWeather.class));
            }
        });
        registerButton = findViewById(R.id.register_user);
        registerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Login.this, Register.class));
            }
        });
    }

    /**
     * 发送登录请求到Web端
     *
     * @param username
     * @param password
     */
    private void login(String username, String password) {
        //创建请求表单
        RequestBody body = new FormBody.Builder()
                .add("username", username)//添加用户名
                .add("password", password)//添加密码
                .build();
        //创建请求
        final Request request = new Request.Builder().url(url).post(body).build();
        //在子线程中获取服务器响应
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = httpClient.newCall(request).execute();
                    //请求成功
                    if (response.isSuccessful()) {
                        String result = response.body().string();

                        Log.i("服务器返回的结果:", result);

                        Message message = Message.obtain();
                        if ("LOGIN_SUCCESS".equals(result)) {
                            message.what = LOGIN_SUCCESS;//设置标志
                            message.obj = "登录成功";//设置内容
                        }
                        if ("LOGIN_FAIL".equals(result)) {
                            message.what = LOGIN_FAIL;//设置标志
                            message.obj = "用户名或密码错误";//设置内容
                        }
                        handler.sendMessage(message);
                    } else {
                        Toast.makeText(Login.this, "服务器无响应", Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    Log.i("Login.java", "服务器异常:" + e.toString());

                    Message message = Message.obtain();
                    message.what = ERROR;
                    message.obj = e.toString();
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

  • 解析天气查询API返回结果用到的Bean:
/**
 * 天气查询API返回结果
 */
public class Weather {
    //值为0或1:1:成功;0:失败
    private String status;//返回状态
    private String count;//返回结果总数目
    private String info;//返回的状态信息
    private String infocode;//返回状态说明,10000代表正确
    private List<Forecasts> forecasts;//预报天气信息数据

   getter/setter方法省略
}
/**
 * 预报天气信息数据
 */
public class Forecasts {
    private String city;//城市名
    private String adcode;//区域编码
    private String province;//省份名
    private String reporttime;//数据发布的时间
    private List<Casts> casts;//预报数据list结构,元素cast,按顺序为当天、第二天、第三天的预报数据

     getter/setter方法省略
}
/**
 * 预报数据list结构,元素cast,按顺序为当天、第二天、第三天的预报数据
 */
public class Casts {
    private String date;
    private String week;
    private String dayweather;
    private String nightweather;
    private String daytemp;
    private String nighttemp;
    private String daywind;
    private String nightwind;
    private String daypower;
    private String nightpower;

  	getter/setter方法省略
}
  • 首页布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/show_city"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:text="蜀山区"
        android:textSize="18sp" />

    <ListView
        android:id="@+id/home_weather"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottom_bar"
        android:layout_below="@+id/show_city"
        android:layout_centerHorizontal="true" />

    <include
        android:id="@+id/bottom_bar"
        layout="@layout/bottombar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />
</RelativeLayout>
  • ListView子项的布局文件,显示天气信息:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/relative_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/show_city">

        <TextView
            android:id="@+id/date"
            android:layout_width="80dp"
            android:layout_height="30dp"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="20dp"
            android:gravity="center"
            android:text="今天"
            android:textColor="#48d1cc"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/day"
            android:layout_width="320dp"
            android:layout_height="30dp"
            android:layout_below="@+id/date"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:text="白天"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/day_weather"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="20dp"
            android:layout_toLeftOf="@+id/center_fill"
            android:gravity="center"
            android:text="小雨"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/center_fill"
            android:layout_width="2dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day"
            android:layout_centerHorizontal="true" />

        <TextView
            android:id="@+id/day_temp"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="20dp"
            android:layout_toRightOf="@+id/center_fill"
            android:gravity="center"
            android:text="11℃"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/day_wind"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day_temp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_toLeftOf="@+id/center_fill"
            android:gravity="center"
            android:text="北风"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/center_fill2"
            android:layout_width="2dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day_weather"
            android:layout_centerHorizontal="true" />

        <TextView
            android:id="@+id/day_power"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day_temp"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/center_fill2"
            android:gravity="center"
            android:text="≤3级"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/night"
            android:layout_width="320dp"
            android:layout_height="30dp"
            android:layout_below="@+id/day_power"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="夜里"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/night_weather"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_toLeftOf="@+id/center_fill3"
            android:gravity="center"
            android:text="中雨"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/center_fill3"
            android:layout_width="2dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night"
            android:layout_centerHorizontal="true" />

        <TextView
            android:id="@+id/night_temp"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/center_fill3"
            android:gravity="center"
            android:text="8℃"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/night_wind"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night_weather"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_toLeftOf="@+id/center_fill4"
            android:gravity="center"
            android:text="西北风"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/center_fill4"
            android:layout_width="2dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night_weather"
            android:layout_centerHorizontal="true" />

        <TextView
            android:id="@+id/night_power"
            android:layout_width="160dp"
            android:layout_height="30dp"
            android:layout_below="@+id/night_temp"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/center_fill4"
            android:gravity="center"
            android:text="≤3级"
            android:textStyle="bold" />
    </RelativeLayout>

</RelativeLayout>
  • 首页定位获取位置并查询该区域的天气信息:
public class ShowWeather extends AppCompatActivity {

    //控件
    private ListView listView;
    private TextView showCity;
    private Button searchBtn;

    //请求的API,详细参考https://lbs.amap.com/api/webservice/guide/api/weatherinfo/
    private String url = "https://restapi.amap.com/v3/weather/weatherInfo?key=你在高德控制台申请的Web服务的key&city=340104&extensions=all&out=json";
    //使用OkHttpClient进行网络请求
    private OkHttpClient httpClient = new OkHttpClient();
    //使用Gson解析json字符串
    private Gson gson = new Gson();
    //存储解析json字符串得到的天气信息
    private List<Map<String, String>> weatherList = new ArrayList<>();
    //保存经纬度
    private String longitude;
    private String latitude;
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = null;
    //声明定位回调监听器
    public AMapLocationListener mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (aMapLocation != null) {
                //错误码为0表示定位成功
                if (aMapLocation.getErrorCode() == 0) {
                    //获取城市信息
                    String city = aMapLocation.getProvince() + aMapLocation.getCity() + aMapLocation.getDistrict();
                    //设置显示
                    showCity.setText(city);
                    //获取经纬度,截取经纬度(不超过6位)
                    longitude = String.valueOf(aMapLocation.getLongitude()).substring(0, 5);
                    latitude = String.valueOf(aMapLocation.getLatitude()).substring(0, 5);
                    Toast.makeText(ShowWeather.this, "经纬度为:" + longitude + "," + latitude, Toast.LENGTH_SHORT).show();
                    //根据经纬度获取adcode
                    getAdcode(longitude + "," + latitude);
                } else {
                    Toast.makeText(ShowWeather.this, "定位失败,ErrCode=" + aMapLocation.getErrorCode(), Toast.LENGTH_SHORT).show();

                    //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
                    Log.i("AmapError", "location Error, ErrCode:"
                            + aMapLocation.getErrorCode() + ", errInfo:"
                            + aMapLocation.getErrorInfo());
                }
            }
        }
    };

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    Toast.makeText(ShowWeather.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    Toast.makeText(ShowWeather.this, "该城市adcode为" + (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    Toast.makeText(ShowWeather.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 3:
                    //创建Adapter
                    final SimpleAdapter simpleAdapter = new SimpleAdapter(ShowWeather.this
                            , weatherList, R.layout.weather_listview_item
                            , new String[]{"date", "day_weather", "day_temp", "day_wind", "day_power"
                            , "night_weather", "night_temp", "night_wind", "night_power"}
                            , new int[]{R.id.date, R.id.day_weather, R.id.day_temp, R.id.day_wind, R.id.day_power
                            , R.id.night_weather, R.id.night_temp, R.id.night_wind, R.id.night_power});
                    //绑定Adapter
                    listView.setAdapter(simpleAdapter);
                    Toast.makeText(ShowWeather.this, (String) msg.obj, Toast.LENGTH_LONG).show();
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //去除标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.show_weather);
        //初始化
        init();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            //如果权限不足提示请求权限
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        } else {
            //如果权限已允许,准备定位
            prepareLocation();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //停止定位
        mLocationClient.stopLocation();
    }

    /**
     * Android6.0申请权限的回调方法
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //如果允许权限则准备定位
            prepareLocation();
        } else {
            Toast.makeText(ShowWeather.this, "请允许应用获取相应的权限", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 定位准备工作
     */
    private void prepareLocation() {
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //设置定位监听
        mLocationClient.setLocationListener(mLocationListener);
        //初始化
        mLocationOption = new AMapLocationClientOption();
        //低功耗定位模式:不会使用GPS和其他传感器,只会使用网络定位(Wi-Fi和基站定位);
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        //使用单次定位,默认为false
        mLocationOption.setOnceLocation(true);
        //设置是否返回地址信息(默认返回地址信息)
        mLocationOption.setNeedAddress(true);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        //设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();
    }

    /**
     * 初始化控件
     */
    private void init() {
        //获取控件
        showCity = findViewById(R.id.show_city);
        listView = findViewById(R.id.home_weather);
        searchBtn = findViewById(R.id.search_btn);
        searchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ShowWeather.this, SearchWeather.class);
                startActivity(intent);
            }
        });
    }

    /**
     * 获取经纬度后,通过逆地理编码API获得该区域的adcode,将其作为天气查询API的参数获得当前位置的天气信息
     *
     * @param location 经纬度信息:经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位
     */
    private void getAdcode(String location) {
        String url = "https://restapi.amap.com/v3/geocode/regeo?key=你在高德控制台申请的Web服务的key&location=" + location;

        final Request request = new Request.Builder().url(url).get().build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = httpClient.newCall(request).execute();
                    //请求成功
                    if (response.isSuccessful()) {
                        String result = response.body().string();

                        Log.i("result", result);

                        //转JsonObject
                        JsonObject object = new JsonParser().parse(result).getAsJsonObject();

                        String adcode = object.get("regeocode").getAsJsonObject()
                                .get("addressComponent").getAsJsonObject().get("adcode").getAsString();

                        Log.i("测试获取adcode", adcode);

                        //请求天气查询
                        getWeather(adcode);

                        Message message = Message.obtain();
                        message.what = 1;
                        message.obj = adcode;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    Log.i("ShowWeather.java", "服务器异常:" + e.toString());

                    Message message = Message.obtain();
                    message.what = 0;
                    message.obj = "服务器异常";
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 通过OkHttp发送网络请求查询天气
     */
    private void getWeather(String adcode) {
        String newUrl = url + "&&city=" + adcode;
        final Request request = new Request.Builder().url(newUrl).get().build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = httpClient.newCall(request).execute();
                    //请求成功
                    if (response.isSuccessful()) {
                        String result = response.body().string();

                        Log.i("服务器返回的结果", result);

                        //使用Gson解析
                        Weather weather = gson.fromJson(result, Weather.class);
                        //获取今天天气信息
                        Casts today = weather.getForecasts().get(0).getCasts().get(0);
                        //添加Map数据到List
                        Map<String, String> map1 = new HashMap<>();
                        map1.put("date", "今天");
                        map1.put("day_weather", today.getDayweather());
                        map1.put("day_temp", today.getDaytemp() + "℃");
                        //如果是“无风向”,直接显示,否则显示“xx风”,提升显示效果
                        if (WeatherUtil.noWindDirection(today.getDaywind())) {
                            map1.put("day_wind", today.getDaywind());
                        } else {
                            map1.put("day_wind", today.getDaywind() + "风");
                        }
                        map1.put("day_power", today.getDaypower() + "级");
                        map1.put("night_weather", today.getNightweather());
                        map1.put("night_temp", today.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(today.getNightwind())) {
                            map1.put("night_wind", today.getNightwind());
                        } else {
                            map1.put("night_wind", today.getNightwind() + "风");
                        }
                        map1.put("night_power", today.getNightpower() + "级");
                        weatherList.add(map1);

                        Log.i("今天", today.toString());

                        //获取明天天气信息
                        Casts tomorrow = weather.getForecasts().get(0).getCasts().get(1);
                        //添加Map数据到List
                        Map<String, String> map2 = new HashMap<>();
                        map2.put("date", "明天");
                        map2.put("day_weather", tomorrow.getDayweather());
                        map2.put("day_temp", tomorrow.getDaytemp() + "℃");
                        if (WeatherUtil.noWindDirection(tomorrow.getDaywind())) {
                            map2.put("day_wind", tomorrow.getDaywind());
                        } else {
                            map2.put("day_wind", tomorrow.getDaywind() + "风");
                        }
                        map2.put("day_power", tomorrow.getDaypower() + "级");
                        map2.put("night_weather", tomorrow.getNightweather());
                        map2.put("night_temp", tomorrow.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(tomorrow.getNightwind())) {
                            map2.put("night_wind", tomorrow.getNightwind());
                        } else {
                            map2.put("night_wind", tomorrow.getNightwind() + "风");
                        }
                        map2.put("night_power", tomorrow.getNightpower() + "级");
                        weatherList.add(map2);

                        Log.i("明天", tomorrow.toString());

                        //获取后天天气信息
                        Casts afterTomorrow = weather.getForecasts().get(0).getCasts().get(2);
                        //添加Map数据到List
                        Map<String, String> map3 = new HashMap<>();
                        map3.put("date", "后天");
                        map3.put("day_weather", afterTomorrow.getDayweather());
                        map3.put("day_temp", afterTomorrow.getDaytemp() + "℃");
                        if (WeatherUtil.noWindDirection(afterTomorrow.getDaywind())) {
                            map3.put("day_wind", afterTomorrow.getDaywind());
                        } else {
                            map3.put("day_wind", afterTomorrow.getDaywind() + "风");
                        }
                        map3.put("day_power", afterTomorrow.getDaypower() + "级");
                        map3.put("night_weather", afterTomorrow.getNightweather());
                        map3.put("night_temp", afterTomorrow.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(afterTomorrow.getNightwind())) {
                            map3.put("night_wind", afterTomorrow.getNightwind());
                        } else {
                            map3.put("night_wind", afterTomorrow.getNightwind() + "风");
                        }
                        map3.put("night_power", afterTomorrow.getNightpower() + "级");
                        weatherList.add(map3);

                        Log.i("后天", afterTomorrow.toString());

                        Message message = Message.obtain();
                        message.what = 3;
                        message.obj = "查询成功";
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    Log.i("ShowWeather.java", "服务器异常:" + e.toString());

                    Message message = Message.obtain();
                    message.what = 2;
                    message.obj = "服务器异常";
                    e.printStackTrace();
                }
            }
        }).start();
    }

}
  • 查询天气的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <RelativeLayout
        android:id="@+id/search_weather_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/edit_city"
            android:layout_width="240dp"
            android:layout_height="40dp"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:hint="输入城市名查询天气"
            android:textSize="16sp" />

        <Button
            android:id="@+id/search_w_btn"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_toRightOf="@+id/edit_city"
            android:background="#8fbc8f"
            android:gravity="center"
            android:text="查询"
            android:textColor="#ffffff" />

    </RelativeLayout>

    <ListView
        android:id="@+id/search_weather"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/search_weather_layout"
        android:layout_centerHorizontal="true" />

</RelativeLayout>
  • 根据输入的位置查询该位置的天气信息;
public class SearchWeather extends AppCompatActivity {
    private EditText edit_city;
    private Button search_btn;
    private ListView listView;

    //请求的API,详细参考https://lbs.amap.com/api/webservice/guide/api/weatherinfo/
    private String url = "https://restapi.amap.com/v3/weather/weatherInfo?key=你在高德控制台申请的Web服务的key&extensions=all&out=json";
    //使用OkHttpClient进行网络请求
    private OkHttpClient httpClient = new OkHttpClient();
    //使用Gson解析json字符串
    private Gson gson = new Gson();

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    Toast.makeText(SearchWeather.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    Toast.makeText(SearchWeather.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    Toast.makeText(SearchWeather.this, "该城市adcode为" + (String) msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 3:
                    List<Map<String, String>> list = (List<Map<String, String>>) msg.obj;
                    //创建Adapter
                    final SimpleAdapter simpleAdapter = new SimpleAdapter(SearchWeather.this
                            , list, R.layout.weather_listview_item
                            , new String[]{"date", "day_weather", "day_temp", "day_wind", "day_power"
                            , "night_weather", "night_temp", "night_wind", "night_power"}
                            , new int[]{R.id.date, R.id.day_weather, R.id.day_temp, R.id.day_wind, R.id.day_power
                            , R.id.night_weather, R.id.night_temp, R.id.night_wind, R.id.night_power});
                    //绑定Adapter
                    listView.setAdapter(simpleAdapter);
                    Toast.makeText(SearchWeather.this, "查询成功", Toast.LENGTH_SHORT).show();
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.search_weather);
        //初始化
        init();
    }

    private void init() {
        edit_city = findViewById(R.id.edit_city);
        search_btn = findViewById(R.id.search_w_btn);
        search_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用方法获取该城市的城市编码
                getAdcode();
            }
        });
        listView = findViewById(R.id.search_weather);
    }

    /**
     * 高德开发平台请求天气查询API中区域编码adcode是必须项,使用高德地理编码服务获取区域编码
     * address:结构化地址信息,规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦
     */
    private void getAdcode() {
        String address = edit_city.getText().toString();
        String url = "https://restapi.amap.com/v3/geocode/geo?key=你在高德控制台申请的Web服务的key&address=" + address;

        final Request request = new Request.Builder().url(url).get().build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = httpClient.newCall(request).execute();
                    //请求成功
                    if (response.isSuccessful()) {
                        String result = response.body().string();

                        Log.i("result", result);

                        //转JsonObject
                        JsonObject object = new JsonParser().parse(result).getAsJsonObject();
                        //转JsonArray
                        JsonArray array = object.get("geocodes").getAsJsonArray();
                        JsonObject info = array.get(0).getAsJsonObject();

                        //获取adcode
                        String adcode = info.get("adcode").getAsString();
                        Log.i("测试获取adcode", adcode);

                        //请求天气查询
                        getWeather(adcode);

                        Message message = Message.obtain();
                        message.what = 2;
                        message.obj = adcode;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    Log.i("SearchMainActivity.java", "服务器异常:" + e.toString());

                    Message message = Message.obtain();
                    message.what = 0;
                    message.obj = "服务器异常";
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 查询天气
     */
    private void getWeather(String adcode) {
        String newUrl = url + "&&city=" + adcode;
        final Request request = new Request.Builder().url(newUrl).get().build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = httpClient.newCall(request).execute();
                    //请求成功
                    if (response.isSuccessful()) {
                        String result = response.body().string();

                        Log.i("服务器返回的结果:", result);

                        //存储解析json字符串得到的天气信息
                        List<Map<String, String>> weatherList = new ArrayList<>();

                        //使用Gson解析
                        Weather weather = gson.fromJson(result, Weather.class);
                        //获取今天天气信息
                        Casts today = weather.getForecasts().get(0).getCasts().get(0);
                        //添加Map数据到List
                        Map<String, String> map1 = new HashMap<>();
                        map1.put("date", "今天");
                        map1.put("day_weather", today.getDayweather());
                        map1.put("day_temp", today.getDaytemp() + "℃");
                        if (WeatherUtil.noWindDirection(today.getDaywind())) {
                            map1.put("day_wind", today.getDaywind());
                        } else {
                            map1.put("day_wind", today.getDaywind() + "风");
                        }
                        map1.put("day_power", today.getDaypower() + "级");
                        map1.put("night_weather", today.getNightweather());
                        map1.put("night_temp", today.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(today.getNightwind())) {
                            map1.put("night_wind", today.getNightwind());
                        } else {
                            map1.put("night_wind", today.getNightwind() + "风");
                        }
                        map1.put("night_power", today.getNightpower() + "级");
                        weatherList.add(map1);

                        //获取明天天气信息
                        Casts tomorrow = weather.getForecasts().get(0).getCasts().get(1);
                        //添加Map数据到List
                        Map<String, String> map2 = new HashMap<>();
                        map2.put("date", "明天");
                        map2.put("day_weather", tomorrow.getDayweather());
                        map2.put("day_temp", tomorrow.getDaytemp() + "℃");
                        if (WeatherUtil.noWindDirection(tomorrow.getDaywind())) {
                            map2.put("day_wind", tomorrow.getDaywind());
                        } else {
                            map2.put("day_wind", tomorrow.getDaywind() + "风");
                        }
                        map2.put("day_power", tomorrow.getDaypower() + "级");
                        map2.put("night_weather", tomorrow.getNightweather());
                        map2.put("night_temp", tomorrow.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(tomorrow.getNightwind())) {
                            map2.put("night_wind", tomorrow.getNightwind());
                        } else {
                            map2.put("night_wind", tomorrow.getNightwind() + "风");
                        }
                        map2.put("night_power", tomorrow.getNightpower() + "级");
                        weatherList.add(map2);

                        //获取后天天气信息
                        Casts afterTomorrow = weather.getForecasts().get(0).getCasts().get(2);
                        //添加Map数据到List
                        Map<String, String> map3 = new HashMap<>();
                        map3.put("date", "后天");
                        map3.put("day_weather", afterTomorrow.getDayweather());
                        map3.put("day_temp", afterTomorrow.getDaytemp() + "℃");
                        if (WeatherUtil.noWindDirection(afterTomorrow.getDaywind())) {
                            map3.put("day_wind", afterTomorrow.getDaywind());
                        } else {
                            map3.put("day_wind", afterTomorrow.getDaywind() + "风");
                        }
                        map3.put("day_power", afterTomorrow.getDaypower() + "级");
                        map3.put("night_weather", afterTomorrow.getNightweather());
                        map3.put("night_temp", afterTomorrow.getNighttemp() + "℃");
                        if (WeatherUtil.noWindDirection(afterTomorrow.getNightwind())) {
                            map3.put("night_wind", afterTomorrow.getNightwind());
                        } else {
                            map3.put("night_wind", afterTomorrow.getNightwind() + "风");
                        }
                        map3.put("night_power", afterTomorrow.getNightpower() + "级");
                        weatherList.add(map3);

                        //将服务器返回数据写入Handler
                        Message message = Message.obtain();
                        message.what = 3;
                        message.obj = weatherList;
                        handler.sendMessage(message);
                        //handler.obtainMessage(1, response).sendToTarget();
                    }
                } catch (Exception e) {
                    Log.i("SearchWeather.java", "服务器异常:" + e.toString());

                    Message message = Message.obtain();
                    message.what = 1;
                    message.obj = e.toString();
                    e.printStackTrace();
                }
            }
        }).start();
    }

}
完整代码:源码

猜你喜欢

转载自blog.csdn.net/weixin_36512652/article/details/85708443