2011年12月14日

【Android】GoogleのOAuthをsignpostを使用して利用する

タイトルが長くなっちゃいましたね。
どれも必要なキーワードなので、入れてみたのですが、
もう少し短くしたかったです。

今回はいよいよコーディングへ入ります。
2つの.jarファイルはダウンロードしましたか?

Build Pathへはちゃんと指定されていますか?
Client IDとClient Secretは記録されていますか?

準備が整いましたら、続きを読んで下さい。



今回は1つのActivityしか使用しないので、
onCreateでいきなりブラウザへリダイレクトをかけましょう。

MainActivity.java

public class MainActivity extends Activity {
  private static final String CLIENT_ID     = "xxxxxxxx";
  private static final String CLIENT_SECRET = "xxxxxxxx";

  private static final String SCOPE         = "https://www.googleapis.com/auth/xxxxxxx";
  private static final String REQUEST_URL   = "https://www.google.com/accounts/OAuthGetRequestToken?scope=";
  private static final String ACCESS_URL    = "https://www.google.com/accounts/OAuthGetAccessToken";
  private static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?hd=default";

  private static final String CALLBACK = "myapp://callback";

  private OAuthConsumer consumer;
  private OAuthProvider provider;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {  
      consumer = new CommonsHttpOAuthConsumer(CLIENT_ID, CLIENT_SECRET);
      provider = new CommonsHttpOAuthProvider(REQUEST_URL + SCOPE, ACCESS_URL, AUTHORIZE_URL);
      String authUrl = provider.retrieveRequestToken(consumer, CALLBACK);
      startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
    } catch (OAuthMessageSignerException e) {
      e.printStackTrace();
    } catch (OAuthNotAuthorizedException e) {
      e.printStackTrace();
    } catch (OAuthExpectationFailedException e) {
      e.printStackTrace();
    } catch (OAuthCommunicationException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Uri uri = intent.getData();
    if (uri != null && uri.toString().startsWith(CALLBACK)) {
      final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
      try {
        provider.retrieveAccessToken(consumer, oauth_verifier);
        Log.d("ACCESS_TOKEN", consumer.getToken());
        Log.d("ACCESS_TOKEN_SECRET", consumer.getTokenSecret());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

では解説をいたします。

まず、SCOPEは用意されているGoogle APIごとに違います。
使用するAPIで調べて下さい。

signpostの使用として、customerとproviderを使用します。
宣言の仕方はonCreate内のように書きます。

CALLBACKには、Manifest.xmlで指定したschemeとhostから出来る文字列を指定します。
これで、ブラウザが"myapp://callback"というデータを紐づけたIntentを発行します。

provider.retrieveRequestToken(consumer, CALLBACK);
で、IDとパスワードを入力する為のページへのURLを作成します。
これをデータとして紐づけてIntentを発行しております。
これでブラウザが立ち上がります。

ブラウザで、IDとパスワードを入力すると、APIのアクセス許可をユーザに求めます。
許可を押すと、myapp://callbackへジャンプします。
この際、引数としてtoken等を保持しています。

myapp://callbackは通常のURLではありませんので、
AndroidのIntentManagerは受け取れるアプリを探します。
ここで、このアプリが受け取ると、onNewIntent(Intent intent)を実行します。
onNewIntentでtokenを解析して、
ACCESS_TOKENとACCESS_TOKEN_SECRETを取得します。

この2つのTOKENが取得できれば、
あとはこの2つを常にAPIに紐づけて引数として与えればアクセス出来るようになります。

何か例を書きたいですね。

いつか書いておきます。

よろしくお願いします。