GoogleAuthUtilを使ってOAuth 2.0 tokenを取得する

GoogleAuthUtilを使ってOAuth 2.0 tokenを取得する
===============================================

GoogleアカウントでsigninしてGoogleのサービスを使うにはGoogleApiClientを使うのが手っ取り早く、tokenを意識することなく各種サービスにアクセスできる。ただ、tokenが必要なユースケースも依然としてあり、GoogleAuthUtilを使ってtokenを取得する必要が出てきたので、簡単な取得サンプルを作ってみた。

サンプルコードのポイントは

- sign-in起動用のボタン`button`と、取得したtoken表示用のTextView `token`を適当に画面にlayoutしておく。
- 既にSettings>Accountsで登録されているGoogleのアカウント名をAccountManager経由で読み出す。このためAndroidManifest.xmlにGET_ACCOUNTSのpermissionが必要。
- AsyncTaskでバックグラウンドでgoogle tokenを取得する。はじめてsign-inするときにはUserRecoverableAuthExceptionが返ってくるので、user consent画面をstartActivityForResult()する。


```java:MainActivity.java
package jp.gr.java_conf.fofn.googleauthutil;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

import java.io.IOException;

public class MainActivity extends Activity {

    private static final String TAG = "AUTH_SAMPLE";
    private static final String ACCOUNT_TYPE_GOOGLE = "com.google";
    private static final String AUTH_SCOPE = "oauth2:profile email";
    private static final int REQUEST_SIGN_IN = 10000;

    private String mAccountName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getGoogleToken(mAccountName);
            }
        });

        // Get google account
        AccountManager accountManager = AccountManager.get(this);
        Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE_GOOGLE);
        mAccountName = accounts[0].name; // it's better to open account chooser.
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SIGN_IN && resultCode == RESULT_OK) {
            getGoogleToken(mAccountName);
        }
    }

    private void getGoogleToken(String accountName) {

        AsyncTask<String, Void, String> task = new AsyncTask<String, Void, String> () {
            @Override
            protected String doInBackground(String... accounts) {
                String scopes = AUTH_SCOPE;
                String token = null;
                try {
                    token = GoogleAuthUtil.getToken(getApplicationContext(), accounts[0], scopes);
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                } catch (UserRecoverableAuthException e) {
                    startActivityForResult(e.getIntent(), REQUEST_SIGN_IN);
                } catch (GoogleAuthException e) {
                    Log.e(TAG, e.getMessage());
                }
                return token;
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                ((TextView) findViewById(R.id.token)).setText(s);
            }
        };

        task.execute(accountName);
    }
}
```