Android中基于心知天气API获取天气信息


为什么要写这篇博客,主要是为了巩固一下JSON的知识,所以大家会看到很多偏文字的讲解,当然最后的代码我会贴出来,这点不必担心,如果不想看讲解可以直接跳到实现部分,也可以直接下载源码, 免费的.

JSON

JSON简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 说人话就是“JSON是一种是有一定顺序的数组/对象”。

JSON对象

JSON对象特征就是多个属性是被 {} 括起来的,下面这就是一个JSON对象。
{
“area”: “北京海淀”,
“name”: “李大嘴”,
“age”: 25
}

JSON数组

JSON 数组其实就是包含了多个 JSON 对象的一个集合,数组是以数组括号 [ ] 括起来的,可以看到这个JSON数组是由相同的JSON对象组成。咱们可以把它称为典型的JSON数组
[{
“area”: “广东”,
“name”: “山鸡哥”,
“age”: 25
}, {
“area”: “广西”,
“name”: “布布”,
“age”: 26
}]
有典型的JSON数组,肯定也有非典型的JSON数组
[{
“area”: “江苏”,
“name”: “徐州”,
“age”: 25
}, {
“city”: “江苏”,
“weather”: “晴”,
}]

JSON解析

JSON解析的方式有挺多的,官方提供的是JSONObect解析,谷歌的开源库GSON,还有一些第三方的开源库比如:Jackson,FastJSON。我这里选择的是官方提供的JSONObject进行解析。具体的实现在后面的实现部分会细讲。

Android中获取天气

获取天气的流程

1:找到一个免费的天气API(心知天气)
2:访问API(需要API Key),得到JSON数据
3:解析JSON数据得到天气信息

获取心知天气的API key

登录心知天气官网,当然你需要先进行注册,登录之后如下图所示在这里插入图片描述
登录之后点击右上角的控制台,如下图所示
在这里插入图片描述
选择产品管理下的添加产品,选择免费版,当然你如果有钱选择开发版或者企业版也是可以的。然后回到产品界面,可以看到我们获取的公钥,私钥非常重要但是我们用不上,一个公钥就够了,我是闲着没事又添加了一个密钥。在这里插入图片描述

获取心知天气的API

点击API文档,可以查看心知天气的API示例和说明,我这里直接截图下来。第一行就是API的示例,下面的API示例中的参数说明,应该不需要我多解释吧,注意KEY后面填写的就是我们获取的API公钥
在这里插入图片描述
那我们先访问下这个API示例,你可以在浏览器的搜索框中输入上图中的示例,看看能得到什么东西呢
在这里插入图片描述
这是什么?这不就是JSON数据吗?我们大致可以看出里面包含着城市,天气,语言等等的信息,我们的任务要便是将这个JSON数据解析出来,变成到正常人能看懂的信息方式。

代码部分

我们要使用OKhttp访问该API,所以要添加OKhttp闭包,在build.Gradle的dependencies{}中添加如下代码,添加后记得同步Gradle文件

 implementation 'com.squareup.okhttp3:okhttp:3.4.1'

AndroidMainfest.xml
添加一行权限(申请网络权限)

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<Button
    android:id="@+id/send_request"
    android:text="Send_request"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
    <TextView
        android:hint="原始JSON数据"
        android:id="@+id/response"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
  <EditText
      android:hint="city"
      android:id="@+id/City"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>
    <EditText
        android:hint="weather"
        android:id="@+id/Weather"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <EditText
        android:hint="temperature"
        android:id="@+id/Temperature"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

MainActivity.xml

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView responseText;
    private EditText weather;
    private EditText city;
    private EditText temperature;
    private String Weather;
    private String CityName;
    private String Tempeature;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button sendRequest = (Button) findViewById(R.id.send_request);
        responseText = (TextView) findViewById(R.id.response);
        weather = (EditText) findViewById(R.id.Weather);
        city = (EditText) findViewById(R.id.City);
        temperature = (EditText) findViewById(R.id.Temperature);
        sendRequest.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.send_request) {
            sendRequestWithOkHttp();
        }
    }

    private void sendRequestWithOkHttp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();//创建一个OkHttp实例
                    Request request = new Request.Builder().url("https://api.seniverse.com/v3/weather/now.json?key=SrvH71t8JeTOXNLJP&location=beijing&language=zh-Hans&unit=c").build();//创建Request对象发起请求,记得替换成你自己的key
                    Response response = client.newCall(request).execute();//创建call对象并调用execute获取返回的数据
                    String responseData = response.body().string();
                    showResPonse(responseData);//显示原始数据和解析后的数据
                    parseJSONWithJSONObject(responseData);//解析SSON数据
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void parseJSONWithJSONObject(String jsonData) {//用JSONObect解析JSON数据
        try {
            JSONObject jsonObject = new JSONObject(jsonData);  
            JSONArray results = jsonObject.getJSONArray("results");   //得到键为results的JSONArray
            JSONObject now = results.getJSONObject(0).getJSONObject("now");//得到键值为"now"的JSONObject
            JSONObject location = results.getJSONObject(0).getJSONObject("location");   //得到键值为location的JSONObject
            Weather = now.getString("text");//得到"now"键值的JSONObject下的"text"属性,即天气信息
            CityName = location.getString("name");  //获得城市名
            Tempeature = now.getString("temperature"); //获取温度
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void showResPonse(final String response) {
        runOnUiThread(new Runnable() {//切换到主线程,ui界面的更改不能出现在子线程,否则app会崩溃
            @Override
            public void run() {
                responseText.setText(response);
                city.setText(CityName);
                weather.setText(Weather);
                temperature.setText(Tempeature);
            }
        });
    }
}

实现的效果如下

我只解析了其中的天气,温度和城市三个信息,其他的硬套应该不难,

进阶-获取任意城市的天气信息

如果我想获得任意一个城市的天气,应该如何实现呢?其实很简单,只要把API的地址中location的值改成可以输入的值即可.重复代码太多我就不想多写了,我会把源码一并上传,可供大家参考.实现效果如下。

  • 11
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用Android Studio和心知天气API创建天气预报应用的步骤: 1. 在Android Studio创建一个新的项目。 2. 在项目的build.gradle文件添加以下依赖项: ```groovy implementation 'com.android.volley:volley:1.2.0' implementation 'com.google.code.gson:gson:2.8.7' ``` 3. 在AndroidManifest.xml文件添加以下权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 4. 创建一个新的Java类,命名为Weather.java,用于存储天气信息的数据模型。 ```java public class Weather { private String city; private String temperature; private String weather; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getTemperature() { return temperature; } public void setTemperature(String temperature) { this.temperature = temperature; } public String getWeather() { return weather; } public void setWeather(String weather) { this.weather = weather; } } ``` 5. 创建一个新的Java类,命名为WeatherRequest.java,用于发送天气请求并解析JSON响应。 ```java public class WeatherRequest { private static final String API_KEY = "YOUR_API_KEY"; private static final String BASE_URL = "https://api.seniverse.com/v3/weather/now.json"; public interface WeatherCallback { void onSuccess(Weather weather); void onError(String message); } public static void getWeather(String city, WeatherCallback callback) { String url = BASE_URL + "?key=" + API_KEY + "&location=" + city; JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, response -> { try { JSONObject result = response.getJSONObject("results").getJSONArray("now").getJSONObject(0); Weather weather = new Weather(); weather.setCity(result.getString("location")); weather.setTemperature(result.getString("temperature")); weather.setWeather(result.getString("text")); callback.onSuccess(weather); } catch (JSONException e) { callback.onError("Failed to parse JSON response"); } }, error -> callback.onError("Failed to make weather request")); RequestQueue queue = Volley.newRequestQueue(context); queue.add(request); } } ``` 6. 在MainActivity.java,添加以下代码来获取天气信息并更新UI: ```java public class MainActivity extends AppCompatActivity { private TextView cityTextView; private TextView temperatureTextView; private TextView weatherTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); cityTextView = findViewById(R.id.cityTextView); temperatureTextView = findViewById(R.id.temperatureTextView); weatherTextView = findViewById(R.id.weatherTextView); WeatherRequest.getWeather("YOUR_CITY", new WeatherRequest.WeatherCallback() { @Override public void onSuccess(Weather weather) { runOnUiThread(() -> { cityTextView.setText(weather.getCity()); temperatureTextView.setText(weather.getTemperature()); weatherTextView.setText(weather.getWeather()); }); } @Override public void onError(String message) { runOnUiThread(() -> Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show()); } }); } } ``` 请注意,将"YOUR_API_KEY"替换为您在心知天气网站上获取API密钥,并将"YOUR_CITY"替换为您想要获取天气信息的城市。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值