Edited at

Android開発〜WEBアクセス(GET)外部と通信してデータを取得してみる。〜


はじめに

こんにちは。某学校でプログラミング等の勉強中のサーバーサイドのプログラマーのワタタクです。:relaxed:

今回もAndroid開発していきましょう。

今回はAndroidで外部のネットワークと接続してデータを取得してみたいと思います。


対象者


  • Javaがそこそこ書ける人。

  • Android開発においてもそこそこできる人。


Webアクセス概要

1) アプリ内で http アクセスのソースコードを記述する。 → レスポンスの内容は JSON か XML が多い。

2) 画面内で画面部品 WebView を使う。 → レスポンスの内容は原則 HTML。


非同期処理

Webアクセスのように、処理に時間がかかるもの、予期せぬエラーが起こりそうなもおは、 メイン処理とは別のスレッドで処理(非同期処理)を行う。


AsyncTask

Androidの非同期処理のうち、UIスレッドとやりとりがある場合は、AsyucTaskクラスを使うと便利。


1.AsyncTaskの使い方

1) Asynuc Task を継承したクラスを作成する。

→ アクティビティクラスの private メンバクラスとして作ると便利。

2) メソッド doInBackground() 内に非同期で行いたい処理を記述する。

→ このメソッドは Asyuc Task の抽象メソッドなので、必ずオーバーライドする必要がある。

3) アクティビティでこのクラスを newして、execute() メソッドを実行する

private class クラス名 extends AsyucTask< ... > {

...
@Override
public String doInBackground( String ... params ) {
// ここに非同期処理を記述
}
}
その後
クラス名 変数名 = new クラス名();
変数名.execute( ... );

*メソッドの引数にある「...」( ドット 3 コ ) は可変長引数を表す。

メソッド内での引数の扱いは配列となる。


2.その他のメソッド

AsyucTask には doInBackground() 以外にも以下のメソッドがある。

これらのメソッドは UI スレッド上で実行されるので、画面部品の操作が可能。



  • onPostExecute() : doInBackground() の終了後に実行される。


  • onPreExecute() : doInBackground() の開始前に実行される。


  • onProgressUpdate() : doInBackground() の中で publishProgress() を呼び出した時に実行される。

さらに、アクティビティから cancel() が呼び出されると、doInBackground() 終了後、 onCancelled() が実行される。


3.ジェネリクス

AsyucTask の子クラスを作るとき、ジェネリクスに 3 個の型を書く必要がある。

型指定が不要なものは Void と記述。

...クラス名 extends AsyucTask<①String, ②Void, ③String> {

①Params

execute() . doInBackground() の引数の型。

→ execute() の引数がそのまま doInBackground() の引数として渡される

②Progress

publishProgress() . onProgressUpdate() の引数の型。

→ publishProgress() の引数が、そのまま onProgressUpdate() の引数として渡される。

③Result

doInBackground() の戻り値、および、onPostExecute() . onCanceled() の引数の型。 → doInBackground() の戻り値は、そのまま、onPostExecute() や onCanceled() の引数 として渡される。


httpアクセス


インターネット接続許可を与える


src/main/AndroidManifest.xml

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

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

もし許可を与えずにインターネット通信を行うとjava.net.SocketException: socket failed: EACCES (Permission denied)の例外が発生します。


インターネットに接続する

HttpURLConnectionオブジェクトを使います。


URL文字列をセットする。

URL url = new URL("URL文字列");


コネクションの取得

con = (HttpURLConnection) url.openConnection();

アクセス先URL情報を持ったURLオブジェクトに対してURL#openConnection()メソッドを実行すると、HttpURLConnectionオブジェクト(コネクション)を取得することができます。


アクセス方法の設定

setRequestMethod()を使います。

*今回はデータ取得のため"GET"

con.setRequestMethod("GET")


実際にインターネット接続

URLConnection#connect()を使います。

con.connect();


コネクションの切断

disconnect()を使います。

処理終了後は、不要なコネクションを残さないために、明示的にコネクションを切断してあげる必要があります。

con.disconnect()


httpリクエストの際のサンプルコード

private class クラス名 extends AsyncTask<String, Void, String> {

private static final String DEBUG_TAG = "タグ";

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

HttpURLConnection con = null;
InputStream is = null;
String result = "";

try {
URL url = new URL(urlStr);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();
is = con.getInputStream();

result = is2String(is);
}
catch(MalformedURLException ex) {
Log.e(DEBUG_TAG, "URL変換失敗", ex);
}
catch(IOException ex) {
Log.e(DEBUG_TAG, "通信失敗", ex);
}
finally {
if (con != null) {
con.disconnect();
}
if (is != null) {
try {
is.close();
}
catch (IOException ex) {
Log.e(DEBUG_TAG, "InputStream解除失敗", ex);
}
}
}
return result;
}

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

InputStreamはバイトを読み込むためのクラス。

*is2Strクラスはおまじないみたいなものとして書いておいてください。理由はわかりません。わかる人は教えてください。


JSONの扱い

JSONObjectクラスを使います。

引数として「JSON文字列」を指定します。

その後、以下の操作を行いながら、目的の JSONObject を取得し、getString( ... ) で値を取得する。


  • 直下の JSONObject の取得は、getJSONObject( ... )

  • 直下の JSONArray( JSON 配列 ) の取得は、getJSONArray( ... )

  • JSONArray の指定の JSONObject の取得は、getJSONObject( ... )


JSON処理の際のサンプルコード

private class クラス名 extends AsyncTask<String, Void, String> {

@Override
public void onPostExecute(String result) {
String title = "";
String text = "";
String dateLabel = "";
String telop = "";
try {
JSONObject rootJSON = new JSONObject(result);
title = rootJSON.getString("title");
JSONObject descriptionJSON = rootJSON.getJSONObject("description");
text = descriptionJSON.getString("text");
JSONArray forecasts = rootJSON.getJSONArray("forecasts");
JSONObject forecastNow = forecasts.getJSONObject(0);
dateLabel = forecastNow.getString("dateLabel");
telop = forecastNow.getString("telop");
}
catch(JSONException ex) {
Log.e(DEBUG_TAG, "JSON解析失敗", ex);
}

}
}

以上。

もし何か間違っている等のご指摘があればご連絡ください。

最後まで読んで頂きありがとうございました。