-
Notifications
You must be signed in to change notification settings - Fork 355
2.09. ネットワーク通信
この章では、ネットワーク通信について解説します。
ネットワークアクセスを行うためにはAndroidManifestファイルにネットワークアクセスを許可するパーミッションを追記する必要があります。 このパーミッションがない場合には、ネットワーク接続がエラーとなります。
<uses-permission android:name="android.permission.INTERNET" />
また、ネットワークの接続状態を確認するためには
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
のパーミッションが必要になります。 このパーミッションを取得することで Wifiまたは3Gなどのネットワーク接続が可能な場合は通信を行い、接続が不可能な場合はオフラインモードでアプリケーションを動作させる。 と言ったようなことが可能になります。
下記のような場合にネットワークへの接続状態を確認したいケースがあると思います。 その際にConnectivityManagerを利用して、ネットワークへの接続状態を確認することができます。
- ネットワークに接続されていない場合は、ローカルにキャッシュされているデータを表示する
- ファイルサイズが大きいためwifiに接続されている場合のみダウンロードする
ネットワークへの接続状態を確認するには、ACCESS_NETWORK_STATEのパーミッションを設定した上で、下記のようなコードで確認ができます。
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info.isConnected()) {
Toast.makeText(this, info.getTypeName() + " connected", Toast.LENGTH_LONG).show();
}
接続されているネットワークの種別を知りたい場合は、NetworkInfo.getType()で取得することができます。 wifiに接続時のみに動作させたい処理は下記のように記述することで実装できます。
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
// wifi時のみ動作する処理を記述
}
AndroidのHTTP通信を行うのclientははHttpURLConnectionとApache HttpClientがあります。
これらのクライアントの主な利用シーンとしては、サーバーのAPIにリクエストを送り、レスポンスを処理するケースです。
通常のhtmlを表示するようなケースはWebView(アプリ内ブラウザ)を利用するのが良いでしょう。
特殊なケースではこれらのクライアントで通信を行いWebViewで、レスポンスのhtmlを表示するようなこともあるかもしれません。
どちらのclientも出来る事に大きな差はありません。そのためアプリケーション内ではどちらかに統一するのが一般的です。 現在、新しくアプリケーションを作成するならばHttpURLConnectionの使用を推奨します。 Android2.2をサポート端末に含める場合はHttpClientの使用が推奨されていますが、アプリケーションの将来性を考えた場合、HttpURLConnectionを使用するのがよいでしょう。
サポートする範囲によって推奨するclientが変わってしまうのはわかりづらいですが、理由についてはこちらを参照してください。
ネットワーク接続の処理は予測不能な遅延を含む可能性があるため、ネットワーク接続の処理はUIThreadで処理を行なってはいけません。 そのため、ネットワーク接続は基本的に前章の非同期処理と組み合わせて使うことになります。
参考:HttpURLConnection | Android Developers
HttpURLConnectionはweb上でデータの送受信をするためのclientです。 APIがシンプルで、サイズが小さいのでリソースに限りがあるAndroidに適しています。
Android2.2以前では、幾つかの問題のあるバグがあったため、推奨されていませんでした。特に、特定の条件でconnection poolを汚染することがありました。 この問題は下記のようなコードで回避ができます。
private void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
Android2.2以前の端末をサポートする場合はこのコードを入れておくほうがよいでしょう。
HttpURLConnectionの使用方法は
- URLオブジェクトのopenConnection()を呼び出すことによりインスタンスを取得出来ます。 ただし、openConnection()で取得できる型はURLConnection型なので、HttpURLConnectionへキャストする必要があります。
- 次に、必要なヘッダーを設定します。 Session cookieや認証情報、Content-typeなどを必要に応じて設定します。
- リクエストにbodyを設定する場合は、setDoOutput(true)でbodyが存在することを明示的に指定してください。 接続を確立後、getOutputStream()で取得したOutputStreamにbodyの内容を書き込みます。
- connect()で接続を確立します。 setDoOutput(false)の場合はこの段階でgetInputStream()でレスポンスを取得できるかと思います。 setDoOutput(treu)の場合は、getOutputStream()で取得したOutputStreamをcloseするまでデータの送信中のステータスになっているため、OutputStreamへの書き込みが完了したらcloseを呼び出すようにしてください。
- レスポンスをgetInputStream()で取得する。
上記のような手順でサーバーからのレスポンスを得ることができます。 ただし、実際にはgetInputStreamの前にgetResponseCode()でステータスコードなどを確認し、必要に応じてエラーハンドリングなどを行う必要があります。また、実際のアプリケーションでは、HttpURLConnectionをラッピングするクラスを作成し、個々のリクエストはラッパーを経由して行うと良いでしょう。
GET処理
URL url = new URL("http://mixi.jp");
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream is = connection.getInputStream();
StringBuilder src = new StringBuilder();
while (true) {
byte[] line = new byte[1024];
int size = is.read(line);
if (size <= 0)
break;
src.append(new String(line, "euc-jp"));
}
} catch (IOException e) {
e.printStackTrace();
} finally{
connection.disconnect();
}
POST処理
URL url = new URL("http://mixi.jp");
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
String postData = "hoge=fuga&piyo=test";
OutputStream os = connection.getOutputStream();
os.write(postData.getBytes());
os.flush();
os.close();
InputStream is = connection.getInputStream();
StringBuilder src = new StringBuilder();
while (true) {
byte[] line = new byte[1024];
int size = is.read(line);
if (size <= 0)
break;
src.append(new String(line, "euc-jp"));
}
} catch (IOException e) {
e.printStackTrace();
} finally{
connection.disconnect();
}
HttpClientクライアントはApacheによって開発が進められているclientです。 HttpURLConnectionよりも扱いやすいですが、Androidでの利用はHttpURLConnectionが推奨されているので、簡単な紹介に留めます。 getの処理は下記のようになります。
HttpClient client = new DefaultHttpClient();
try {
client.execute(new HttpGet("http://mixi.jp"),
new ResponseHandler<String>() {
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
return EntityUtils.toString(response.getEntity());
}
});
} catch (IOException e) {
e.printStackTrace();
}
- (実習) HttpURLConnectionを利用してmixi.jpへアクセスをし、取得できたhtmlの文字列を画面に表示してください。
- (実習) HttpClientを利用して実習1と同様のことを行なってください。
- (課題) youtubeで日本で前日の評価が最も高い動画のタイトルをAPIで取得し表示してください。
Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.