Android-Json数据解析之空气质量检测

作者: SeanMa | 来源:发表于2017-07-18 17:05 被阅读151次

    一、JSON基础

    1.JSON优点:格式简单,占宽带小,多语言支持

    2.JSON缺点:编码必须是Unicode,语法过于严谨

    但也因为JSON语法严谨(如四大基础规则),才能支持多语言

    3.JSON四大基础规则:

    (1)并列数据之间用逗号隔开(",");

    (2)映射用冒号表示(":");

    (3)并列数据集合集合(数组)用"[]"表示;

    (4)映射的集合(对象)"{}"表示;


    二、空气质量检测app开发

    1.开发环境:

    Android Studio 2.1.2(API:18~24)

    空气质量检测API(https://www.juhe.cn/docs/api/id/33)

    jdk1.8.0_91

    2.工程开发:

    (1)搭建工程

    这里写图片描述

    (2)空气质量检测API数据申请

    申请api和key请上网站(https://www.juhe.cn/docs/api/id/33), 申请完之后数据将以JSON的格式返回,而读者要做的就是请求数据和解析数据,就是这么简单。
    这里写图片描述
    返回的数据我只是解析了其中的两个,读者可以根据自己需要解析更多的数据

    (3)返回的JSON格式数据

    {
        "resultcode": "200",
        "reason": "SUCCESSED!",
        "error_code": 0,
        "result": [
            {
                "citynow": {
                    "city": "suzhou",
                    "AQI": "77",
                    "quality": "良",
                    "date": "2014-05-09 14:00"
                },
                "lastTwoWeeks": {
                    "1": {
                        "city": "suzhou",
                        "AQI": "100",
                        "quality": "良",
                        "date": "2014-05-08"
                    },
                    "2": {
                        "city": "suzhou",
                        "AQI": "99",
                        "quality": "良",
                        "date": "2014-05-07"
                    },
                    "3": {
                        "city": "suzhou",
                        "AQI": "77",
                        "quality": "良",
                        "date": "2014-05-06"
                    },
                    "4": {
                        "city": "suzhou",
                        "AQI": "75",
                        "quality": "良",
                        "date": "2014-05-05"
                    },
                    "5": {
                        "city": "suzhou",
                        "AQI": "78",
                        "quality": "良",
                        "date": "2014-05-04"
                    },
                    "6": {
                        "city": "suzhou",
                        "AQI": "84",
                        "quality": "良",
                        "date": "2014-05-03"
                    },
                    "7": {
                        "city": "suzhou",
                        "AQI": "135",
                        "quality": "轻度污染",
                        "date": "2014-05-02"
                    },
                    "8": {
                        "city": "suzhou",
                        "AQI": "126",
                        "quality": "轻度污染",
                        "date": "2014-05-01"
                    },
                    "9": {
                        "city": "suzhou",
                        "AQI": "87",
                        "quality": "良",
                        "date": "2014-04-30"
                    },
                    "10": {
                        "city": "suzhou",
                        "AQI": "97",
                        "quality": "良",
                        "date": "2014-04-29"
                    },
                    "11": {
                        "city": "suzhou",
                        "AQI": "77",
                        "quality": "良",
                        "date": "2014-04-28"
                    },
                    "12": {
                        "city": "suzhou",
                        "AQI": "84",
                        "quality": "良",
                        "date": "2014-04-27"
                    },
                    "13": {
                        "city": "suzhou",
                        "AQI": "45",
                        "quality": "优",
                        "date": "2014-04-26"
                    },
                    "14": {
                        "city": "suzhou",
                        "AQI": "56",
                        "quality": "良",
                        "date": "2014-04-25"
                    },
                    "15": {
                        "city": "suzhou",
                        "AQI": "83",
                        "quality": "良",
                        "date": "2014-04-24"
                    },
                    "16": {
                        "city": "suzhou",
                        "AQI": "95",
                        "quality": "良",
                        "date": "2014-04-23"
                    },
                    "17": {
                        "city": "suzhou",
                        "AQI": "101",
                        "quality": "轻度污染",
                        "date": "2014-04-22"
                    }
                },
                "lastMoniData": {
                    "1": {
                        "city": "上方山",
                        "AQI": "77",
                        "quality": "良",
                        "PM2.5Hour": "46μg/m³",
                        "PM2.5Day": "46μg/m³",
                        "PM10Hour": "104μg/m³",
                        "lat": "31.247222",
                        "lon": "120.561389"
                    },
                    "2": {
                        "city": "南门",
                        "AQI": "112",
                        "quality": "轻度污染",
                        "PM2.5Hour": "84μg/m³",
                        "PM2.5Day": "84μg/m³",
                        "PM10Hour": "—μg/m³",
                        "lat": "31.286389",
                        "lon": "120.6275"
                    },
                    "3": {
                        "city": "彩香",
                        "AQI": "76",
                        "quality": "良",
                        "PM2.5Hour": "46μg/m³",
                        "PM2.5Day": "46μg/m³",
                        "PM10Hour": "101μg/m³",
                        "lat": "31.301944",
                        "lon": "120.590833"
                    },
                    "4": {
                        "city": "轧钢厂",
                        "AQI": "68",
                        "quality": "良",
                        "PM2.5Hour": "41μg/m³",
                        "PM2.5Day": "41μg/m³",
                        "PM10Hour": "85μg/m³",
                        "lat": "31.326389",
                        "lon": "120.595556"
                    },
                    "5": {
                        "city": "吴中区",
                        "AQI": "64",
                        "quality": "良",
                        "PM2.5Hour": "46μg/m³",
                        "PM2.5Day": "46μg/m³",
                        "PM10Hour": "—μg/m³",
                        "lat": "31.270278",
                        "lon": "120.612778"
                    },
                    "6": {
                        "city": "苏州新区",
                        "AQI": "72",
                        "quality": "良",
                        "PM2.5Hour": "46μg/m³",
                        "PM2.5Day": "46μg/m³",
                        "PM10Hour": "93μg/m³",
                        "lat": "31.299444",
                        "lon": "120.543333"
                    },
                    "7": {
                        "city": "苏州工业园区",
                        "AQI": "82",
                        "quality": "良",
                        "PM2.5Hour": "60μg/m³",
                        "PM2.5Day": "60μg/m³",
                        "PM10Hour": "88μg/m³",
                        "lat": "31.309722",
                        "lon": "120.669167"
                    }
                }
            }
        ]
    }
    

    读者谨记:在JSON中,"[ ]"指的是数组(集合),"{ }"指的是对象

    (3)代码编写

    activity_main.xml如下所示
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.administrator.whetherreporter.MainActivity">
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
    
                android:text="@string/cityName"
                android:textSize="25sp" />
    
            <EditText
                android:id="@+id/cityName"
                android:layout_width="297dp"
                android:layout_height="wrap_content" />
        </LinearLayout>
    
        <Button
            android:id="@+id/submit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/submit"
            android:textSize="25sp" />
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/show"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textColor="#000"
                android:textSize="18sp" />
        </ScrollView>
    </LinearLayout>
    
    

    界面比较丑,读者可以根据自己需要修改界面,其实认真写好界面,不失为一款好的应用

    strings.xml如下所示
    <resources>
        <string name="cityName">城市:</string>
        <string name="submit">提交</string>
        <string name="app_name"></string>
        <string name="city">城市</string>
        <string name="AQI">空气质量指数</string>
        <string name="quality">空气质量</string>
        <string name="time">更新时间</string>
        <string name="loc">地点</string>
        <string name="PM2.5Hour">PM2.5Hour</string>
        <string name="PM2.5Day">PM2.5Day</string>
        <string name="PM10">PM10Hour</string>
        <string name="lat">维度</string>
        <string name="lon">经度</string>
    </resources>
    
    MainActivity.java 如下所示
    package com.example.administrator.whetherreporter;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    /**
     * Created by Sean on 2016/8/11.
     */
    
    public class MainActivity extends AppCompatActivity {
        private EditText et_cityName;
        private Button btn_submit;
        private TextView tv_show;
        private Task task;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            et_cityName= (EditText) findViewById(R.id.cityName);
            btn_submit= (Button) findViewById(R.id.submit);
            tv_show= (TextView) findViewById(R.id.show);
            btn_submit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String cityName=et_cityName.getText().toString();
                    if (cityName.length()<1){
                        Toast.makeText(MainActivity.this,
                                "请输入城市的名字",Toast.LENGTH_SHORT).show();
                        return;
                    }
                    else {
                        //开启多线程,一般将比较耗时的操作交给另一条线程
                        task=new Task(MainActivity.this,tv_show);  
                        task.execute(cityName);
                    }
                }
            });
        }
    }
    
    
    Taks.java 如下所示
    package com.example.administrator.whetherreporter;
    
    import android.content.Context;
    import android.os.AsyncTask;
    import android.widget.TextView;
    import android.widget.Toast;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    
    /**
     * Created by Sean on 2016/8/11.
     */
    
    public class Task extends AsyncTask<String, Void, String> {
        private TextView tv_show;
        private Context context;
        //获取的API接口
        private static final String url = "http://web.juhe.cn:8080/environment/air/cityair";
        //获取的API的key
        private static final String key = "8118a1d36116d6e89f543163055d7530";
    
        public Task(Context context, TextView tv_show) {
            this.context = context;
            this.tv_show = tv_show;
        }
    
        /***
         *
         * 通过API请求数据
         * @param strings :从主线程中执行子线程传入的字符串,即cityName
         * @return        :请求API之后返回的JSON格式数据
         */
        @Override
        protected String doInBackground(String... strings) {
            String city = strings[0];
            ArrayList<NameValuePair> firstList = new ArrayList<NameValuePair>();
            //设置访问文本类型
            firstList.add(new BasicNameValuePair("Content-Type", "text/html,charset=utf-8"));
    
            String targetUrl = url;
            //请求的参数
            ArrayList<NameValuePair> paramsList = new ArrayList<NameValuePair>();
            paramsList.add(new BasicNameValuePair("city", city));
            paramsList.add(new BasicNameValuePair("key", key));
    
            for (int i = 0; i < paramsList.size(); i++) {
                NameValuePair nowPair = paramsList.get(i);
                String value = nowPair.getValue();
                try {
                    value = URLEncoder.encode(value, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                if (i == 0) {
                    targetUrl += ("?" + nowPair.getName() + "=" + value);
                } else {
                    targetUrl += ("&" + nowPair.getName() + "=" + value);
                }
            }
            //以Get的形式访问
            HttpGet httpGet = new HttpGet(targetUrl);
            try {
                for (int i = 0; i < firstList.size(); i++) {
                        httpGet.addHeader(firstList.get(i).getName(),       firstList.get(i).getValue());
                }
    
                HttpClient httpClient = new DefaultHttpClient();
    
                HttpResponse httpResponse = httpClient.execute(httpGet);
                if (httpResponse.getStatusLine().getStatusCode()==200){
                    String result= EntityUtils.toString(httpResponse.getEntity());
                    return result;
                }
                else
                    return null;
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
            return null;
        }
    
        /***
         *
         * 解析返回的数据
         * @param s   :请求之后返回的数据
         */
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (s!=null){
                try {
                    JSONObject jsonObject=new JSONObject(s);
                    int resultCode=jsonObject.getInt("resultcode");
                    if (resultCode==200){
                        JSONArray resultArray=jsonObject.getJSONArray("result");
                        JSONObject resultJsonObject = resultArray.getJSONObject(0);
                        JSONObject A= (JSONObject) resultJsonObject.get("citynow");
                        JSONObject B= (JSONObject) resultJsonObject.get("lastMoniData");
    
                        String division="---------------------------------------------";
                        
                        String output=
                                 context.getString(R.string.city)+":"+A.optString("city")+"\n"
                                +context.getString(R.string.AQI)+":"+A.optString("AQI")+"\n"
                                +context.getString(R.string.quality)+":"+A.optString("quality")+"\n"
                                +context.getString(R.string.time)+":"+A.optString("date")+"\n"
                                +division+"\n"
                                +"监测点数据"+"\n";
                        for (int i=0;i<B.length();i++) {
                            int w=i+1;
                            String n=Integer.toString(w);
                            JSONObject C= (JSONObject) B.get(n);
                            output=output
                                    + context.getString(R.string.loc) + ":" + C.optString("city") + "\n"
                                    + context.getString(R.string.AQI) + ":" + C.optString("AQI") + "\n"
                                    + context.getString(R.string.quality) + ":" + C.optString("quality") + "\n"
                                    + context.getString(R.string.PM10) + ":" + C.optString("PM10Hour") + "\n"
                                    + context.getString(R.string.PM2_5Hour) + ":" + C.optString("PM2.5Hour") + "\n"
                                    + context.getString(R.string.PM2_5Day) + ":" + C.optString("PM2.5Day") + "\n"
                                    + context.getString(R.string.lat) + ":" + C.optString("lat") + "\n"
                                    + context.getString(R.string.lon) + ":" + C.optString("lon") + "\n";
                        }
                        tv_show.setText(output);
                    }
                    else if (resultCode==202){
                        String reason=jsonObject.getString("reason");
                        tv_show.setText(reason);
                    }
                    else{
                        Toast.makeText(context, "查询失败",
                                Toast.LENGTH_LONG).show();
                        tv_show.setText("");
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
    
            }
            else {
                Toast.makeText(context, "查询失败",
                        Toast.LENGTH_LONG).show();
                tv_show.setText("");
            }
        }
    }
    

    *注意:类NameValuePair在Android API22的是后就已经过时了,可以用到类ContentValue来代替,使用方式如下图所示 *


    这里写图片描述

    HttpGet 和 HttpClient 需要读者自己导入第三方包

    这里写图片描述

    三、测试

    这里写图片描述
    这里写图片描述

    由于API本身的局限性,所以有些地方数据可能有问题,请包涵!


    That's all , 感谢您的阅读,之后我会将我的项目发布到GitHub。

    请大家尊重原创者版权,转载请标明出处 http://blog.csdn.net/AAAAA_Sean_M/article/details/52183277

    参考:http://blog.csdn.net/hantangsongming/article/details/42234293

    相关文章

      网友评论

        本文标题:Android-Json数据解析之空气质量检测

        本文链接:https://www.haomeiwen.com/subject/ueuhkxtx.html