LoginSignup
13
12

More than 5 years have passed since last update.

Google Sign-In

Last updated at Posted at 2015-04-23

転載元: Android : Google Sign-In

Prerequisites

  • Android 2.3 以上, あるいは最新のGoogle Play Storeを搭載していること.
  • 最新のAndroid SDK Toolsをインストールしていること.
  • Google Play Service SDKをインストールしていること.
  • コンパイルバージョンがAndroid2.3以上であること.

Step 1: Google Sign-In APIの有効化

  1. Google Developers Consoleへ移動
  2. プロジェクトを作成する
  3. AndroidアプリケーションとしてクライアントIDを作成する

NOTE

デバッグ用.keystoreのSHA1ハッシュを確認するには次のコマンドを参照.

keytool -exportcert -alias androiddebugkey -keystore path-to-debug-or-production-keystore -list -v

デバッグ用.keystoreはMacだと~/.android/debug.keystore. Windowsでは%USERPROFILE%\.android\debug.keystoreに標準で格納されている.

デバッグ用keystoreのパスワードはandroid.

Step 2: Android Studio Project の設定

build.gradleのdependenciesセクションにGoogle Play Serviceを追加.


dependencies {
    compile 'com.google.android.gms:play-services:7.0.0'
}

Step 3: Permission宣言

アプリケーションが使用するGoogle Play ServiceのバージョンをAndroidManifestのapplicationタグ配下に宣言する.

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

Google APIにアクセスするためINTERNETパーミッションを宣言する.

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

アカウント名を取得するためGET_ACCOUNTパーミッションを宣言する.

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

OAuth 2.0 tokenを取得するためUSE_CREDENTIALSパーミッションを宣言する.

<uses-permission android:name="android.permission.USE_CREDENTIALS" />

GoogleApiClient の初期化

GoogleApiClientはGoogle Play Serviceに接続されるServiceConnectionのラッパーとして作用する.
GoogleApiClientはGoogle Sign-In APIと通信し, 非同期通信によりサービスを有効化した後機能する. そのためには,

  • Google Play Serviceがデバイス上で実行されており, あなたのActivityがService connectionに接続できていること.
  • ユーザがあなたのアプリでアカウントを選択し, ユーザのアカウントがあなたのアプリに権限を与えていること.

GoogleApiClientのライフサイクルをActivityのライフサイクルの中で管理するための一般的な方法は下記.

  1. Activity.onCreateでGoogleApiClientを初期化
  2. Activity.onStartでGoogleApiClient.connectを起動
  3. Activity.onStopでGoogleApiClient.disconnectを起動

これを実行するとActivityにはコネクションが有効化あるいは接続失敗したことがConnectionCallbacksとOnConnectionFailedListenerに通知される.

addScopeメソッドでアプリが許容を求めるスコープを定義できる.

  • 基本的なプロフィール情報が必要であればprofile
  • ユーザのGoogle account emailアドレスが必要であればemail
import android.app.Activity;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.view.View;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.plus.Plus;

public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        View.OnClickListener {

    /* Request code used to invoke sign in user interactions. */
    private static final int RC_SIGN_IN = 0;

    /* Client used to interact with Google APIs. */
    private GoogleApiClient mGoogleApiClient;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Plus.API)
                .addScope(new Scope("profile"))
                .build();

       findViewById(R.id.sign_in_button).setOnClickListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onClick(View v) {
      // ...
    }

    // ...

  }

GoogleApiClientがコネクションを有効化できなかった時, onConnectionFailedのコールバックが呼ばれる. これにはConnectionResultが渡されるためエラーの解決に使用できる. ConnectionResult.getResolution()を呼ぶとユーザにアカウントを選択する操作を促すためのPendingIntentを得ることができる.
(例えば年とワーク接続を有効かするように求めたり, アカウントの選択をユーザに求めたりする)

@Override
public void onConnectionFailed(ConnectionResult result) {
  if (!mIntentInProgress && result.hasResolution()) {
    try {
      mIntentInProgress = true;
      result.startResolutionForResult(this, RC_SIGN_IN);
    } catch (SendIntentException e) {
      // The intent was canceled before it was sent.  Return to the default
      // state and attempt to connect to get an updated ConnectionResult.
      mIntentInProgress = false;
      mGoogleApiClient.connect();
    }
  }
}

@Override
public void onConnected(Bundle connectionHint) {
  // We've resolved any connection errors.  mGoogleApiClient can be used to
  // access Google APIs on behalf of the user.
}

@Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
  if (requestCode == RC_SIGN_IN) {
    mIntentInProgress = false;

    if (!mGoogleApiClient.isConnected()) {
      mGoogleApiClient.reconnect();
    }
  }
}

クライアントのサービス接続が確立されたらGoogleApiClient.disconnectをonStopメソッドの中で呼び出しこれを切断する必要がある.

Google Play ServiceはActivityがサービスコネクションをロストした際に呼ばれるonConnectionSuspendedコールバックを呼び出す. 一般的にこの場合はユーザが解決を試みることができるようにサービスへの再接続を試みる.

@Override
public void onConnectionSuspended(int cause) {
  mGoogleApiClient.connect();
}

Google Sign-In ボタンの追加

  1. アプリケーションのレイアウトにSignInButtonを追加
<com.google.android.gms.common.SignInButton
    android:id="@+id/sign_in_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
  1. OnClickListenerを登録する
findViewById(R.id.sign_in_button).setOnClickListener(this);
  1. Sign-Inボタンを使用するにはActivityのSign-Inフローを変更する必要がある. ActivityがOnCnnectionFaildコールバックを受け取ったらすぐに問題解決のためのユーザインタラクションを開始する. Activityはその間Sing-inボタンのクリックを抑止するべき.
/**
 * True if the sign-in button was clicked.  When true, we know to resolve all
 * issues preventing sign-in without waiting.
 */
private boolean mSignInClicked;

/**
 * True if we are in the process of resolving a ConnectionResult
 */
private boolean mIntentInProgress;

@Override
public void onConnectionFailed(ConnectionResult result) {
  if (!mIntentInProgress) {
    if (mSignInClicked && result.hasResolution()) {
      // The user has already clicked 'sign-in' so we attempt to resolve all
      // errors until the user is signed in, or they cancel.
      try {
        result.startResolutionForResult(this, RC_SIGN_IN);
        mIntentInProgress = true;
      } catch (SendIntentException e) {
        // The intent was canceled before it was sent.  Return to the default
        // state and attempt to connect to get an updated ConnectionResult.
        mIntentInProgress = false;
        mGoogleApiClient.connect();
      }
    }
  }
}
  1. ユーザがSign-Inボタンをクリックした後, mSignInClickedフラグをセットし, onConnectionFailedで接続エラーを解決する必要がある. 解決可能なエラーはユーザにサービスへの接続とアプリへの権限承認を促す.
public void onClick(View view) {
  if (view.getId() == R.id.sign_in_button && !mGoogleApiClient.isConnecting()) {
    mSignInClicked = true;
    mGoogleApiClient.connect();
  }
}
  1. 接続が確立された場合はmSignInClickedフラグをリセットする.
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
  if (requestCode == RC_SIGN_IN) {
    if (responseCode != RESULT_OK) {
      mSignInClicked = false;
    }

    mIntentInProgress = false;

    if (!mGoogleApiClient.isConnected()) {
      mGoogleApiClient.reconnect();
    }
  }
}
  1. ユーザがSign-Inを無事終えるとonConnectedが呼ばれる. この時点でユーザの名前を取得するか認証リクエストを作成することができる.
@Override
public void onConnected(Bundle connectionHint) {
  mSignInClicked = false;
  Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
}

以上.

13
12
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
13
12