Android* アプリケーションから Google Drive* に接続する

同カテゴリーの次の記事

Android* でインテル® インテグレーテッド・パフォーマンス・プリミティブ (インテル® IPP) を使用する

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Connecting to Google Drive* from an Android* App」の日本語参考訳です。


ソースコードのダウンロード

この記事では、Android* アプリケーションから Google Drive* (Google ドライブ) オンライン・ストラージ・サービスに接続するサンプル・アプリケーションを使って、 アプリケーションの操作に応じて実行されるコード領域について説明します。このアプリケーションは、こちらにある Google Drive* のサンプルをベースにしています。サンプルをビルドする前に同 Web ページの手順に従って、アプリケーションを Google Cloud Console に登録してください。

ほとんどの Android* アプリケーションと同様に、このサンプル・アプリケーションは MainActivity の onCreate 関数で始まります。この関数は、Google Drive* アカウントの接続に必要な認証情報を設定します。アクティビティーを開始してプロンプトを表示し、登録済みのアカウントから Google* アカウントを選択するか、新しいアカウント情報を入力するように促します。

mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE));
startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);

次に、この関数はボタンリスナーと ListView リスナーを設定します。

基本 UI の設定が完了したら、アプリケーションはユーザーがダウンロード・ボタンかアップロード・ボタンを選択するのを待機します。ユーザーがアップロード・ボタンをタップすると、そのボタンの OnClickListener が Intent として起動し、アプリケーションはデバイスのストレージからアップロード可能なメディアファイルを取得できます。

final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
        final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
        galleryIntent.setType("*/*");
        startActivityForResult(galleryIntent, RESULT_STORE_FILE);
    }
});

この Intent は startActivityForResult で開始されるため、リターン時にメイン・アクティビティーの onActivityResult 関数が RESULT_STORE_FILE とともに呼び出されます。ユーザーが選択したファイルの URI は data.getData() で取得できます。

protected void onActivityResult(final int requestCode, final int resultCode, final Intent data)
{
    switch (requestCode)
    {
        …
        case RESULT_STORE_FILE: mFileUri = data.getData();
        // ファイルを Google Drive* に保存する
            saveFileToDrive();
        break;
    }
}

この URI により、saveFileToDrive() 呼び出しを使用して、ファイルを Google Drive* に保存することができます。Google Drive* API は、 メイン UI スレッドが遅くなり UI の遅延が生じないように、Google Drive* アカウントとのすべての通信を新しいスレッドで行います。

private void saveFileToDrive()
{
    Thread t = new Thread(new Runnable()
    {
        @Override public void run()
        {
             …
        }
    });
    t.start();
}

run 関数内で、メディアファイルの実際のパスに基づいて新しい URI を作成します。URI に関連付けられているパスは Gallery Intent から返される仮想パスなので、Google Drive* API のアップロード機能では利用できません。以下のように物理パスを取得して、それを基に Google Drive* にアップロードする新しい URI を作成します。

// 実際のパスから URI を作成する
String path; path = getPathFromUri(mFileUri);
mFileUri = Uri.fromFile(new java.io.File(path));
…
    java.io.File fileContent = new java.io.File(mFileUri.getPath());

次に、ファイルコンテンツをユーザーの Google Drive* にアップロードするため、Google Drive* API に渡す FileContent 変数と File 変数を作成します。OnCreate で生成された Service オブジェクトから File のオブジェクトを作成し、Insert 関数でアップロードするメディアファイルのコンテンツを準備します。そして、execute を呼び出して、実際にコンテンツをクラウド上の Google Drive* にプッシュします。

FileContent mediaContent = new FileContent(cR.getType(mFileUri), fileContent);
// File のメタデータ
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType(cR.getType(mFileUri));
com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.Insert i1 = f1.insert(body, mediaContent);
File file = i1.execute();

これでアップロード終了です。ユーザーの Google Drive* アカウントのルートにファイルが表示されます。

次に、ユーザーがダウンロード・ボタンをタップするケースについて考えてみましょう。ボタンがタップされると、getDriveContents 関数が呼び出されます。

final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
        getDriveContents();
    }
});

getDriveContents は、Google Drive* アカウントにある全コンテンツのファイル名のリストをダウンロードするため、新しいスレッドを開始します。

private void getDriveContents()
{
    Thread t = new Thread(new Runnable()
    {
        @Override public void run()
        {
            mResultList = new ArrayList();
            …
        }
    });
    t.start();
} 

getDriveContents 内で FileList オブジェクトを設定し、ファイルリストを要求します。ゴミ箱フォルダーにある全オブジェクトを取得対象外にするため、Q の値を “trashed=false” に設定します。すべてのファイルデータを取得し、Files の ArrayList に格納したら、ユーザーが Google Drive* アカウントにあるダウンロード可能なファイルを確認できるように、UI に ListView を表示します。

com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.List request = null;
do
{
    try
    {
        request = f1.list();
        request.setQ("trashed=false");
        com.google.api.services.drive.model.FileList fileList = request.execute(); 

        mResultList.addAll(fileList.getItems()); 

        request.setPageToken(fileList.getNextPageToken());
    } catch (UserRecoverableAuthIOException e) {
        startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
    } catch (IOException e) {
        e.printStackTrace();
        if (request != null)
        {
            request.setPageToken(null);
        }
    }
} while (request.getPageToken() !=null && request.getPageToken().length() > 0); 

populateListView();

populateListView は、ArrayList からファイル名を取得し、単純な文字列配列に格納します。そして、その配列と ArrayAdapter を利用して ListView を表示します。ListView を表示したら、アプリケーションは再びユーザー入力を待機します。

ユーザーが ListView からファイル名を選択すると、その OnItemClickListener 関数が呼び出されます。

OnItemClickListener mMessageClickedHandler = new OnItemClickListener()
{
    public void onItemClick(AdapterView parent, View v, int position, long id)
    {
        downloadItemFromList(position);
    }
};

この関数は、選択されたリストの位置とともに downloadItemFromList を呼び出します。再びGoogle Drive* との通信が必要なため、新しいスレッドをスポーンします。ListView で選択されたファイルと Files の ArrayList にあるファイルが正しく関連付けられたら、そのファイルのダウンロード URL から HTTP 要求を作成します。そして、execute を呼び出してファイルコンテンツのダウンロードを開始します。ファイルコンテンツは、InputStream 形式で返されます。

com.google.api.client.http.HttpResponse resp =
    mService.getRequestFactory()
    .buildGetRequest(new GenericUrl(tmp.getDownloadUrl()))
    .execute();
InputStream iStream = resp.getContent();
try
{
    final java.io.File file = new java.io.File(Environment
        .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(),
        tmp.getTitle());
    showToast("Downloading: " + tmp.getTitle() + " to " + Environment
        .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
    storeFile(file, iStream);
} finally {
    iStream.close();
}

InputStream は、デバイスの内部または外部ストレージ (SD カード) のディレクトリーにファイルを格納する OutputStream とともに使用できます。

private void storeFile(java.io.File file, InputStream iStream)
{
	try
	{
		final OutputStream oStream = new FileOutputStream(file);
		try
		{
			try
			{
				final byte[] buffer = new byte[1024];
				int read;
				while ((read = iStream.read(buffer)) != -1)
				{
					oStream.write(buffer, 0, read);
				}
				oStream.flush();
			} finally {
				oStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}

ストレージへの書き込みが終了したら、ユーザーは別のファイルをダウンロードしたり、新しいファイルをアップロードすることができます。

このほかにも、Google Drive* API には、ユーザーの Google Drive* アカウントに接続する魅力的な Android* アプリケーションの開発に役立つさまざまな機能があります。Google Drive* API の詳細は、https://developers.google.com/drive/v2/reference/ (英語) を参照してください。

著者紹介

Gideon は、インテル コーポレーションのソフトウェア & サービスグループ (SSG) に所属し、独立系ソフトウェア・ベンダー (ISV) と協力して、インテル® Atom™ プロセッサー向けにソフトウェアの最適化に取り組んでいます。以前は、Android* プラットフォーム向けの Linux* グラフィックス・ドライバーの開発に従事していました。

 
 
 
 

サンプルのダウンロード

添付ファイル サイズ
googledriveapp.zip 105.71KB

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事