Android開発〜WEBアクセス（POST）外部と通信してデータを送信してみる。〜

#はじめに
こんにちは。某学校でプログラミング等の勉強中のサーバーサイドのプログラマーのワタタクです。:relaxed:
今回もAndroid開発していきましょう。
今回はAndroidで外部のネットワークと接続してデータを送信してみたいと思います。
ほぼほぼ前回のGETの時と同じです。

#対象者
- javaがそこそこ書ける人。
- Android開発においてもそこそこできる人。
- [Android開発〜WEBアクセス（GET）外部と通信してデータを取得してみる。〜](https://qiita.com/watataku/items/a34ff1f5927c0b32f0ab)をみた人。

#POST送信
＊HttpURLConnectionでPOST送信を行うには、前回「Android開発〜WEBアクセス（GET）外部と通信してデータを取得してみる。〜」で紹介したUrl.openConnection と、con.disconnect() の間に以下の処理を記述する。
1) 送信するリクエストパラメータを「&」でつないだ文字列を用意する。

```
String postData = “ リクエストパラメータ１ = ” + 値１ + “ &リクエストパラメータ２ = ” + 値２
```
2) リクエストメソッドを POST に設定する。

``` 
con.setRequestMethod(“POST”)
```
3) リクエストパラメータの出力を可能にする。 

```
con.setDoOutput(true)
```
4) OutputStream を取得する。 → サーバとパイプをつなぐ。

```
OutputStream os = con.getOutputStream()
```
5) リクエストパラメータを送信する → サーバとパイプをつなぐ。

```
os.write(postData.getByte())
//文字列 (String) バイト化しないとデータ送信できない
```

**(注)** *POSTの時はcon.connect()は不要。*
#Progress
AsyucTaskの「doInBackground()」内で**publishProgress()**を呼び出すと、UIスレッドで「onProgressUpdate()」が実行される。

- publishProgress( ) の引数に渡した値がそのまま onProgressUpdate( ) の引数に渡される。 
- 引数の型は AsyucTask のジェネリクスの 2 コ目で指定する。

```
private class PostAccess extends AsyucTask< String, String, String > {   
                             ...
  public String doInBackground(String ... parent) {
                         ...
    publishProgress(文字列);
  }

  public void onProgressUpdate(String ... values) {
    super.onProgressUpdate(values);//お約束として書いておく
  }
}
```

#サーバーにPOSTするサンプルコード
＊今回は画面上で名前とコメントを入力してもらいサーバーにPOSTしその内容がおうむ返しでサーバーから帰ってくるという簡単なサンプルコードです。

```java
public class PostActivity extends AppCompatActivity {

    private static final String ACCESS_URL = "http://xxx.xxx.xx/xx/~~~.php";

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

    public void sendButtonClick(View view) {
        EditText etName = findViewById(R.id.etName);
        EditText etComment = findViewById(R.id.etComment);
        TextView tvProcess = findViewById(R.id.tvProcess);
        TextView tvResult = findViewById(R.id.tvResult);

        tvProcess.setText("");
        tvResult.setText("");

        String name = etName.getText().toString();
        String comment = etComment.getText().toString();

        PostAccess access = new PostAccess(tvProcess, tvResult);
        access.execute(ACCESS_URL, name, comment);
    }

    private class PostAccess extends AsyncTask<String, String, String> {
        private static final String DEBUG_TAG = "PostAccess";
        private TextView _tvProcess;
        private TextView _tvResult;
        private boolean _success = false;

        public PostAccess(TextView tvProcess, TextView tvResult) {
            _tvProcess = tvProcess;
            _tvResult = tvResult;
        }

        @Override
        public String doInBackground(String... params) {
            String urlStr = params[0];
            String name = params[1];
            String comment = params[2];

            String postData = "name= " + name + "&comment=" + comment;
            HttpURLConnection con = null;
            InputStream is = null;
            String result = "";

            try {
                publishProgress(getString(R.string.msg_send_before));
                URL url = new URL(urlStr);
                con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("POST");
                con.setConnectTimeout(5000);
                con.setReadTimeout(5000);
                con.setDoOutput(true);
                OutputStream os = con.getOutputStream();
                os.write(postData.getBytes());
                os.flush();
                os.close();
                int status = con.getResponseCode();
                if (status != 200) {
                    throw new IOException("ステータスコード: " + status);
                }
                publishProgress(getString(R.string.msg_send_after));
                is = con.getInputStream();

                result = is2String(is);
                _success = true;
            }
            catch(SocketTimeoutException ex) {
                publishProgress(getString(R.string.msg_err_timeout));
                Log.e(DEBUG_TAG, "タイムアウト", ex);
            }
            catch(MalformedURLException ex) {
                publishProgress(getString(R.string.msg_err_send));
                Log.e(DEBUG_TAG, "URL変換失敗", ex);
            }
            catch(IOException ex) {
                publishProgress(getString(R.string.msg_err_send));
                Log.e(DEBUG_TAG, "通信失敗", ex);
            }
            finally {
                if (con != null) {
                    con.disconnect();
                }
                try {
                    if (is != null) {
                        is.close();
                    }
                }
                catch (IOException ex) {
                    publishProgress(getString(R.string.msg_err_parse));
                    Log.e(DEBUG_TAG, "InputStream解析失敗", ex);
                }
            }
            return result;
        }

        @Override
        public void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            String message = _tvProcess.getText().toString();
            if (!message.equals("")) {
                message += "\n";
            }
            message += values[0];
            _tvProcess.setText(message);
        }

        @Override
        public void onPostExecute(String result) {
            if (_success) {
                String name = "";
                String comment = "";
                onProgressUpdate(getString(R.string.msg_parse_before));
                try {
                    JSONObject rootJson = new JSONObject(result);
                    name = rootJson.getString("name");
                    comment = rootJson.getString("comment");
                }
                catch (JSONException ex) {
                    onProgressUpdate(getString(R.string.msg_err_parse));
                    Log.e(DEBUG_TAG, "JSON解析失敗", ex);
                }
                onProgressUpdate(getString(R.string.msg_parse_after));

                String message = getString(R.string.dlg_msg_name) + name + "\n" + getString(R.string.dlg_msg_comment) + comment;
                _tvResult.setText(message);
            }
        }

        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();
        }
    }
}

```
以上。
もし何か間違っている等のご指摘があればご連絡ください。
最後まで読んで頂きありがとうございました。