我从https://developers.google.com/+/mobile/android/getting-started学习了google plus登录
当我启动我的应用程序时,有一个Toast消息"用户已连接!" 然后我按下G +登录按钮我的应用程序强制关闭.
这是logcat的消息形式
04-08 18:31:21.680 24231-24231/app.umitems.test.testgoogleplus1.app D/? onClick() 04-08 18:31:21.680 24231-24231/app.umitems.test.testgoogleplus1.app D/AndroidRuntime? Shutting down VM 04-08 18:31:21.680 24231-24231/app.umitems.test.testgoogleplus1.app W/dalvikvm? threadid=1: thread exiting with uncaught exception (group=0x41f99ce0) 04-08 18:31:21.685 24231-24231/app.umitems.test.testgoogleplus1.app E/AndroidRuntime? FATAL EXCEPTION: main Process: app.umitems.test.testgoogleplus1.app, PID: 24231 java.lang.NullPointerException at app.umitems.test.testgoogleplus1.app.ExampleActivity.resolveSignInError(ExampleActivity.java:68) at app.umitems.test.testgoogleplus1.app.ExampleActivity.onClick(ExampleActivity.java:166) at com.google.android.gms.common.SignInButton.onClick(Unknown Source) at android.view.View.performClick(View.java:4445) at android.view.View$PerformClick.run(View.java:18446) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5081) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607) at dalvik.system.NativeStart.main(Native Method)
这是我的代码
package app.umitems.test.testgoogleplus1.app; import android.app.Activity; import android.content.Intent; import android.content.IntentSender; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.plus.Plus; public class ExampleActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { /* Request code used to invoke sign in user interactions. */ private static final int RC_SIGN_IN = 0; /* Client used to interact with Google APIs. */ private GoogleApiClient mGoogleApiClient; /* A flag indicating that a PendingIntent is in progress and prevents * us from starting further intents. */ private boolean mIntentInProgress; /* Track whether the sign-in button has been clicked so that we know to resolve * all issues preventing sign-in without waiting. */ private boolean mSignInClicked; /* Store the connection result from onConnectionFailed callbacks so that we can * resolve them when the user clicks sign-in. */ private ConnectionResult mConnectionResult; View btn; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_example); mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(Plus.API, null) //.addScope(Plus.SCOPE_PLUS_LOGIN) .build(); btn = findViewById(R.id.sign_in_button); btn.setOnClickListener(this); } protected void onStart() { super.onStart(); mGoogleApiClient.connect(); } /* A helper method to resolve the current ConnectionResult error. */ public void resolveSignInError() { Log.d("","resolveSignInError()"); if (mConnectionResult.hasResolution()) { Log.d("","resolveSignInError() mConnectionResult.hasResolution()"); try { mIntentInProgress = true; /*startIntentSenderForResult(mConnectionResult.getIntentSender(), RC_SIGN_IN, null, 0, 0, 0);*/ mConnectionResult.startResolutionForResult(this, // your activity RC_SIGN_IN); } catch (IntentSender.SendIntentException e) { // The intent was canceled before it was sent. Return to the default // state and attempt to connect to get an updated ConnectionResult. Log.d("","resolveSignInError() mConnectionResult.hasResolution() catch"); mIntentInProgress = false; mGoogleApiClient.connect(); } } } protected void onStop() { super.onStop(); if (mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } @Override public void onConnected(Bundle bundle){ // We've resolved any connection errors. mGoogleApiClient can be used to // access Google APIs on behalf of the user. mSignInClicked = false; Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show(); } @Override public void onConnectionSuspended(int i){ mGoogleApiClient.connect(); } @Override public void onDisconnected(){ } @Override public void onConnectionFailed(ConnectionResult result) { if (!mIntentInProgress) { // Store the ConnectionResult so that we can use it later when the user clicks // 'sign-in'. mConnectionResult = result; if (mSignInClicked) { // The user has already clicked 'sign-in' so we attempt to resolve all // errors until the user is signed in, or they cancel. resolveSignInError(); } } } /*@Override public void onConnectionFailed(ConnectionResult result){ if (!mIntentInProgress && result.hasResolution()) { try { mIntentInProgress = true;*//* startIntentSenderForResult(result.getIntentSender(), RC_SIGN_IN, null, 0, 0, 0);*//* result.startResolutionForResult(this, // your activity RC_SIGN_IN); } catch (IntentSender.SendIntentException e) { // The intent was canceled before it was sent. Return to the default // state and attempt to connect to get an updated ConnectionResult. mIntentInProgress = false; mGoogleApiClient.connect(); } } }*/ protected void onActivityResult(int requestCode, int responseCode, Intent intent) { if (requestCode == RC_SIGN_IN) { if (responseCode != RESULT_OK) { mSignInClicked = false; } mIntentInProgress = false; if (!mGoogleApiClient.isConnecting()) { mGoogleApiClient.connect(); } } } @Override public void onClick(View view){ Log.d("","onClick()"); if (view.getId() == R.id.sign_in_button && !mGoogleApiClient.isConnecting()) { mSignInClicked = true; resolveSignInError(); } } }
我刚发现该应用会在未经许可的情况下自动连接到Google+.我不需要按登录按钮,但我可以通过我的帐户发布.这是一个关于隐私的错误吗?
好!因此,吐司是因为您已登录,当您单击时,您尝试再次登录:因为您没有要解决的错误的连接结果,您将获得NPE.
这是它的工作原理:
您的登录状态存储在Google Play服务中.
当您连接时,您的应用会连接到Google Play服务并尝试查看您之前是否已登录.
如果有,则回调onConnected.
如果还没有,它会回调onConnectionFailed并给你一个ConnectionResult.
当用户点击登录时,您在ConnectionResult上"解决错误" - 这只是一个挂起的Intent,它会触发帐户选择器和同意屏幕.
当用户同意时,您的应用程序将在onActivityResult中回调,然后重新连接(并且流程再次启动,此时间结束于步骤3).
因此,如果您使用onConnected,则应隐藏登录按钮 - 用户已登录!
现在,也许出于任何原因,您希望用户必须单击按钮才能开始.那也没关系.在onClick中,您只需要测试mPlusClient是否已连接.如果是,请在登录后直接进入您想要做的任何事情.如果没有,则解决连接结果.