HTTP POST によるファイルのアップロード

スマートフォンなどの携帯端末では、外出先のメモ、写真などをウェブサイトにアップロードしておき、 後から PC を使ってそれらの情報を閲覧するなどすると便利な場合が少なくありません。

ここでは、特に写真をアップロードする場合を考えます。

写真などの画像ファイルをウェブサイトにアップロードする方法はいくつかありますが、 良くやる方法としては HTML のフォームでファイルを選択して、ウェブサイトにアップロードするといった流れではないでしょうか。

このとき裏では、HTTP の POST リクエストでマルチパート・フォーム・データをウェブサーバーに送信していることになります。

サーバー側のファイル受信

PHP によるサーバー側の受け口を先に作っておきましょう。

<?php
$target_dir  = "./_upfiles/";
$target_path = $target_dir . basename( $_FILES['f1']['name']);
if(move_uploaded_file($_FILES['f1']['tmp_name'], $target_path)) {
 echo "The file ".  basename( $_FILES['f1']['name']).
 " has been uploaded";
} else{
 echo "エラーが発生しました。";
}
?>

これによって、"f1" という名前の <input type="file" name="f1" ... > といったフォームデータを受信して、_upfiles という名前のディレクトリに保存できます。

HTTP POST によるファイルアップロード

HttpClient の入手

http://hc.apache.org/downloads.cgi から HttpClient (GA) の新しいバージョンをダウンロードします。 ここでは HttpClient 4.2.1 を利用します。

展開したあと libs フォルダに httpmime-4.2.1.jar をインポートします。

httpmime

具体的には libs のコンテキストメニューから Import... を選択。General > File System と選択して、 上でダウンロードして (展開した)、httpmime-4.2.1.jar を選択します。

マルチパート・フォーム・データとしてファイルをアップロード

ここでは HTML のフォームからファイルをアップロードする方法に代えて、 Android アプリケーションからファイルをアップロードする方法を紹介します。

package com.keicode.android.test.httpuploadtest1;

import java.io.File;
import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

public class UploadAsyncTask 
  extends AsyncTask<String, Integer, Integer> {

  ProgressDialog dialog;
  Context context;
  
  public UploadAsyncTask(Context context){
    this.context = context;
  }
  
  @Override
  protected Integer doInBackground(String... params) {

    try {
      String fileName = params[0];
      
      HttpClient httpClient = new DefaultHttpClient();
      HttpPost httpPost = new HttpPost("アップロード先 URL");
      ResponseHandler<String> responseHandler =
        new BasicResponseHandler();
      MultipartEntity multipartEntity =
        new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
      
      File file = new File(fileName);
      FileBody fileBody = new FileBody(file, "image/jpeg");
      multipartEntity.addPart("f1", fileBody);
      
      httpPost.setEntity(multipartEntity);
      httpClient.execute(httpPost, responseHandler);
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    return 0;
  }

  @Override
  protected void onPostExecute(Integer result) {
    if(dialog != null){
      dialog.dismiss();
    }
  }

  @Override
  protected void onPreExecute() {
    dialog = new ProgressDialog(context);
    dialog.setTitle("Please wait");
    dialog.setMessage("Uploading...");
    dialog.show();
  }  
}

ここでは非同期タスクとして Upload タスクを作成しました。

実際には処理時間が長引くこともありますから、サービスで実施した方が良いでしょう。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門