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

本文介绍如何在Android应用中结合高德地图API实现天气查询功能。通过获取用户位置的经纬度,进行逆地理编码获取adcode,再调用天气查询API获取未来几天的天气信息,展示在ListView中。同时支持用户输入查询其他城市天气,详细讲解了Android端的代码实现和关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  主要功能:
  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();
             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值