Programming Style

メニュー

初心者がアプリ開発者になるためのプログラミング学習サイト

[Android] HttpURLConnection:GETリクエストでファイルをダウンロードする

android-common-top

HttpURLConnectionを利用すると、HTTP通信を使った処理を実装することができます。ここでは、HttpURLConnectionでHTTPのGETリクエストを実行し、ファイルをダウンロードする方法について説明します。

 

広 告

 

目次

前提条件

動作確認端末

  • Google Nexus 7 – 5.1.1 – API22(実機)

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

 

アプリがインターネット接続するためには、アプリに対して「ネットワークへのフルアクセス」の許可を与える必要があります。

  android-httpurlconnection-get-text-01   「ネットワークへのフルアクセス」の許可を与えるためには、マニフェストファイルの<manifest>タグ配下に以下のパーミッションを1行を追加します。  

 

src/main/AndroidManifest.xml

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

 

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

 

 

 

 

2. HttpURLConnectionを使ったGETリクエストの実装例

 

まずはHttpURLConnectionを使ってHTTPのGETリクエストを実行し、テキストを取得する処理の実装例を示します。

 

HTTP通信のようなインターネット通信処理は、ThreadAsyncTaskなどを使用して別スレッド(ワーカースレッド)で実装する必要があります。今回の例では、AsyncTaskを使います。

 

HttpURLConnectionを使ったGETリクエストの実装例

import android.os.AsyncTask;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public final class HttpGetTask extends AsyncTask<URL, Void, Boolean> {

    @Override
    protected Boolean doInBackground(URL[] urls) {
        HttpURLConnection con = null;
        try {
            // アクセス先URL
            final URL url = new URL(values[0]);
            // 出力ファイルフルパス
            final String filePath = "/xxxx/xxxx/xxxx/filename.xxx";

            // ローカル処理
            // コネクション取得
            con = (HttpURLConnection) url.openConnection();
            con.connect();

            // HTTPレスポンスコード
            final int status = con.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                // 通信に成功した
                // ファイルのダウンロード処理を実行
                // 読み込み用ストリーム
                final InputStream input = con.getInputStream();
                final DataInputStream dataInput = new DataInputStream(input);
                // 書き込み用ストリーム
                final FileOutputStream fileOutput = new FileOutputStream(filePath);
                final DataOutputStream dataOut = new DataOutputStream(fileOutput);
                // 読み込みデータ単位
                final byte[] buffer = new byte[4096];
                // 読み込んだデータを一時的に格納しておく変数
                int readByte = 0;

                // ファイルを読み込む
                while((readByte = dataInput.read(buffer)) != -1) {
                    dataOut.write(buffer, 0, readByte);
                }
                // 各ストリームを閉じる
                dataInput.close();
                fileOutput.close();
                dataInput.close();
                input.close();
                // 処理成功
                return true;
            }

        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (con != null) {
                // コネクションを切断
                con.disconnect();
            }
        }
        return false;
    }
}

 

上記のHttpGetTaskを呼び出し例は以下のとおりです。ActivityFragmentのライフサイクルイフサイクルメソッドなどメインスレッドにて実装します。

 

HttpGetTaskの呼び出し例

try {
    new HttpGetTask().execute(new URL("http://xxxxxxxxxx/xxxxxx/"));
} catch (MalformedURLException e) {
    e.printStackTrace();
}

 

AsyncTask#execute()メソッドの引数には、リクエス先のURLオブジェクトを渡します。

 

 

 

3. GETリクエストする

 

以下がGETリクエストを実行するためのコードです。

 

GETリクエスト処理部分

HttpURLConnection con = null;
con = (HttpURLConnection) url.openConnection();
con.connect();

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

 

URLConnection#connect()メソッドで実際にインターネット接続をします。

 

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

 

コネクションを切断

con.disconnect();

 

 

 

4. ファイルをダウンロードする

 

GETリクエストを実行し、サーバアクセスに成功した場合にのみ、ファイルのダウンロード処理を実行します。

 

HTTP通信でサーバアクセスが成功すると、サーバからHTTPステータスコードの200がレスポンスコードとして返ってきます。データ取得に成功したかは、このコードで判定することができます。

 

以下がレスポンスコードを判定するためのコードです。

 

レスポンスコードが成功(200)であった場合

// HTTPレスポンスコード
final int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
    // 通信に成功した
}

 

HttpURLConnection#getResponseCode()メソッドを使うとサーバからのレスポンスコードを取得することができます。取得できたレスポンスコードが200かどうかを判定するためには、HttpURLConnectionに用意された定数を用います。

 

Nexus7 端末で上記コードを実行した場合、以下のようなリクエスト情報が送信されます。

 

Nexus7で実行した場合のTCPダンプ

GET /xxxxxxx/ HTTP/1.1
User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 7 Build/LMY47V)
Host: xxxxxxxxxx
Connection: Keep-Alive
Accept-Encoding: gzip

 

アクセスに成功した後はファイルをダウンロードする処理を実行します。テキストデータの読み込み処理は以下のコードのとおりです。

 

ファイルのダウンロード処理

// ファイルのダウンロード処理を実行
// 読み込み用ストリーム
final InputStream input = con.getInputStream();
final DataInputStream dataInput = new DataInputStream(input);
// 書き込み用ストリーム
final FileOutputStream fileOutput = new FileOutputStream(filePath);
final DataOutputStream dataOut = new DataOutputStream(fileOutput);
// 読み込みデータ単位
final byte[] buffer = new byte[4096];
// 読み込んだデータを一時的に格納しておく変数
int readByte = 0;

// ファイルを読み込む
while((readByte = dataInput.read(buffer)) != -1) {
    dataOut.write(buffer, 0, readByte);
}

// 各ストリームを閉じる
dataInput.close();
fileOutput.close();
dataInput.close();
input.close();

ファイルを読み込み、書き込みをするためにはストリームを使います。読み込み用のストリームとしてはDataInputStreamを、書き込み用のストリームとしてはDataOutputStreamを用います。これらストリームを大容量のサイズのデータを扱う場合に使用されます。ストリームは以下の手順で使用します。

 

  • 1. ストリームを開く
  • 2. データが存在する限り、読み込みを継続する
  • 3. ストリームを閉じる

読み込み用ストリームを開いた後は、DataInputStream#read(byte[])を使用してバイトデータを読み込みます。

書き込みストリームを開いた後は、DataOutputStream#write(byte[] buffer, int offset, int count)を使ってバイトデータを書き込みます。

 

DataInputStream#read(byte[])-1を返却するとデータの読み込みが終了したことを意味するため処理を終了します。

 

最後にストリームは閉じるようにします。

 

 

 

 

5. 参考URL

 

HttpURLConnection | Android Developers

http://developer.android.com/intl/ja/reference/java/net/HttpURLConnection.html

 

広 告

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です