40
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google APIs Client Library for JavaからGoogle Drive APIを使用する

Last updated at Posted at 2014-05-11

AndroidからGoogle DriveのAPIを使用する場合、Google Play Serviceに統合されたGoogle Drive APIを利用するのが楽です。
が、現状では自アプリ作成したファイル/フォルダの操作のみしかできないため、それ以外のことをする場合にはGoogle APIs Client Library for Javaを利用する必要があります。

上記にも接続と認証を行う際のスニペットが載っていますが、不完全で分かりにくかったため利用方法のメモ書きです。

##下準備

アプリケーション登録

Google Developers Consoleで作成するAndroidアプリの登録を行っておきます。
以下を参照して、Client IDを新規追加してください。
https://developers.google.com/drive/android/auth

jar

以下からLibraryのダウンロード(Android Studioの場合はimport設定)を行います。
https://developers.google.com/api-client-library/java/apis/drive/v2

Eclipseでの開発の場合、ダウンロード後のzipを解凍し、
readme.htmlに記載されている通り、以下のjarをlibs下に配置します。

google-api-services-drive-v2-rev123-1.18.0-rc.jar (※)
google-api-client-1.18.0-rc.jar
google-oauth-client-1.18.0-rc.jar
google-http-client-1.18.0-rc.jar
jsr305-1.3.9.jar
google-http-client-gson-1.18.0-rc.jar
gson-2.1.jar
google-api-client-android-1.18.0-rc.jar
google-http-client-android-1.18.0-rc.jar

※のみをプロジェクトのプロパティからJava Build PathのLibrariesに追加する

依存ライブラリ

Google Play Service用ライブラリプロジェクトに依存が必要です。
http://developer.android.com/google/play-services/setup.html

Permission

以下を追加します。

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

MetaData

Google Play Serviceを利用するために以下を追加します。

AndroidManifest.xml
   <application
      ...>
       <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
   </appliction>

実装

以下の流れで接続と認証、API呼び出しを行います。

  1. アカウント選択ダイアログ呼び出し用のIntentを発行
  2. Drive APIを呼び出す
  3. 2のとき、認証が必要な場合にExceptionが発生するので認証用のIntentを発行
  4. 認証後、Drive APIを再呼び出し

1については、一度接続したアカウント名をPreference等に保存しておき、設定することも可能です。

Activity.java
package com.example.googledriveapisample;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAuthIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class MainActivity extends Activity {

	private static final String TAG = MainActivity.class.getSimpleName();
	
    private static final int REQUEST_ACCOUNT_PICKER = 1;
    
    private static final int REQUEST_AUTHORIZATION = 2;

    private GoogleAccountCredential mCredential;
	
	private Drive mDriveService;
	
	private List<File> mFileList = new ArrayList<File>();
	
	private Handler mHandler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mHandler = new Handler();
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		
		setupDriveService();
	}
	
	private void setupDriveService() {
        mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE));
    	if (mDriveService == null) {
    		// 保存済みのアカウント名を取得(xxx@gmail.com)
    		String accountName = getSavedAccountName();
    		if (accountName.isEmpty()) {
    			// アカウント名がなければアカウント選択ダイアログ表示用のIntentを発行
    			startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
    		} else {
    			// アカウント名がある場合
    			mCredential.setSelectedAccountName(accountName);
    			// DriveAPI用のインスタンス生成
    			mDriveService = getDriveService();
    			// Drive API呼び出し
    			callDriveApi();
    		}
    	}
	}
	
	private void callDriveApi() {
		// 非UIスレッドで呼び出す
		// (AsyncTask等でAPI呼び出し用の基底クラスをつくって認証が必要な場合の処理を実施したほうが良い)
		(new Thread(new Runnable() {
			@Override
			public void run() {
				mFileList.clear();
				try {
					// ファイル一覧を取得したい場合
					Files.List request = mDriveService.files().list();
					// クエリ文字列をセット(以下はMIMETYPEを指定)
					request.setQ("mimeType = 'audio/mpeg'");

					do {
						// API呼び出し
						FileList files = request.execute();
						// 取得したFileリストを保持用のメンバーにセット
						mFileList.addAll(files.getItems());
						// 全アイテムを取得するために繰り返し
						request.setPageToken(files.getNextPageToken());
					} while (request.getPageToken() != null
							&& request.getPageToken().length() > 0);

					for (File f : mFileList) {
						Log.d(TAG, f.getTitle());
					}
					
				} catch (UserRecoverableAuthIOException e) {
					// 認証が必要な場合に発生するException
					// これが発生したら認証のためのIntent発行を行い、認証後、DriveAPIを再呼び出しする
					final Intent authIntent = e.getIntent();
					mHandler.post(new Runnable() {
						@Override
						public void run() {
							startActivityForResult(authIntent, REQUEST_AUTHORIZATION);
						}
					});
				} catch (GoogleAuthIOException e) {
					// Developer ConsoleでClientIDを設定していない場合に発生する
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		})).start();
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_ACCOUNT_PICKER:
			if ((resultCode == RESULT_OK) && (data != null)) {
				// 選択されたアカウント名を取得
				String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
	            if (accountName != null) {
	                mCredential.setSelectedAccountName(accountName);
	                mDriveService = getDriveService();
	                // Drive API呼び出し
	                callDriveApi();
	                // 必要ならアカウント名を保存しておく
	                saveAccountName(accountName);
	            }			
	        } else {
				// エラー処理
			}
			break;
			
		case REQUEST_AUTHORIZATION:
			if (resultCode == RESULT_OK) {
				// 認証に成功したのでDrive APIを再呼び出し
				callDriveApi();
			} else {
				// エラー処理
			}
			break;
		}
	}
		
	private Drive getDriveService() {
    	return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), mCredential).build();
	}
	
	private String getSavedAccountName() {
		SharedPreferences prefs = getSharedPreferences("prefs_name", Context.MODE_PRIVATE);
		return prefs.getString("key_account_name", "");
	}
	
	private void saveAccountName(final String accountName) {
		SharedPreferences prefs = getSharedPreferences("prefs_name", Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString("key_account_name", accountName);
		editor.commit();
	}
}

参考

Google Play Service用の認証方法との住み分けについて
http://stackoverflow.com/questions/22142641/access-to-google-api-googleaccountcredential-usingoauth2-vs-googleauthutil-get

40
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?