尝试使用来自 Google 帐户的人 API 获取用户信息时出错?

Error when trying to get user information using people API from googleAccount?

我正在尝试从 google 获取用户帐户信息,例如生日、性别和其他用户数据,但在使用人 API

时出现此异常
W/System.err: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "The request is missing a valid API key.",
    "reason" : "forbidden"
  } ],
  "message" : "The request is missing a valid API key.",
  "status" : "PERMISSION_DENIED"
}

我不知道在哪里添加我的 api 键来解决我的异常 这是我的代码

package com.example.MyApp.ui.activities;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.example.myApp.R;
import com.example.myApp.utils.PreferenceController;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleBrowserClientRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.people.v1.PeopleService;
import com.google.api.services.people.v1.model.Person;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class LoginActivity extends AppCompatActivity {
    private final String TAG = "LoginActivity";
    private SignInButton loginWithGoogleAccountBtn;
    private static final int RC_SIGN_IN = 1;
    AccountManager accountManager;
    GoogleSignInClient mGoogleSignInClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
// Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        loginWithGoogleAccountBtn = findViewById(R.id.loginWithGoogleAccountBtn);
        loginWithGoogleAccountBtn.setSize(SignInButton.SIZE_STANDARD);
        loginWithGoogleAccountBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signIn();


            }

        });
    }

    private void signIn() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    protected void onStart() {
        super.onStart();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        if (account != null) {
            Toast.makeText(this, "account : " + account.getDisplayName() + " : email " + account.getEmail() + "account id " + account.getId(), Toast.LENGTH_SHORT).show();
            try {
                getAccountData(account);
            } catch (IOException e) {
                e.printStackTrace();
            }
            redirectToMain();
        }
    }

    public void getAccountData(final GoogleSignInAccount account) throws IOException {
        Thread myThread = new Thread() {
            @Override
            public void run() {
                HttpTransport httpTransport = new NetHttpTransport();
                JacksonFactory jsonFactory = new JacksonFactory();
                String clientId = Constant.CLIENT_ID;
                String clientSecret = Constant.CLIENT_SECRET;
                GoogleCredential credential = new GoogleCredential.Builder()
                        .setTransport(httpTransport)
                        .setJsonFactory(jsonFactory)

                        .setClientSecrets(clientId, clientSecret)
                        .build();

                PeopleService peopleService =
                        new PeopleService.Builder(httpTransport, jsonFactory, credential).setApplicationName("MyApp").
                                build();
                try {

                    Person profile = peopleService.people().get("people/" + account.getId())
                            .setPersonFields("names,genders")
                            .setAccessToken(account.getIdToken())
                            .execute();

                    Log.i(TAG, profile.getGenders().get(0).getValue());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        myThread.start();


    }


    private void redirectToMain() {

        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

        } catch (ApiException e) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            e.printStackTrace();
            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data
        if (requestCode == RC_SIGN_IN) {
            Log.i(TAG, "onActivityResult: ");
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }

    }
}

从 Intent 获取 google 帐户后我的个人对象出现异常异常出现在此处

Person profile = peopleService.people().get("people/" + account.getId())
                        .setPersonFields("names,genders")
                        .setAccessToken(account.getIdToken())
                        .execute();

调用account.getIdToken()时,其返回值为null

那是因为在创建您的 GoogleSignIn 时,您没有请求 ID 令牌。

Id Token 必须显式请求,您可以按如下方式进行:

  • 替换以下代码:
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                                                     .requestEmail()
                                                     .build();
    
    对于以下内容:
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                                                     .requestIdToken("YOUR_OAUTH_CLIENT_ID")
                                                     .requestEmail()
                                                     .build();
    
    YOUR_OAUTH_CLIENT_ID 字符串应替换为您的实际 OAuth 客户端 ID。