Android アプリから S3 へファイルをアップロードする方法

ここでは AWS S3 (Simple Storage Service) へファイルを保存するアンドロイド・ネイティブ・アプリケーションの開発方法について説明します。

Android 開発全般については、当サイトの姉妹サイト Android 開発入門 を参考にしてください。

このページでは S3 へのファイルアップロードに特化した箇所および AWS の開発環境作りのポイント等について説明します。

Android アプリから S3 へファイルをアップロードする方法

開発環境

まず開発環境についてですが、私が試したところでは 32 ビット版の ADT バンドルを利用しないと、アプリケーションが正常に実行できませんでした。

これが何の影響であるかまで確認していませんが、32 ビット版を使ったということだけ念のため。

32 ビット版は ADT ダウンロードサイトで明示的に選択することで、ダウンロード可能です。

AWS SDK for Android については、AWS の該当サイトからダウンロードできます。

zip でダウンロードして任意のフォルダに展開します。

コード

まず Eclipse で Android アプリケーションのプロジェクトを作成し、その中に libs というフォルダを作成します。

そして、その中に AWS SDK の aws-android-sdk-x.x.x-debug.jar をインポートします。x.x.x の部分にはお使いの AWS SDK のバージョン番号が入ります。 今回は aws-android-sdk-1.6.0-debug.jar でした。

AWS Android

さて、ファイルのアップロードですがここでは非同期タスクとして実装します。

メイン UI スレッドからネットワーク操作を実行できないので、サービス、または、こうした非同期タスクなどでワーカースレッドから処理を実行します。

そして、完了通知については非同期タスクなら onPostExecute メソッドにて実行(これは UI スレッドで実行される)、 サービスならブロードキャストレシーバを使うなどすれば良いでしょう。

S3 へのアップロードについては、AmazonS3Client オブジェクトの putObject メソッドで実行します。

クライアント作成時に、BasicAWSCredentials で認証情報を設定し、そして PutObjectRequest オブジェクトにアップロード先のキー情報(バケツ及びキー名)、そして端末内のファイルパスを指定した情報を 詰め込み、それを putObject メソッドに渡します。

アップロードはこれで OK ですが、ここでは public-read のパーミッションを setObjectAcl メソッドを使って設定しています。

コードは次の通り。

package com.example.awss3up1;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;


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

  final String MY_ACCESS_KEY_ID = "...";
  final String MY_SECRET_KEY = "...";
  final String MY_PICTURE_BUCKET = "mybucket";

  final String TAG = "S3UP";
  Context context;
  String path;
  String keyName;


  public UploadAsyncTask(
    Context context, String path, String keyName) {
    this.context = context;
    this.path = path;
    this.keyName = keyName;
  }

  @Override
  protected Boolean doInBackground(String... arg0) {

    Boolean ret = Boolean.FALSE;

    Log.d(TAG, "Start uploadFile");

    try {

      AmazonS3Client s3Client = new AmazonS3Client(
        new BasicAWSCredentials(
          MY_ACCESS_KEY_ID, MY_SECRET_KEY ) );
      PutObjectRequest por = new PutObjectRequest(
        MY_PICTURE_BUCKET,
        keyName,
        new java.io.File(path) );
      s3Client.putObject(por);
      s3Client.setObjectAcl(
        MY_PICTURE_BUCKET,
        keyName,
        CannedAccessControlList.PublicRead);

      ret = Boolean.TRUE;
    }
    catch(Exception ex){
      Log.d(TAG, ex.getMessage());
    }

    Log.d(TAG, "Exit uploadFile");

    return ret;
  }

  @Override
  protected void onPostExecute(Boolean result) {
    Toast.makeText(context,
      "result = " + result.toString(),
      Toast.LENGTH_SHORT).show();
  }

}

尚、ローカルのファイルパス名などは ギャラリーからファイルを選択 などを参考にすることで取得可能です。