【ぶっちゃけAndroidアプリ開発】HTTP通信してJSON取得して表示するサンプル

HTTP通信してWebサーバー上にあるJSONデータを取得してTextViewに表示するアプリです。
動くサンプルコードが欲しい人のために、簡単な解説とともに載せておきます。

Android StudioでEmpty Activityで新規プロジェクト作成し、コピペして一部修正すれば動くはずです。

＜前提＞
作成日:2019年12月27日
AndroidStudio 3.5.3
targetSdkVersion 26
CompileSdkVersion 29

・Empty Activityの雛形を元に作成。
・レンタルサーバーなど、JSONファイルをアップロードできる環境があること。
##サンプルコード
###JSONデータ
```jsondata.json
{"profile":[
  {
    "no":"0001",
    "name":"山田太郎",
    "address":
      {
        "address1":"千代田1-1",
        "city":"千代田区",
        "state":"東京都"
      },
    "phone":"03-111-1111",
    "mail":"taro@yaxxx.co.jp"
  },
  {
    "no":"0002",
    "name":"田中花子",
    "address":
      {
        "address1":"西区高島2-16",
        "city":"横浜市",
        "state":"神奈川県"
      },
    "phone":"045-222-2222",
    "mail":"hanako@gxxxx.com"
  },
  {
    "no":"0003",
    "name":"加藤次郎",
    "address":
      {
        "address1":"浦和区高砂3-15-1",
        "city":"さいたま市",
        "state":"埼玉県"
      },
    "phone":"048-333-3333",
    "mail":"jiro@dxxxxx.ne.jp"
  }
]}
```
・今回使用する住所録チックなJSONデータ。
・「jsondata.json」というファイル名で予めWebサーバー上にアップロードしておいてください。
###HTTPリクエスト&JSONパースする非同期クラス

```AsyncHttpRequest.java
public class AsyncHttpRequest extends AsyncTask<String, Void, JSONObject> {
    private Activity mActivity;

    public AsyncHttpRequest(Activity activity) {
        mActivity = activity;
    }

    @Override
    protected JSONObject doInBackground(String... params) {
        HttpURLConnection con = null;
        StringBuilder builder = new StringBuilder();
        JSONObject json = new JSONObject();
        try {
            URL url = new URL(params[0]);
            con = (HttpURLConnection) url.openConnection();
            InputStream stream = con.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
            String line = "";
            while ((line = reader.readLine()) != null)
                builder.append(line);
            stream.close();

            json = new JSONObject(builder.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally{
            con.disconnect();
        }

        return json;
    }

    public void onPostExecute(JSONObject json) {
        StringBuilder builder = new StringBuilder();
        try {
            JSONArray array = json.getJSONArray("profile");
            for (int i = 0; i < array.length(); i++) {
                JSONObject obj = array.getJSONObject(i);
                builder.append(obj.getString("no") + "\n");
                builder.append(obj.getString("name") + "\n");
                builder.append(obj.getJSONObject("address").getString("state"));
                builder.append(obj.getJSONObject("address").getString("city"));
                builder.append(obj.getJSONObject("address").getString("address1") + "\n");
                builder.append(obj.getString("phone") + "\n");
                builder.append(obj.getString("mail") + "\n");
            }
            ((TextView) mActivity.findViewById(R.id.textview)).setText(builder.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
```
・HTTPリクエストを出して、JSONデータを取得し、パースして出力する処理。
・HTTPリクエストは非同期処理で行う必要があるため、AsyncTaskを継承したクラスで実装する。[AsyncTaskについては別ページでぶっちゃけました](https://qiita.com/Pinehead/items/fbe74db334c8b6b68401)ので、参照してください。
・doInBackgroundメソッドでHTTPリクエストを発行し、結果をJSONオブジェクトにしてreturnする。
・onPostExecuteでJSONオブジェクトをパースして全データをTextViewに出力する。
・今回使用したデータは、3件のprofileが入っているので、JSON配列(JSONArrayを使う)で順に取り出す。
###メインActivity
```MainActivity.java
public class MainActivity extends AppCompatActivity {

    private AsyncHttpRequest httpreq; // 追加

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

        httpreq = new AsyncHttpRequest(this); // 追加
        httpreq.execute("http://xxxxxxx.php.xdomain.jp/jsondata.json"); // 追加

    }
}
```
・3行追加してください。
・executeメソッドのURLを、あなたのWebサーバーのURLに書き換えてください。
###マニフェスト

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

    <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>
    <uses-permission android:name="android.permission.INTERNET" />


</manifest>
```
・uses-permission タグの行を追加してください。このアプリにHTTP通信を許可する指定です。
###レイアウト
```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```
・TextViewのidに「textview」を指定してください。
###実行結果
![Screenshot_20191227-181330_TestGetJsonArray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142654/7c0d271d-219c-f319-1923-7a4645db0fd3.jpeg)