!!!ネット上のサンプルをいじったバージョン
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}}