Android 集成 google 登录并获取性别等隐私信息的实现代码
前言
公司做海外产品的,集成的是 google 账号登录,账号信息、邮箱等这些不涉及隐私的按 google 的正常登录流程可以轻松实现 。但是一旦需要获取涉及隐私的信息就比较麻烦,文档也不是十分清晰,非常难找,很多坑。
google 账号登录
官方链接:https://developers.google.com/identity/sign-in/android/start
https://developers.google.com/identity/sign-in/android/sign-in
google 账号登录接入的坑:
- 申请的
client_id
必须是 api console 后台 :https://console.cloud.google.com/apis 与 google play 后台对应的应用关联起来。 client_id
下的签名信息和报名信息必须和测试时的 apk 的签名信息和报名信息一致。- 在 google play 下启动 google 的二次签名,则 api console 后台的签名信息是二次签名后的信息。打包测试时使用上传 到 Google play 后台的 apk 的签名证书即可。
google 登录的流程在这个文档写的比较清楚了:https://developers.google.com/identity/sign-in/android/sign-in,这里大致说一下,不贴代码了
构建需求请求的内容:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .requestIdToken("your client_id") .build(); // Build a GoogleSignInClient with the options specified by gso. mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
2.发起登录请求,跳转 google 登录页面。
Intent signInIntent = mGoogleSignInClient.getSignInIntent(); startActivityForResult(signInIntent, RC_SIGN_IN);
获取 Google 登录返回
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { // The Task returned from this call is always completed, no need to attach // a listener. Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); handleSignInResult(task); } }
获取 用户 id token,传到你自己的 服务端 做验证
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) { try { GoogleSignInAccount account = completedTask.getResult(ApiException.class); // Signed in successfully, show authenticated UI. } catch (ApiException e) { // The ApiException status code indicates the detailed failure reason. // Please refer to the GoogleSignInStatusCodes class reference for more information. Log.w(TAG, "signInResult:failed code=" + e.getStatusCode()); } }
切换账号
/** * 重新获取账号列表 */ public void revokeAccess() { try { if (mGoogleSignInClient!=null && mActivity!=null){ mGoogleSignInClient.revokeAccess().addOnCompleteListener(mActivity, new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Log.d(TAG, "onComplete: "); } }); } } catch (Exception e){ e.printStackTrace(); } }
获取公开资料和需要特别授权的信息(性别、生日等)
1、在构建请求是新增获取 的公共资料信息 及 需要获取的特殊信息
private static final String GENDER_SCOPE = "https://www.googleapis.com/auth/user.gender.read"; GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .requestIdToken("your client_id") .requestScopes(new Scope(GENDER_SCOPE)); .build(); // Build a GoogleSignInClient with the options specified by gso. mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
需要请求的信息可在如下链接查找:https://developers.google.com/people/api/rest/v1/people/get
2、检测是否有权限
GoogleSignInAccount lastSignedInAccount = GoogleSignIn.getLastSignedInAccount(mActivity); Scope scope = new Scope(GENDER_SCOPE); if (Utils.isNeedRequest() && !GoogleSignIn.hasPermissions(lastSignedInAccount,scope)){ SGLog.d(TAG+" need requst permission..."); GoogleSignIn.requestPermissions(mActivity,RC_GET_TOKEN,lastSignedInAccount,scope); }
注意:这一步不需要也可以,有这一步会出现一个 “再确认” 的授权页面,没有也不影响获取的信息。
3、跳转登录页面 (同以上 google 账号登录)
4、获取登录信息 (同以上 Google账号登录)
5、开启线程获取 特殊信息
getProfileAsyncTask = new GetProfileAsyncTask(mActivity, new GpProfileInfoCallback() { @Override public void onGetProfileInfo(Person person) { SGLog.d(TAG+" onGetProfileInfo... "); getProfileInfo(person); } }); getProfileAsyncTask.execute(signInAccount);
异步任务
// Global instance of the HTTP transport private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport(); // Global instance of the JSON factory private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private static class GetProfileAsyncTask extends AsyncTask<GoogleSignInAccount, Void, Person> { // Retrieved from the sigin result of an authorized GoogleSignIn private WeakReference<Activity> mActivityRef; private GpProfileInfoCallback mProfileInfoCallback; public GetProfileAsyncTask(Activity activity,GpProfileInfoCallback callback) { mActivityRef = new WeakReference<>(activity); mProfileInfoCallback = callback; } @Override protected Person doInBackground(GoogleSignInAccount... params) { if (mActivityRef.get() == null){ SGLog.d(TAG+" GetProfileAsyncTask doInBackground activity is null."); return null; } GoogleSignInAccount signInAccount = params[0]; Context context = mActivityRef.get().getApplicationContext(); GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2( context, Collections.singleton(GENDER_SCOPE)); credential.setSelectedAccount(signInAccount.getAccount()); SGLog.d(TAG+" get profile info start."); PeopleService service = new PeopleService.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(ApkUtils.getAppName(context)) // your app name .build(); SGLog.d(TAG+" get profile info start."); // Get info. on user Person person =null; try { person = service .people() .get("people/me") .setPersonFields("genders") .execute(); SGLog.d(TAG+" getPerson end."); // return the result if (mProfileInfoCallback!=null){ mProfileInfoCallback.onGetProfileInfo(person); } } catch (Exception e) { SGLog.e(TAG+e.getMessage()); if (mProfileInfoCallback!=null){ mProfileInfoCallback.onGetProfileInfo(null); } e.printStackTrace(); } return person; } @Override protected void onPostExecute(Person aVoid) { super.onPostExecute(aVoid); } }
获取性别信息
private void getProfileInfo(Person person){ SGLog.d(TAG+" executeProfileInfo..."); if (person == null){ notifyResult(mLastUser,Utils.SUCCESS); }else { try { List<Gender> genders = person.getGenders(); Gender gender = genders.get(0); String value = gender.getValue(); SGLog.d(TAG+" genders:"+genders.size()+ " gender:"+value); mLastUser.setGender(value); notifyResult(mLastUser,Utils.SUCCESS); }catch (Exception e){ SGLog.e(TAG+" getProfileInfo error."); notifyResult(null,SGErrorCode.LOGIN_FAILED); e.printStackTrace(); } } }
参考文献:
https://developers.google.com/identity/sign-in/android/sign-in
https://developers.google.cn/android/guides/http-auth
https://developers.google.com/people/api/rest/?apix=true
https://github.com/googlesamples/google-services/tree/master/android/signin
https://developers.google.com/people/api/rest/v1/people/get
总结
栏 目:Android代码
本文标题:Android 集成 google 登录并获取性别等隐私信息的实现代码
本文地址:http://www.codeinn.net/misctech/161731.html