通信処理は時間を要することがあるため、別スレッドにて処理するようにします。
Android 3.0 (Honeycomb) 以降では、メインスレッドで通信を行うとNetworkOnMainThreadException例外が発生します。これはStrictModeによる制約です。NetworkOnMainThreadException | Android Developers
つねにネットワークに接続されているとは限らないため、通信の前には必ずネットワークへの接続を確認します。
ACCESS_NETWORK_STATEのパーミッションが必要です。
android.net.ConnectivityManager connectivityManager = (android.net.ConnectivityManager) getSystemService(android.content.Context.CONNECTIVITY_SERVICE); android.net.NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { // 接続済み } else { // 未接続 }
≫java.net.HttpURLConnectionクラス
org.apache.http.client.HttpClient
HttpClientはインターフェイスのため、インスタンスを得るには、これを継承したクラスを生成します。
HttpClient httpClient = new DefaultHttpClient();
HttpClientは基本的に、
の3つのメソッドを持ちます。このうち重要なのはexecute()で、このメソッドは8つのメソッドによってオーバーロードされています。そのうちの1つに、
public abstract T execute( HttpUriRequest request, ResponseHandler<? extends T> responseHandler )execute - HttpClient | Android Developers
があります。戻り値の型Tは、responseHandler引数の生成時の型変数Tで指定します。
指定URLへリクエストを送信し、レスポンスボディを出力します。
String url = "http://example.com"; ResponseHandler<String> responseHandler = new ResponseHandler<String>() { @Override public String handleResponse(HttpResponse response) throws IOException { String entity = null; if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { entity = EntityUtils.toString(response.getEntity(), "UTF-8"); } return entity; } }; HttpClient httpClient = new DefaultHttpClient(); String responseBody = null; try { HttpGet httpGet = new HttpGet(url); responseBody = httpClient.execute(httpGet, responseHandler); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { httpClient.getConnectionManager().shutdown(); } System.out.println(responseBody);
ResponseHandlerは、HttpResponseによって生成されたレスポンスの処理をカプセル化します。このインターフェイスは、1つの抽象メソッドを持つのみです。
public abstract T handleResponse (HttpResponse response)handleResponse - ResponseHandler | Android Developers
引数のresponseから、HTTPのレスポンスを取得できるHttpResponseを得られます。
public abstract HttpEntity getEntity ()getEntity - HttpResponse | Android Developers
public abstract StatusLine getStatusLine ()getStatusLine - HttpResponse | Android Developers
HttpResponseのインスタンスからメッセージのエンティティを取得するには、
String messageEntity = null; if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { messageEntity = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); }
のようにします。
Android 3.0以降ならば、非同期のデータ読み込みをサポートするLoaderクラスを使用できます。
通信に失敗したときのエラーに「permission」の単語が含まれているならば、その処理に適した認可をユーザーから得る必要があります。Managing Network Usage | Android Developers
通信に失敗し、LogCatに「Caused by: libcore.io.ErrnoException: getaddrinfo failed: EACCES (Permission denied)」のように出力されることがあります。この場合には、マニフェストの<uses-permission>で、ネットワーク利用の認可を得る必要があります。
<uses-permission android:name="android.permission.INTERNET" />
SecurityException例外が発生し、Permission denied (missing INTERNET permission?)となるときも同様です。
「ConnectivityService: Neither user NNN nor current process has android.permission.ACCESS_NETWORK_STATE.」のようなエラーとなるときには、
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
の記述を追加します。
エミュレータからlocalhostへ接続を試みたとき、「failed to connect to localhost/127.0.0.1 (port 80) after 15000ms: isConnected failed: ECONNREFUSED (Connection refused)」のようなエラーとなる場合には、特別に用意されているIPアドレスで指定します。struts - test the localhost in android emulator - Stack Overflow