web-dev-qa-db-ja.com

AndroidのGoogleサインインから性別などのプロファイルを取得する方法は?

私はアプリにグーグルサインインを統合したい、ユーザーが最初にサインインするとき、これにバインドするアカウントを作成するので、性別、ロケールなどのプロファイルが必要です。グーグルサインインドキュメントとクイック-startサンプルのショー:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

クリックしてサインインしたら、電話します:

  Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);

サインインに成功すると、onActivityResultのデータ構造GoogleSignInResultをGoogleSignInResultから取得できます。DisplayName、email、idのみを含むGoogleSignInAccountを取得できます。しかし https://developers.google.com/apis-Explorer/#p/ の場合、性別、ロケールなどのプロファイルを取得できます。見逃したものはありますか?

そして、私はグーグルプラスAPIを試しました、それは私が欲しいものを手に入れることができるようです。しかし、使用方法がわからない、ドキュメントは次のようにクライアントを作成すると言います:

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(new Scope(Scopes.PLUS_LOGIN))
            .addScope(new Scope(Scopes.PLUS_ME))
            .build();

しかし、これを使用すると、サインインボタンをクリックするとアプリがクラッシュします。

更新:Googleサインインの新しいバージョンへの更新時の問題 Googleサービス3.0.0でapi_key/current keyがありません

25
dx3904

更新:

Plus.PeopleApiはGoogle Play開発者サービス9.4では Googleの宣言ノート として廃止されているため、次のソリューションを使用してください- Google People API 代わりに:

Playサービス8.3の新しいGoogleサインインで個人情報を取得する (Isabella Chenの回答);

明示的な要求があるにもかかわらず、Google Plusアカウントから個人の誕生日を取得できません

更新終了


まず、GoogleアカウントのGoogle+プロフィールを作成したことを確認してください。その後、次のコードを参照できます。

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)             
                .requestScopes(new Scope(Scopes.PLUS_LOGIN))
                .requestEmail()
                .build();

そして

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .addApi(Plus.API)
                .build();

それから

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);

            // G+
            Person person  = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
            Log.i(TAG, "--------------------------------");
            Log.i(TAG, "Display Name: " + person.getDisplayName());
            Log.i(TAG, "Gender: " + person.getGender());
            Log.i(TAG, "AboutMe: " + person.getAboutMe());
            Log.i(TAG, "Birthday: " + person.getBirthday());
            Log.i(TAG, "Current Location: " + person.getCurrentLocation());
            Log.i(TAG, "Language: " + person.getLanguage());
        }
    }

内部build.gradleファイル

// Dependency for Google Sign-In
compile 'com.google.Android.gms:play-services-auth:8.3.0'
compile 'com.google.Android.gms:play-services-plus:8.3.0'

My GitHubサンプルプロジェクト をご覧ください。お役に立てれば!

30
BNK

Plusのものは非推奨です。今後は使用しないでください。これを行う方法は Google People API を使用してプロジェクトでこのAPIを有効にします。そうしないと、Studioでスローされる例外には、プロジェクトを直接有効にするためのリンクが含まれています(Nice)。

アプリのbuild.gradleに次の依存関係を含めます。

compile 'com.google.api-client:google-api-client:1.22.0'
compile 'com.google.api-client:google-api-client-Android:1.22.0'
compile 'com.google.apis:google-api-services-people:v1-rev4-1.22.0'

通常のように承認されたGoogleSignInを実行します。基本的なアカウントのもの以外のスコープやAPIは必要ありません。

GoogleSignInOptions.DEFAULT_SIGN_IN

.addApi(Auth.GOOGLE_SIGN_IN_API, gso)

メールとプロフィールのリクエストだけで十分です。

これで、サインインの結果が成功すると、メールを含むアカウントを取得できます(IDでこれを行うこともできます)。

final GoogleSignInAccount acct = googleSignInResult.getSignInAccount();

次に、新しい部分:AsyncTaskを作成して実行し、acctメールを取得した後に Google People API を呼び出します。

// get Cover Photo Asynchronously
new GetCoverPhotoAsyncTask().execute(Prefs.getPersonEmail());

AsyncTaskは次のとおりです。

// Retrieve and save the url to the users Cover photo if they have one
private class GetCoverPhotoAsyncTask extends AsyncTask<String, Void, Void> {
    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();

    // Retrieved from the sigin result of an authorized GoogleSignIn
    String personEmail;

    @Override
    protected Void doInBackground(String... params) {
        personEmail = params[0];
        Person userProfile = null;
        Collection<String> scopes = new ArrayList<>(Collections.singletonList(Scopes.PROFILE));

        GoogleAccountCredential credential =
                GoogleAccountCredential.usingOAuth2(SignInActivity.this, scopes);
        credential.setSelectedAccount(new Account(personEmail, "com.google"));

        People service = new People.Builder(httpTransport, jsonFactory, credential)
                .setApplicationName(getString(R.string.app_name)) // your app name
                .build();

        // Get info. on user
        try {
            userProfile = service.people().get("people/me").execute();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage(), e);
        }

        // Get whatever you want
        if (userProfile != null) {
            List<CoverPhoto> covers = userProfile.getCoverPhotos();
            if (covers != null && covers.size() > 0) {
                CoverPhoto cover = covers.get(0);
                if (cover != null) {
                    // save url to cover photo here, load at will
                    //Prefs.setPersonCoverPhoto(cover.getUrl());
                }
            }
        }

        return null;
    }
}

Person から入手できるものを次に示します。

コードをプロジェクトに貼り付ける場合は、インポートが正しく解決されることを確認してください。古いAPIの一部と重複するクラス名があります。

8
Michael Updike

ログイン後、次を実行します。

 Plus.PeopleApi.load(mGoogleApiClient, acct.getId()).setResultCallback(new ResultCallback<People.LoadPeopleResult>() {
        @Override
        public void onResult(@NonNull People.LoadPeopleResult loadPeopleResult) {
            Person person = loadPeopleResult.getPersonBuffer().get(0);

            LogUtil.d("googleuser: getGivenName " + (person.getName().getGivenName()));
            LogUtil.d("googleuser: getFamilyName " + (person.getName().getFamilyName()));
            LogUtil.d("googleuser: getDisplayName " + (person.getDisplayName()));
            LogUtil.d("googleuser: getGender " + (person.getGender() + ""));
            LogUtil.d("googleuser: getBirthday " + (person.getBirthday() + ""));
        }
    });
3
Frank

以下のようなGoogleサインインオプションを作成します。これは私に最適です

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestProfile()
            .requestScopes(new Scope(Scopes.PLUS_ME))
            .requestScopes(new Scope(Scopes.PLUS_LOGIN))
            .build();
2

解決策を見つけるのに少し時間を費やしたので、それを達成する現在の方法を共有させてください。

次のようなGoogleサインインオプションを拡張する必要があります。

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.google_client_id)) //like: '9241xyz.apps.googleusercontent.com'
            .requestEmail()
            .requestProfile()
            .requestServerAuthCode(getString(R.string.google_client_id))
            .build();

次に、応答として、GoogleSignInAccountでGoogleSignInResultオブジェクトを受け取ります。トークンIDと認証コードの両方をそこから抽出します。

private void handleGoogleSignInResult(GoogleSignInResult result) {
    if (result.isSuccess()) {
        GoogleSignInAccount acct = result.getSignInAccount();
        String authCode = acct.getServerAuthCode();
        String idToken = acct.getIdToken();
    }
}

次に行う必要があるのは、POST request:

POST https://www.googleapis.com/oauth2/v4/token
Body (x-www-form-urlencoded):
grant_type authorization_code
client_id 9241xyz.apps.googleusercontent.com
client_secret MNw...fMO
redirect_uri ""
code auth_code_from_google_account
id_token id_token_from_google_account

リクエストはAndroid appで行うことができますが、client_secretをAndroid app。このようなリクエストに対する応答は次のようになります。

{
"access_token": "ya29.GluIBuHTXZ...kTglmCceBG",
"expires_in": 3552,
"scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsImt....V6EAlQd3-Y9CQ"
}

次に、ユーザーの詳細についてユーザープロファイルエンドポイントを照会できます。

GET https://www.googleapis.com/oauth2/v3/userinfo
Headers:
Authorization : Bearer ya29.GluIBuHTXZ...kTglmCceBG

応答は次のようになります。

{
"sub": "107...72",
"name": "Johny Big",
"given_name": "Johny",
"family_name": "Big",
"profile": "https://plus.google.com/107417...990272",
"picture": "https://lh3.googleusercontent.com/-....IxRQ/mo/photo.jpg",
"email": "[email protected]",
"email_verified": true,
"gender" : "male",
"locale": "en"
}

ただし、ユーザーが自分に関する情報へのパブリックアクセスを持っていない場合、性別フィールドはここにありません。おそらく、Googleサインインリクエストで追加のスコープを要求する必要がありますが、私はチェックしませんでした。 (共有オプションはGoogleアカウントページの下にあります: https://myaccount.google.com/personal-info

0
pkleczko