草庐IT

android - 尽管有明确请求,但无法从 Google Plus 帐户获取私有(private)生日

coder 2023-12-13 原文

我正在尝试从其 Google Plus 帐户获取用户的信息,包括性别和年龄。由于这些字段可能是私有(private)的,我认为明确请求它们可以解决问题。然而,尽管登录对话框明确指出该应用程序请求查看您的完整出生日期,但我无法获得生日信息。

这些是我的范围(尝试了很多变化):

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

我错过了什么吗?或者即使明确请求也无法获取私有(private)数据?

谢谢。

顺便说一句,我还没有尝试过使用私有(private)性别的场景。

最佳答案

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

请注意:

If the request requires authorization (such as a request for an individual's private data), then the application must provide an OAuth 2.0 token with the request. The application may also provide the API key, but it doesn't have to.

Requests to the People API for non-public user data must be authorized by an authenticated user.

...

  1. If the user approves, then Google gives your application a short-lived access token.
  2. Your application requests user data, attaching the access token to the request.
  3. If Google determines that your request and the token are valid, it returns the requested data.

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

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


更新:假设您的应用可以使用我上面回答中的示例代码获取访问 token ,然后在 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提供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)

关于android - 尽管有明确请求,但无法从 Google Plus 帐户获取私有(private)生日,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37962724/

有关android - 尽管有明确请求,但无法从 Google Plus 帐户获取私有(private)生日的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  6. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby - 无法覆盖 irb 中的 to_s - 2

    我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)

  10. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

随机推荐