[JAVA] Asynchronous processing and Web API integration in Android Studio

While looking at the technical book, create an application that acquires weather information using the API.

activity_main.xml


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

    <!--View city list-->
    <ListView
        android:id="@+id/lvCityList"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5" />

    <!--Layout of the lower half of the screen displaying weather information-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="10dp"
        android:layout_weight="0.5"
        android:orientation="vertical">

        <!--Display "Weather details"-->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:gravity="center"
            android:text="@string/tv_winfo_title"
            android:textSize="25dp"
            />

        <!--Layout to arrange city names and weather side by side-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:orientation="horizontal">

            <!--Display of city name-->
            <TextView
                android:id="@+id/tvCityName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp"/>

            <!--Show the weather-->
            <TextView
                android:id="@+id/tvWeatherTelop"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:textSize="20sp"/>
        </LinearLayout>

        <!--Screen parts that allow the detailed weather information to be scrolled-->
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <!--View detailed weather information-->
            <TextView
                android:id="@+id/tvWeatherDesc"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textSize="15dp"/>
        </ScrollView>
    </LinearLayout>
</LinearLayout>

AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.asyncsample">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

strings.xml


<resources>
    <string name="app_name">Weather information</string>
    <string name="tv_winfo_title">Weather details</string>

</resources>

MainActivity.java


package com.example.asyncsample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

//Get screen part ListView
        ListView lvCityList = findViewById(R.id.lvCityList);
//Prepare List object to be used in SimpleAdapter
        List<Map<String, String>> cityList = new ArrayList<>();
//Preparation of Map object to store city data and data registration to cityList
        Map<String, String> city = new HashMap<>();
        city.put("name", "Osaka");
        city.put("id", "270000");
        cityList.add(city);
        city = new HashMap<>();
        city.put("name", "Kobe");
        city.put("id", "280010");
        cityList.add(city);

//Used with SimpleAdapter from-Preparation of variables for to
        String[] from = {"name"};
        int[] to = {android.R.id.text1};
//Set SimpleAdapter
        SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, cityList, android.R.layout.simple_expandable_list_item_1, from, to);
//Set SimpleAdapter in ListView
        lvCityList.setAdapter(adapter);
//Set listener on ListView
        lvCityList.setOnItemClickListener(new ListItemClickListener());
    }

//A member class that describes the processing when a list is selected
    private class ListItemClickListener implements AdapterView.OnItemClickListener{
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id){
//Get the city name and city ID of the row tapped in ListView
            Map<String, String> item = (Map<String, String>) parent.getItemAtPosition(position);
            String cityName = item.get("name");
            String cityId = item.get("id");
//Set the acquired city name to tvCityName
            TextView tvCityName = findViewById(R.id.tvCityName);
            tvCityName.setText(cityName + "Weather:");
//Get TextView to display weather information
            TextView tvWeatherTelop = findViewById(R.id.tvWeatherTelop);
//Get TextView to display detailed weather information
            TextView tvWeatherDesc = findViewById(R.id.tvWeatherDesc);
//WeatherInfoReceiver new. Pass the TextView obtained above as an argument.
            WeatherInfoReceiver receiver = new WeatherInfoReceiver(tvWeatherTelop, tvWeatherDesc);
//Run WeatherInfoReceiver
            receiver.execute(cityId);
        }
    }

    private class WeatherInfoReceiver extends AsyncTask<String, String, String> {
//Screen part field to display the current weather
        private TextView _tvWeatherTelop;

//Screen part field to display weather details
        private TextView _tvWeatherDesc;

//constructor
//The screen parts that display the weather information are acquired in advance and stored in the field.
        public WeatherInfoReceiver(TextView tvWeatherTelop, TextView tvWeatherDesc){
            _tvWeatherTelop = tvWeatherTelop;
            _tvWeatherDesc = tvWeatherDesc;
        }
        @Override
        public String doInBackground(String... params){
//Get the first variable length argument (index 0). This is the city ID.
            String id = params[0];
//Create a connection URL string using the city ID
            String urlStr = "http://weather.livedoor.com/forecast/webservice/json/v1?city=" + id;
//JSON string obtained from the weather information service. Weather information is stored.
            String result = "";
//Describe the process to connect to the above URL and get the JSON string here
//Returns a JSON string
            HttpURLConnection con = null;

            InputStream is = null;
            try{
                URL url = new URL(urlStr);
                con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("GET");
                con.connect();
                is = con.getInputStream();
                result = is2String(is);
            }
            catch(MalformedURLException ex){

            }
            catch(IOException ex){

            }
            finally{
                if(con != null){
                    con.disconnect();
                }
                if(is != null){
                    try{
                        is.close();
                    }
                    catch(IOException ex){

                    }
                }
            }
            return result;
        }
        @Override
        public void onPostExecute(String result){
//Prepare a character string variable for weather information
            String telop = "";
            String desc = "";
            try{
                JSONObject rootJSON = new JSONObject(result);
                JSONObject descriptionJSON = rootJSON.getJSONObject("description");
                desc = descriptionJSON.getString("text");
                JSONArray forecasts = rootJSON.getJSONArray("forecasts");
                JSONObject forecastNow = ((JSONArray) forecasts).getJSONObject(0);
                telop = forecastNow.getString("telop");
            }
            catch(JSONException ex){

            }
//Describe the process to analyze the weather information JSON character string here.
//Set the weather information string in TextView
            _tvWeatherTelop.setText(telop);
            _tvWeatherDesc.setText(desc);
        }

    }
    private String is2String(InputStream is) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        StringBuffer sb = new StringBuffer();
        char[] b = new char[1024];
        int line;
        while(0 <= (line = reader.read(b))){
            sb.append(b, 0, line);
        }
        return sb.toString();
    }
}

Recommended Posts

Asynchronous processing and Web API integration in Android Studio
About UI thread processing in Android asynchronous
Java to C and C to Java in Android Studio
Notes in Android studio
Try implementing asynchronous processing in Azure
Automatically insert `@SuppressWarnings` in Android Studio
Implementation of asynchronous processing in Tomcat
OkHttp3 (GET, POST) in Android Studio
Web application structure by Java and processing flow in the presentation layer
Basic basis of Android asynchronous processing "AsyncTask"
Asynchronous processing by RxJava (RxAndroid) on Android
Implementation of multi-tenant asynchronous processing in Tomcat
How to implement asynchronous processing in Outsystems
How to use ExpandableListView in Android Studio
Impressions and doubts about using java for the first time in Android Studio
Riot (chat app) development (settings) in Android Studio
Asynchronous processing with regular execution in Spring Boot
Vulnerabilities and Countermeasures in Important Processing (Purchase Processing) (CSRF)
3 ways to import the library in Android Studio
Use the JDK used in Android Studio in the terminal
Beginners try using android studio Part 2 (event processing)
[Android] Alphabet uppercase limit and length limit in EditText
Difficulties when implementing Alarm Manager in Android Studio
Represents "next day" and "previous day" in Java / Android