谷歌登录 - 安卓 - 点击时屏幕冻结

时间:2017-08-01 05:58:21

标签: android google-signin

我在我的某个应用中使用Google登录。我从这个链接获得了代码 - https://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/

我做的一切都很完美,但每当我点击登录时,应用程序最终会冻结并崩溃。

似乎无法弄清楚我做错了什么。

这是我的日志:

Class not found when unmarshalling: com.google.android.gms.auth.api.signin.internal.SignInConfiguration
                                        java.lang.ClassNotFoundException: com.google.android.gms.auth.api.signin.internal.SignInConfiguration
                                            at java.lang.Class.classForName(Native Method)
                                            at java.lang.Class.forName(Class.java:309)
                                            at java.lang.Class.forName(Class.java:273)
                                            at android.os.Parcel.readParcelableCreator(Parcel.java:2281)
                                            at android.os.Parcel.readParcelable(Parcel.java:2245)
                                            at android.os.Parcel.readValue(Parcel.java:2152)
                                            at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
                                            at android.os.BaseBundle.unparcel(BaseBundle.java:221)
                                            at android.os.BaseBundle.containsKey(BaseBundle.java:269)
                                            at android.content.Intent.hasExtra(Intent.java:4884)
                                            at com.miui.server.XSpaceManagerService.isPublicIntent(XSpaceManagerService.java:174)
                                            at com.android.server.am.ActivityStackSupervisorInjector.checkXSpaceControl(ActivityStackSupervisorInjector.java:56)
                                            at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:897)
                                            at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:3478)
                                            at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:3465)
                                            at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:140)
                                            at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2245)
                                            at android.os.Binder.execTransact(Binder.java:446)
                                         Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.auth.api.signin.internal.SignInConfiguration" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
                                            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                            at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                            at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                            at java.lang.Class.classForName(Native Method) 
                                            at java.lang.Class.forName(Class.java:309) 
                                            at java.lang.Class.forName(Class.java:273)

这是我的 MainActivity.java

package com.example.hitesh.google_login;

    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.support.annotation.NonNull;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;

    import com.android.volley.toolbox.ImageLoader;
    import com.android.volley.toolbox.NetworkImageView;
    import com.bumptech.glide.Glide;
    import com.bumptech.glide.load.engine.DiskCacheStrategy;
    import com.google.android.gms.auth.api.Auth;
    import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
    import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
    import com.google.android.gms.auth.api.signin.GoogleSignInResult;
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.SignInButton;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.common.api.OptionalPendingResult;
    import com.google.android.gms.common.api.ResultCallback;
    import com.google.android.gms.common.api.Status;

    import java.nio.BufferUnderflowException;

    public class MainActivity extends AppCompatActivity implements View.OnClickListener,GoogleApiClient.OnConnectionFailedListener {

        private static final String TAG = MainActivity.class.getSimpleName();
        private static final int RC_SIGN_IN = 007;

        private GoogleApiClient mGoogleApiClient;
        private ProgressDialog mProgressDialog;

        private SignInButton btnSignIn;
        private Button btnSignOut, btnRevokeAccess;
        private LinearLayout llProfileLayout;
        private ImageView imgProfilePic;
        private TextView txtName, txtEmail;





        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);


            btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
            btnSignOut = (Button) findViewById(R.id.btn_sign_out);
            btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
            llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
            imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
            txtName = (TextView) findViewById(R.id.txtName);
            txtEmail = (TextView) findViewById(R.id.txtEmail);

            btnSignIn.setOnClickListener(this);
            btnSignOut.setOnClickListener(this);
            btnRevokeAccess.setOnClickListener(this);

            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestEmail()
                    .build();

            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .enableAutoManage(this, this)
                    .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                    .build();

            // Customizing G+ button
            btnSignIn.setSize(SignInButton.SIZE_STANDARD);
            btnSignIn.setScopes(gso.getScopeArray());


     }



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


        private void signOut() {
            Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            updateUI(false);
                        }
                    });
        }

        private void revokeAccess() {
            Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            updateUI(false);
                        }
                    });
        }

        private void handleSignInResult(GoogleSignInResult result) {
            Log.d(TAG, "handleSignInResult:" + result.isSuccess());
            if (result.isSuccess()) {
                // Signed in successfully, show authenticated UI.
                GoogleSignInAccount acct = result.getSignInAccount();

                Log.e(TAG, "display name: " + acct.getDisplayName());

                String personName = acct.getDisplayName();
    //            String personPhotoUrl = acct.getPhotoUrl().toString();
                String email = acct.getEmail();

              //  Log.e(TAG, "Name: " + personName + ", email: " + email
                //        + ", Image: " + personPhotoUrl);

                txtName.setText(personName);
                txtEmail.setText(email);


                updateUI(true);
            } else {
                // Signed out, show unauthenticated UI.
                updateUI(false);
            }
        }

        @Override
        public void onClick(View v) {
            int id = v.getId();

            switch (id) {
                case R.id.btn_sign_in:
                    signIn();
                    break;

                case R.id.btn_sign_out:
                    signOut();
                    break;

                case R.id.btn_revoke_access:
                    revokeAccess();
                    break;
            }
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
            if (requestCode == RC_SIGN_IN) {
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
                handleSignInResult(result);
            }
        }

        @Override
        public void onStart() {
            super.onStart();

            OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
            if (opr.isDone()) {
                // If the user's cached credentials are valid, the OptionalPendingResult will be "done"
                // and the GoogleSignInResult will be available instantly.
                Log.d(TAG, "Got cached sign-in");
                GoogleSignInResult result = opr.get();
                handleSignInResult(result);
            } else {
                // If the user has not previously signed in on this device or the sign-in has expired,
                // this asynchronous branch will attempt to sign in the user silently.  Cross-device
                // single sign-on will occur in this branch.
                showProgressDialog();
                opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
                    @Override
                    public void onResult(GoogleSignInResult googleSignInResult) {
                        hideProgressDialog();
                        handleSignInResult(googleSignInResult);
                    }
                });
            }
        }

        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
            // An unresolvable error has occurred and Google APIs (including Sign-In) will not
            // be available.
            Log.d(TAG, "onConnectionFailed:" + connectionResult);
        }

        private void showProgressDialog() {
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage(getString(R.string.loading));
                mProgressDialog.setIndeterminate(true);
            }

            mProgressDialog.show();
        }

        private void hideProgressDialog() {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.hide();
            }
        }

        private void updateUI(boolean isSignedIn) {
            if (isSignedIn) {
                btnSignIn.setVisibility(View.GONE);
                btnSignOut.setVisibility(View.VISIBLE);
                btnRevokeAccess.setVisibility(View.VISIBLE);
                llProfileLayout.setVisibility(View.VISIBLE);
            } else
                {
                btnSignIn.setVisibility(View.VISIBLE);
                btnSignOut.setVisibility(View.GONE);
                btnRevokeAccess.setVisibility(View.GONE);
                llProfileLayout.setVisibility(View.GONE);
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

使用我的代码。通过引用同一网站的工作代码。

的build.gradle

#!/usr/bin/lua5.1
require( "behaviortrees" ) -- loads the Lua module above and adds to package.loaders
print( require( "xxx" ) ) -- loads xxx.bt (but an xxx Lua module would still take precedence)

activity_main.xml中

    apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.admin.logingoogle"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.1'
    compile 'com.google.android.gms:play-services-auth:9.2.1'
    // glide is added to load the g+ profile image. Ignore if you want
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile "com.squareup.picasso:picasso:2.4.0"
    testCompile 'junit:junit:4.12'
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity" >

<LinearLayout
    android:id="@+id/llProfile"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20dp"
    android:orientation="horizontal"
    android:weightSum="3"
    android:visibility="gone">

    <ImageView
         android:id="@+id/imgProfilePic"
        android:layout_width="80dp"
        android:layout_height="80dp"
          />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:orientation="vertical"
        android:layout_weight="2" >

        <TextView
            android:id="@+id/txtName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textSize="20dp" />

        <TextView
            android:id="@+id/txtEmail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textSize="18dp" />
    </LinearLayout>
</LinearLayout>

<com.google.android.gms.common.SignInButton
    android:id="@+id/btn_sign_in"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20dp"/>

<Button
    android:id="@+id/btn_sign_out"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/btn_logout_from_google"
    android:visibility="gone"
    android:layout_marginBottom="10dp"/>

<Button
    android:id="@+id/btn_revoke_access"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/btn_revoke_access"
    android:visibility="gone" />

<ImageView
     android:id="@+id/imgPP"
    android:layout_width="100dp"
    android:layout_height="100dp" />

答案 1 :(得分:0)

您正在MainActivty UI线程中调用并使用登录代码,因为您的应用程序线程处于等待状态,直到它从谷歌获得响应。

要解决它,请在单独的线程中写入登录代码,以便在应用程序请求respose时,它不会将主UI线程置于等待状态。这将有助于解决冻结申请的问题。可在此处查看线​​程文档Thread Documentation

答案 2 :(得分:0)

使用以下代码进行Google登录,它也适用于您自己的自定义按钮:

public class GoogleLogin extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
private ProgressDialog mProgressDialog;
private GoogleSignInOptions googleSignInOptions;
private ProgressDialog progressDialog;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();
    if(checkPlayServices(this)) {
        buildGoogleApiClient(googleSignInOptions);
    }
    progressDialog=new ProgressDialog(this,R.style.CustomProgressDialog);
    LivepoolsUtils.showProgressDialog(this,progressDialog);
    if(Validator.isNotNull(mGoogleApiClient)) {
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, Constants.RC_SIGN_IN);
    }

}


private void buildGoogleApiClient(GoogleSignInOptions googleSignInOptions) {
    if(Validator.isNull(mGoogleApiClient)){
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, googleSignInOptions)
                .build();
    }

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

public static boolean checkPlayServices(Context context) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(context);
    if (resultCode != ConnectionResult.SUCCESS)
    {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            apiAvailability.getErrorDialog((GoogleLogin)context, resultCode, Constants.PLAY_SERVICES_RESOLUTION_REQUEST)
                    .show();
        }
        return false;
    }
    return true;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == Constants.RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    }
}

private void handleSignInResult(GoogleSignInResult result) {
    if (result.isSuccess()) {
        GoogleSignInAccount acct = result.getSignInAccount();
        Toast.makeText(this,acct.getDisplayName(),Toast.LENGTH_LONG).show();
        email=acct.getEmail();


    }
    else
    {

      finish();
    }
}



@Override
protected void onStop() {
    super.onStop();
    if (mProgressDialog != null) {
        mProgressDialog.dismiss();
    }
}

@Override
public void onBackPressed() {
    super.onBackPressed();
    finish();
}