!!!ネット上のサンプルをいじったバージョン http://li4shi2.wordpress.com/2011/08/21/picasa%E3%81%AB%E7%94%BB%E5%83%8F%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B%EF%BC%88android%EF%BC%89/ http://tomokey.blogspot.jp/2011/06/javaoauth.html !必要なパーミッション !必要なライブラリ libs ディレクトリに {{ref libs.zip}} を展開して jar ファイルを入れておく必要がある。 !アカウント選択 {{code Java, public void selectAccount(final OnSelectAccountListener listener){ AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle("Select a Google account"); final AccountManager manager = AccountManager.get(activity); final Account[] accounts = manager.getAccountsByType("com.google"); final int size = accounts.length; String[] names = new String[size]; for (int i = 0; i < size; i++) { names[i] = accounts[i].name; } // names[size] = "New Account"; builder.setItems(names, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == size) { // addAccount(manager); // listener.onSelect(); } else { listener.onSelect(accounts[which]); // gotAccount(manager, accounts[which]); } } }); builder.create().show(); } }} !取得したアカウントで Authトークン取得 {{code Java, public boolean authenticate(Account account, boolean clearCache, boolean retry ){ AccountManager manager = AccountManager.get(activity); if (clearCache){ manager.invalidateAuthToken("com.google", this.authToken); } try { Bundle bundle = manager.getAuthToken(account, PicasaWebAlbums.AUTH_TOKEN_TYPE, true, null, null).getResult(); if (bundle.containsKey(AccountManager.KEY_INTENT)) { Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT); int flags = intent.getFlags(); flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; intent.setFlags(flags); activity.startActivityForResult(intent, REQUEST_AUTHENTICATE); return false; } else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) { this.authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); this.account = account; transport.setClientLoginToken(this.authToken); return true; } return false; } catch (Exception e){ if (retry){ return reauthenticate(e, account); } else { return false; } } } private boolean reauthenticate(Exception e, Account account) { // e.printStackTrace(); if (e instanceof HttpResponseException) { int statusCode = ((HttpResponseException) e).response.statusCode; if (statusCode == 401 || statusCode == 403) { return authenticate(account, true, false); } } return false; } }} Authトークンは、一定時間で無効になる。その場合は AccountManager#invalidateAuthToken() してから、 AccountManager#getAuthToken() する。また、Authトークンが無効な状態でアクセスすると HttpResponseException が発生し、 response.statusCode が 401 か 403 になる・・・はず。 !!!AndroidのAccountManager経由でGoogleのOAuth2認証を行う http://kinsentansa.blogspot.jp/2012/08/androidaccountmanagergoogleoauth2.html http://kinsentansa.blogspot.jp/2012/04/androidgoogleoauth2.html !必要なパーミッション !アカウント選択 {{code Java, protected static final String ACCOUNT_TYPE = "com.google"; protected void chooseAccount() { Log.v("chooseAccount", "AuthToken取得開始(アカウント選択)"); accountManager.getAuthTokenByFeatures(ACCOUNT_TYPE, authTokenType, null, AccountManagerOAuth2Activity.this, null, null, new AccountManagerCallback() { public void run(AccountManagerFuture future) { onGetAuthToken(future); } }, null); } }} !アカウント名取得 {{code Java, Bundle bundle = future.getResult(); accountName = bundle.getString(AccountManager.KEY_ACCOUNT_NAME); }} !トークン取得 {{code Java, protected static final int REQUEST_CODE_AUTH = 0; protected void getAuthToken() { Account account = null; Account[] accounts = accountManager.getAccounts(); for (int i = 0; i < accounts.length; i++) { account = accounts[i]; if (account.name.equals(accountName)) { break; } } Log.v("getAuthToken", "AuthToken取得開始"); accountManager.getAuthToken(account, authTokenType, true, new AccountManagerCallback() { public void run(AccountManagerFuture future) { try { Bundle bundle = future.getResult(); if (bundle.containsKey(AccountManager.KEY_INTENT)) { //まだAPIアクセス許可が出ていない場合にgetAuthToken()すると //BundleにKEY_INTENTが含まれる。この場合AuthTokenはNULLとなる。 Log.v("getAuthToken", "アクセス許可画面へ"); Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT); //「FLAG_ACTIVITY_NEW_TASK」の前の「~」はビット反転演算子 //これをしないとアクセス許可画面でのボタンクリックを待たずにonActivityResult()が呼ばれてしまう intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK); startActivityForResult(intent, REQUEST_CODE_AUTH); } else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) { onGetAuthToken(future); } } catch (Exception e) { Log.v("getAuthToken", "AuthToken取得失敗", e); } } }, null); } }} !Authトークン取得時に Activity に処理が流れた場合 {{code Java, protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.v("onActivityResult", "requestCode=" + requestCode + " resultCode=" + resultCode); switch (requestCode) { case REQUEST_CODE_AUTH: if (resultCode == RESULT_OK) { getAuthToken(); } else { Log.v("onActivityResult", "アクセス許可画面で拒否された"); } break; } } }} resultCode == RESULT_OK になれば Authトークン取得の準備が完了する。 再度、getAuthTokenを呼び accountManager.getAuthToken で Authトークンを取得する。 !Authトークンについて authTokenは一定期間過ぎると無効になるので再取得する必要がある。 一定時間が過ぎたauthTokenを使ってAPIにリクエストすると「"code":401」を含むjsonが返される。 {{category2 プログラミング言語,Java,Android}}