android Application Development - From Design to Implementation of 4-10 Analytical Weather Forecast Data

Posted by ricroma on Mon, 20 May 2019 21:47:37 +0200

Analysis of Weather Forecast Data

After the layout of the interface is completed, it is necessary to design code to control the logic of the elements on the interface.

  1. Obtaining weather forecast data from network;
  2. Analyzing the acquired data;
  3. Update the weather forecast interface according to the analytical results.

Weather forecast data depends on the server on the network, not on the application developers themselves. If the application and network server are developed by two dialers at the same time, it is very likely that the server is not ready when the mobile phone needs to get data.

What should we do in this case?

We can construct a false data by ourselves to simulate the situation where the real data has been obtained. Of course, such false data from format to content should be consistent with the real data provided by the network. The more the two are the same, the simpler the code modification is needed when switching to real data later.

So in actual development projects, application developers and network developers will draw up a data protocol beforehand, and application developers will know how to construct false data when they see this protocol, instead of waiting for the work of network developers. Network developers will also strictly develop according to this protocol, otherwise in the future, the cooperation between the mobile terminal and the network terminal will be chicken and duck.

Let's assume that we've got the weather forecast data on the network, see how to parse the data and update the weather forecast interface.

data format

Nowadays, data exchange between application side (client side) and network side (server side) usually uses two formats of text content: XML and JSON.

For example, the information of a class is obtained through the Internet (assuming that it contains the name, age and gender of the students).

Full name Age Gender
Zhao Yi 15 male
Money two 14 female
Sun San 16 female
Li Si 12 male

* Using XML to convey information, the possible content is:

```xml
<students>
    <student>
        <name>Zhao Yi</name>
        <age>15</age>
        <sex>male</sex>
    </student>

    <student>
        <name>Money two</name>
        <age>14</age>
        <sex>female</sex>
    </student>

    <student>
        <name>Sun San</name>
        <age>16</age>
        <sex>female</sex>
    </student>

    <student>
        <name>Li Si</name>
        <age>12</age>
        <sex>male</sex>
    </student>

</students>
```
Each node`<>`Represents a data.
  • Using JSON to convey information, the possible content is:

    {
        "students":
        [
            {
                "name":"Zhao Yi", 
                "age":"15", 
                "sex":"male"
            },
            {
                "name":"Money two", 
                "age":"14", 
                "sex":"female"
            },
            {
                "name":"Sun San", 
                "age":"16", 
                "sex":"female"
            },
            {
                "name":"Li Si", 
                "age":"12", 
                "sex":"male"
            }
        ]
    }

Compared with JSON, XML takes less space and expresses more concisely in JSON format. So JSON seems to be more popular with developers.

What we use here is data in JSON format.

JSON preliminary

The JSON format is also easy to understand.

  • Data consists of names and values, such as "name" and "Li Si".

    1. They are separated and "enclosed" (values of numerical types can be expanded without quotation marks, such as "age":12, but in order to simplify the rules of everyone's memory, they should be expanded).
    2. It can be followed by [], or {}; different parentheses represent different types of data;
    "name":"Li Si"
    "age":"12"
    "sex":"male"
  • Using {}, it contains different items of the same thing.

    {
        "name":"Li Si",
        "age":"12",
        "sex":"male"
    }
  • Using [], it contains the same kind of things, there will be multiple level data items inside.

    "data":
    [
            {
              "name":"Li Si",
              "age":"12",
              "sex":"male" 
            },
            {
                "name":"Li San",
                "age":"11",
                "sex":"male" 
            },
            {
                "name":"Li Wu",
                "age":"13",
                "sex":"female" 
            }
    ]

Weather data

According to the previous functional planning, we have determined the format of network data, take out a real example to feel it:

{
    "error_code": "0",
    "data": {
        "location": "Chengdu",
        "temperature": "23°",
        "temperature_range": "18℃~23℃",
        "weather_code": "5",
        "wind_direction": "Southeast",
        "wind_level": "1 level",
        "humidity_level": "30%",
        "air_quality": "good",
        "sport_level": "suitable",
        "ultraviolet_ray": "weak",
        "forcast": [
            {
                "date": "Tomorrow",
                "temperature_range": "18℃~23℃",
                "weather_code": "0"
            },
            {
                "date": "Saturday",
                "temperature_range": "17℃~21℃",
                "weather_code": "1"
            },
            {
                "date": "Sunday",
                "temperature_range": "19℃~24℃",
                "weather_code": "3"
            },
            {
                "date": "Monday",
                "temperature_range": "16℃~22℃",
                "weather_code": "4"
            },
            {
                "date": "Tuesday",
                "temperature_range": "20℃~26℃",
                "weather_code": "2"
            }
        ]
    }
}

You can see that the whole data is divided into two parts.

  • error_code: The error code returned by the server on the network side. If the server finds itself having problems, it can tell the client the value of this field. After the client receives the return value, it first checks whether the field is 0. For non-zero values, we need to be alert, which indicates that the value of the data field may be invalid.

    However, you also need to remember that the JSON content returned is negotiated between application developers and network developers, and you can also not design the error_code field. But now we have formed a tacit understanding, most of them regard this field as the standard of JSON data.

  • Data: Carry actual data that we really care about, and all weather-related data is in this field.

Next, we will focus on the data field.

Weather Details Data

Weather details data need to be used as follows.

"location": "Chengdu",
"temperature": "23°",
"temperature_range": "18℃~23℃",
"weather_code": "5",

The value of most data is what we want to display on the interface, which is very simple. For example,

JSON field name JSON field values Interface display
location Chengdu Chengdu
temperature 23° 23°
temperature_range 18℃~23℃ 18℃~23℃

In the weather_code field, the values are values, and different values represent different weather states.

Value Weather condition Apply the corresponding icon to display
0 Fine R.mipmap.ic_sunny_l
1 rain R.mipmap.ic_rainy_l
2 Cloudy R.mipmap.ic_cloudy_l
3 Fog R.mipmap.ic_fog_l
4 Snow R.mipmap.ic_snow_l
5 fine with occasional clouds R.mipmap.ic_sunny_cloudy_l

Weather forecast data

Weather forecast data include five sub-items-five-day weather forecast.

"forcast": [
      {
          "date": "Tomorrow",
          "temperature_range": "18℃~23℃",
          "weather_code": "0"
      },
      {
          "date": "Saturday",
          "temperature_range": "17℃~21℃",
          "weather_code": "1"
      },
      {
          "date": "Sunday",
          "temperature_range": "19℃~24℃",
          "weather_code": "3"
      },
      {
          "date": "Monday",
          "temperature_range": "16℃~22℃",
          "weather_code": "4"
      },
      {
          "date": "Tuesday",
          "temperature_range": "20℃~26℃",
          "weather_code": "2"
      }
]

The value of most data is what we want to display on the interface. For example,

JSON field name JSON field values Interface display
date Monday Monday
temperature_range 16℃~22℃ 16℃~22℃

The weather_code field, which takes values as values, represents different weather conditions. Its understanding is the same as that of weather_code in weather forecast data, but the icon is smaller.

Value Weather condition Apply the corresponding icon to display
0 Fine R.mipmap.ic_sunny_s
1 rain R.mipmap.ic_rainy_s
2 Cloudy R.mipmap.ic_cloudy_s
3 Fog R.mipmap.ic_fog_s
4 Snow R.mipmap.ic_snow_s
5 fine with occasional clouds R.mipmap.ic_sunny_cloudy_s

Weather Index Information

Weather index information needs to be used as follows.

"wind_direction": "Southeast",
"wind_level": "1 level",
"humidity_level": "30%",
"air_quality": "good",
"sport_level": "suitable",
"ultraviolet_ray": "weak"

The value of the data is what we want to display on the interface. For example,

JSON field name JSON field values Interface display Icons used
wind_direction Southeast Southeast R.mipmap.ic_wind_direction
wind_level Level 1 Level 1 R.mipmap.ic_wind_level
humidity_level 30% 30% R.mipmap.ic_humidity_level
air_quality good good R.mipmap.ic_air_quality
sport_level suitable suitable R.mipmap.ic_sport_level
ultraviolet_ray weak weak R.mipmap.ic_ultraviolet_level

Parsing JSON data

Android SDK provides us with very good JSON parsing support. We don't need to write a JSON parser, just take it and use it.

  1. Add JSON false data,

    public class MainActivity extends AppCompatActivity {
    
        private final String FAKE_DATA= "{\n" +
                "    \"error_code\": \"0\",\n" +
                "    \"data\": {\n" +
                "        \"location\": \"Chengdu\",\n" +
                "        \"temperature\": \"23°\",\n" +
                "        \"temperature_range\": \"18℃~23℃\",\n" +
                "        \"weather_code\": \"5\",\n" +
                "        \"wind_direction\": \"Southeast\",\n" +
                "        \"wind_level\": \"1 level\",\n" +
                "        \"humidity_level\": \"30%\",\n" +
                "        \"air_quality\": \"good\",\n" +
                "        \"sport_level\": \"suitable\",\n" +
                "        \"ultraviolet_ray\": \"weak\",\n" +
                "        \"forcast\": [\n" +
                "            {\n" +
                "                \"date\": \"Tomorrow\",\n" +
                "                \"temperature_range\": \"18℃~23℃\",\n" +
                "                \"weather_code\": \"0\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"date\": \"Saturday\",\n" +
                "                \"temperature_range\": \"17℃~21℃\",\n" +
                "                \"weather_code\": \"1\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"date\": \"Sunday\",\n" +
                "                \"temperature_range\": \"19℃~24℃\",\n" +
                "                \"weather_code\": \"3\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"date\": \"Monday\",\n" +
                "                \"temperature_range\": \"16℃~22℃\",\n" +
                "                \"weather_code\": \"4\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"date\": \"Tuesday\",\n" +
                "                \"temperature_range\": \"20℃~26℃\",\n" +
                "                \"weather_code\": \"2\"\n" +
                "            }\n" +
                "        ]\n" +
                "    }\n" +
                "}";
    ......
    }
  2. Delete the false data previously created for weather index information and create a JSON parser in onCreate().

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
    
        try {
            JSONObject weatherResult = new JSONObject(FAKE_DATA);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    Android Studio will prompt you to handle try catch exceptions. If there is a problem in parsing JSON strings while the program is running, we will make further processing by exceptional error reporting.

  3. Parse error_code to determine whether the data is available.

    try {
            JSONObject weatherResult = new JSONObject(FAKE_DATA);
            int errorCode = weatherResult.getInt("error_code");
            if(errorCode == 0) {
    
            }
            else {
    
            }
    } catch (JSONException e) {
       e.printStackTrace();
    }

    Here, getInt("error_code") is used to get the corresponding value of the error field, and the value is parsed into a numerical int type.

Analysis of weather detail data

  1. Get the data structure of the data field by getJSONObject("data");
  2. Through getString (xxxx) and getInt(xxx), the specific contents of location temperature_range weather_code and other fields are obtained.
if(errorCode == 0) {
    JSONObject data = weatherResult.getJSONObject("data");
    String location = data.getString("location");
    String temperature = data.getString("temperature");
    String temperatureRange = data.getString("temperature_range");
    int weatherCode = data.getInt("weather_code");
}

Analysis of Weather Forecast Data

  1. By getJSONArray("forcast"), all the weather forecast sub-items in forcast field are obtained. There are five sub-items in total.

  2. Through getString (xxxx) and getInt(xxx), the contents of date temperature_range weather_code and other fields are obtained.

if(errorCode == 0) {
    ......

    JSONArray forcast = data.getJSONArray("forcast");
    for(int i = 0; i < forcast.length(); i++) {
        JSONObject forcastItem = forcast.getJSONObject(i);
        String date = forcastItem.getString("date");
        String forcastTemperatureRange = forcastItem.getString("temperature_range");
        int forcastWeatherCode = forcastItem.getInt("weather_code");
    }
}

Analysis of Weather Index Data

Get the specific content of wind_direction wind_level humidity_level air_quality sport_level ultraviolet_ray and other fields by getString (xxxx);

if(errorCode == 0) {
    ......

    String windDirection = data.getString("wind_direction");
    String windLevel = data.getString("wind_level");
    String humidityLevel = data.getString("humidity_level");
    String airQuality = data.getString("air_quality");
    String sportLevel = data.getString("sport_level");
    String ultravioletRay = data.getString("ultraviolet_ray");
}

The complete code is as follows.

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

   try {
        JSONObject weatherResult = new JSONObject(FAKE_DATA);
        int errorCode = weatherResult.getInt("error_code");
        if(errorCode == 0) {
            JSONObject data = weatherResult.getJSONObject("data");
            String location = data.getString("location");
            String temperature = data.getString("temperature");
            String temperatureRange = data.getString("temperature_range");
            int weatherCode = data.getInt("weather_code");

            JSONArray forcast = data.getJSONArray("forcast");
            for(int i = 0; i < forcast.length(); i++) {
                JSONObject forcastItem = forcast.getJSONObject(i);
                String date = forcastItem.getString("date");
                String forcastTemperatureRange = forcastItem.getString("temperature_range");
                int forcastWeatherCode = forcastItem.getInt("weather_code");

            }

            String windDirection = data.getString("wind_direction");
            String windLevel = data.getString("wind_level");
            String humidityLevel = data.getString("humidity_level");
            String airQuality = data.getString("air_quality");
            String sportLevel = data.getString("sport_level");
            String ultravioletRay = data.getString("ultraviolet_ray");
        }
        else {

        }
   } catch (JSONException e) {
       e.printStackTrace();
   }
}

About debugging

The parsed data needs to be updated to the interface. But in the process of parsing, we hope to see whether the results of parsing are correct as soon as possible.

Android Studio provides us with two ways to debug code and see the code run to intermediate state: breakpoint debugging and Log debugging.

breakpoint debugging

Breakpoint debugging allows the program to freeze the state of the application when it runs to a certain state, as if time had stopped. Then let's have time to observe one by one whether the parameters of the program at this time meet our expectations.

This debugging method is suitable for time-insensitive programs. That is to say, the debugged program thread does not need to rely on other threads, even if it temporarily stops working, it will not affect other threads or be affected by other threads.

  1. Break in where you want the code to stop running - click before the code and a red dot appears. If you want to cancel, just click again.

  2. Deploy the program in debug run (ctrl+D). When the program runs to the location where the endpoint is set, the program stops and switches to the Debug window. At this point, we can observe the parameters.

    For example, the right half of the figure below lists the values of each variable when it stops; the left side shows how the function went to the call stack (who called the function). We can analyze them one by one and observe them in detail to see if they meet our expectations.

  3. Using Run - > Step Over (or F8) in the menu bar allows the program to execute one step down. If you press it several times, it will be executed several times in turn.

    Here we can see that the weather forecast data we analyzed are all right.

Endpoint debugging has many quick keys, which are worth remembering and can greatly speed up our development efficiency.

Log debugging

For those time-related programs (can't let the program pause, wait for you to observe slowly), we can't use static debugging methods to set breakpoints, we have to use dynamic debugging, add log mode.

Log's Chinese name is Log, which represents the information printed during the program's operation in the programming world. According to log, we can know where the program is running now. Log can also carry the information output of some variables in the program, so that we can more accurately know the current running state of the program.

Add Log to the code

By adding a function to the code, you can output these log s through a special tool. We used it when we started the project.

The way to add log s to Android code is as follows:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d("TEST", "Weather app launched");
}

This uses the Log library provided by Android, which represents information of Debug type.

We add Log information to the weather forecast data.

try {
    Log.d("TEST","start to parse JSON content");

    JSONObject weatherResult = new JSONObject(FAKE_DATA);
    int errorCode = weatherResult.getInt("error_code");
    Log.d("TEST", "error_code = " + errorCode);
    if(errorCode == 0) {
        JSONObject data = weatherResult.getJSONObject("data");
        String location = data.getString("location");
        String temperature = data.getString("temperature");
        String temperatureRange = data.getString("temperature_range");
        int weatherCode = data.getInt("weather_code");

        Log.d("TEST","weather detail info: "+
            " location=" + location +
            " temperature=" + temperature +
            " temperatureRange=" + temperatureRange +
            " weatherCode=" + weatherCode);

        JSONArray forcast = data.getJSONArray("forcast");
        for(int i = 0; i < forcast.length(); i++) {
            JSONObject forcastItem = forcast.getJSONObject(i);
            String date = forcastItem.getString("date");
            String forcastTemperatureRange = forcastItem.getString("temperature_range");
            int forcastWeatherCode = forcastItem.getInt("weather_code");

            Log.d("TEST","weather forcast info: "+
                    " date=" + date +
                    " forcastTemperatureRange=" + forcastTemperatureRange +
                    " forcastWeatherCode=" + forcastWeatherCode);
        }

        String windDirection = data.getString("wind_direction");
        String windLevel = data.getString("wind_level");
        String humidityLevel = data.getString("humidity_level");
        String airQuality = data.getString("air_quality");
        String sportLevel = data.getString("sport_level");
        String ultravioletRay = data.getString("ultraviolet_ray");

        Log.d("TEST","more weather info: "+
            " windDirection=" + windDirection +
            " windLevel=" + windLevel +
            " humidityLevel=" + humidityLevel +
            " airQuality=" + airQuality +
            " sportLevel=" + sportLevel +
            " ultravioletRay=" + ultravioletRay );

        Log.d("TEST","finish to parse JSON content");
    }
    else {
        Log.d("TEST","finish to parse JSON content without parse");
    }
} catch (JSONException e) {
    e.printStackTrace();
    Log.d("TEST","fail to parse JSON content");
}

Log view

After adding log information, the program is deployed to the device through debug app, and the corresponding information can be seen in the logcat window of Android Monitor tool.

As you can see, our analysis of JSON is absolutely correct.

The output debugging information is as follows:

02-10 13:49:29.608 7948-7948/com.anddle.weatherapp D/TEST: error_code = 0

Can you guess what it means?

Field contents Field meaning
02-10 13:49:29.608 Time when log is printed
7948-7948 The thread number at which this code is executed
com.anddle.weatherapp The package name of the program to which this code belongs
D The log is printed by Log.d(). If E is displayed, it is printed by Log.e().
TEST Content of the first parameter in Log.d() function
error_code = 0 Content of the second parameter in Log.d() function

The Log library for Android application development provides several different levels of logs: Verbose Debug Info Warning Error. We can add different levels of logs according to the needs of our logs in the form of:

Log.v("TAG","content is verbose");
Log.d("TAG","content is debug");
Log.i("TAG","content is info");
Log.w("TAG","content is waring");
Log.e("TAG","content is error");

/*******************************************************************/
* Copyright Statement
* This tutorial is only available in CSDN and Ann bean net Published, other websites appear this tutorial is infringement.

* In addition, we have also launched Arduino Intelligent Hardware related tutorials, you can in our online store Learn Arduino programming from me Purchase related hardware. At the same time, thank you for your support to our farmers.

* Finally, I would like to thank you once again for your support to Andou. Thank you:)
/*******************************************************************/

Topics: JSON network Android xml