ネットワーク

通信処理は時間を要することがあるため、別スレッドにて処理するようにします。

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 {
    // 未接続
}

HTTPクライアント

HttpURLConnectionクラス

java.net.HttpURLConnectionクラス

HttpClientインターフェイス

org.apache.http.client.HttpClient

HttpClientはインターフェイスのため、インスタンスを得るには、これを継承したクラスを生成します。

HttpClient httpClient = new DefaultHttpClient();

メソッド

HttpClientは基本的に、

  • execute()
  • getConnectionManager()
  • getParams()

の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インターフェイス

ResponseHandlerは、HttpResponseによって生成されたレスポンスの処理をカプセル化します。このインターフェイスは、1つの抽象メソッドを持つのみです。

public abstract T handleResponse (HttpResponse response)
handleResponse - ResponseHandler | Android Developers

引数のresponseから、HTTPのレスポンスを取得できるHttpResponseを得られます。

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

のようにします。

Loaderクラス

Android 3.0以降ならば、非同期のデータ読み込みをサポートするLoaderクラスを使用できます。

トラブル対処法

認可 (permission)

通信に失敗したときのエラーに「permission」の単語が含まれているならば、その処理に適した認可をユーザーから得る必要があります。Managing Network Usage | Android Developers

permission.INTERNET

通信に失敗し、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?)となるときも同様です。

permission.ACCESS_NETWORK_STATE

ConnectivityService: Neither user NNN nor current process has android.permission.ACCESS_NETWORK_STATE.」のようなエラーとなるときには、

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

の記述を追加します。

localhostへの接続

エミュレータから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

Androidの情報サイトから、まとめて検索