虽然明确要求,但无法通过Google Plus帐户获得私人生日

时间:2016-06-22 08:37:51

标签: android google-play-services google-plus google-signin google-plus-signin

我正在尝试从其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();

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

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())获取它,但据我搜索过,此变量根本不拥有所请求的数据。

我错过了什么吗?或者,虽然明确的请求可能无法获取私人数据?

感谢。

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

2 个答案:

答案 0 :(得分:4)

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

请注意:

  

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

  

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

     

...

     
      
  1. 如果用户批准,那么Google会为您的应用提供短暂的访问令牌
  2.   
  3. 您的应用程序请求用户数据,将访问令牌附加到请求中。
  4.   
  5. 如果Google确定了这一点   您的请求和令牌有效,它会返回请求的数据。
  6.   

如果您的应用尚未获得访问令牌,您可以阅读Using OAuth 2.0 to Access Google APIs或在以下问题中尝试我的回答:

  

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

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

...
@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提供了试一试,如下面的截图

enter image description here

其他有用的链接:

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)

答案 1 :(得分:0)

尝试初始化

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

否则请求用户需要公开查看生日。