尽管明确要求,但无法从 Google Plus 帐户获取私人生日

Posted

技术标签:

【中文标题】尽管明确要求,但无法从 Google Plus 帐户获取私人生日【英文标题】:Cannot get private birthday from Google Plus account although explicit request 【发布时间】:2016-10-24 01:58:20 【问题描述】:

我正在尝试从其 Google Plus 帐户中获取用户的信息,包括性别和年龄。由于这些字段可能是私有的,我认为明确地请求它们可以解决问题。然而,虽然登录对话框明确指出应用程序请求View your complete date of birth,但我却没有得到生日。

这些是我的范围(尝试了许多变体):

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        //.requestScopes(new Scope(Scopes.PROFILE))
        //.requestScopes(new Scope(Scopes.PLUS_LOGIN))
        .requestScopes(new Scope("https://www.googleapis.com/auth/user.birthday.read"),
                new Scope("https://www.googleapis.com/auth/userinfo.profile"))
        //.requestProfile()
        .requestEmail()
        .build();

mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this, this)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .addApi(Plus.API)
        .addScope(new Scope(Scopes.PROFILE))
        .build();

onActivityResult 中使用已弃用的getCurrentPerson 时,我得到空值:

if (requestCode == RC_SIGN_IN) 
    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

    if (mGoogleApiClient.hasConnectedApi(Plus.API)) 
        Person person  = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
        if (person != null) 
            Log.i(TAG, person.getDisplayName());    //returns full name successfully
            Log.i(TAG, person.getGender());         //0
            Log.i(TAG, person.getBirthday());       //null
        
    

我也尝试从帐户 (GoogleSignInAccount account = result.getSignInAccount()) 中获取它,但据我搜索,此变量根本不拥有请求的数据。

我错过了什么吗?或者,尽管有明确的请求,但可能无法获取私有数据?

谢谢。

顺便说一句,我还没有尝试过私人性别的场景。

【问题讨论】:

【参考方案1】:

试试这个初始化

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

其他请求的用户需要公开显示生日。

【讨论】:

【参考方案2】:

我认为this Google People API documentation 会对您的问题有所帮助。

请注意:

如果请求需要授权(例如请求 个人的私人数据),则应用程序必须提供OAuth 2.0 令牌 与请求。应用程序也可以提供 API 密钥,但不是必须的。

对非公开用户数据的 People API 请求必须由经过身份验证的用户授权。

...

    如果用户批准,Google 会为您的应用程序提供一个短期的访问令牌。 您的应用程序请求用户数据,并将 访问令牌 附加到请求中。 如果 Google 确定 您的请求和令牌有效,它会返回请求的数据。

如果您的应用没有访问令牌,您可以阅读Using OAuth 2.0 to Access Google APIs 或尝试我对以下问题的回答:

How to get access token after user is signed in from Gmail in android?


更新:假设您的应用可以使用我上面答案中的示例代码获取访问令牌,然后在onResponse 中,添加更多的sn-ps,如下所示:

...
@Override
public void onResponse(Response response) throws IOException 
    try 
        JSONObject jsonObject = new JSONObject(response.body().string());
        final String message = jsonObject.toString(5);
        Log.i("onResponse", message);

        // FROM HERE...
        String accessToken = jsonObject.optString("access_token");

        OkHttpClient client2 = new OkHttpClient();
        final Request request2 = new Request.Builder()
                .url("https://people.googleapis.com/v1/people/me")
                .addHeader("Authorization", "Bearer " + accessToken)
                .build();

        client2.newCall(request2).enqueue(new Callback() 
            @Override
            public void onFailure(final Request request, final IOException e) 
                Log.e("onFailure", e.toString());
            

            @Override
            public void onResponse(Response response) throws IOException 
                try 
                    JSONObject jsonObject = new JSONObject(response.body().string());
                    final String message = jsonObject.toString(5);
                    Log.i("onResponse", message);
                 catch (JSONException e) 
                    e.printStackTrace();
                
            
        );
     catch (JSONException e) 
        e.printStackTrace();
    

...

Logcat 信息(由于它很长,我被截断了)

I/onResponse: 
                   "photos": [
                        
                             "url": "https:...photo.jpg",
                             "metadata": 
                                  "source": 
                                       "id": "1....774",
                                       "type": "PROFILE"
                                  ,
                                  "primary": true
                             
                        
                   ],
                   ...                                                                               
                   "birthdays": [
                        
                             "date": 
                                  "month": 2,
                                  "year": 1980,
                                  "day": 2
                             ,
                             "metadata": 
                                  "source": 
                                       "id": "1....774",
                                       "type": "PROFILE"
                                  ,
                                  "primary": true
                             
                        
                   ],
                   ....
              

GoogleSignInOptionsGoogleApiClient

String serverClientId = getString(R.string.server_client_id);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(new Scope("https://www.googleapis.com/auth/user.birthday.read"))
        .requestServerAuthCode(serverClientId)
        .build();

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

请注意,我这里使用的 OkHttp 版本是 v2.6.0,如果您的应用使用最新的(3.3.1),那么语法/类会有所不同。当然,你也可以使用其他的如 Volley、Retrofit...


此外,this Google's People API - Method people.get 提供 Try It 如下截图所示

其他有用的链接:

Google Developers Blog - Announcing the People API

Google APIs related to Google People API

Authorizing with Google for REST APIs (another way to get access token)

【讨论】:

请记住,问题是关于 Google plus api,他没有询问 people api。这可能有帮助,也可能没有帮助,但它不能回答他的问题 @DalmTo 对不起,如果我误解了 OP 的问题,看起来他没有提到 API。此外,他的代码还使用 PeopleApi insile Plus,现在已弃用 :) 无论如何都要删除我的答案以避免任何混淆。 我对这些以某种方式相关的 API 感到有些困惑。无论如何,您的链接和 sn-ps 很有用,我仍在深入研究它,一旦我确定它会发布一个完整的答案。谢谢! 关于这些Google的API,我想你可以阅读developers.googleblog.com/2016/02/announcing-people-api.html和developers.google.com/people/related-apis

以上是关于尽管明确要求,但无法从 Google Plus 帐户获取私人生日的主要内容,如果未能解决你的问题,请参考以下文章

如何从 google plus 帐户中注销 google plus 在 android 中的集成

从 android 应用程序共享后从 google plus 注销

无法在 ionic 3 项目的模块中导入 google plus 插件

尽管手动测试成功,但通过重力表单从 Google 广告点击中捕获的 UTM 参数仍然无效

应用在 Play 商店发布后,Google plus 登录和 Google 地图无法使用

无法使用 Google Plus 登录,出现 com.google.android.gms.common.api.ApiException: 10: