在 Android 应用中,Google 登录弹出窗口未加载

Posted

技术标签:

【中文标题】在 Android 应用中,Google 登录弹出窗口未加载【英文标题】:In Android app Google Sign-In pop up does not load 【发布时间】:2019-05-26 16:00:23 【问题描述】:

每当我尝试通过启动 google 登录 Intent 进行登录时,它都会直接转到 onActivityResult,而我没有机会选择帐户。 它所做的只是使屏幕变暗,但没有显示选择帐户的窗口。 然后登录失败并出现此 ApiException:

java.lang.ClassNotFoundException: com.google.android.gms.common.api.Scope

java.lang.RuntimeException: Canvas: trying to draw too large(256000000bytes) bitmap.

(完整堆栈跟踪:https://pastebin.com/vBZeBLu0)

我所有使用的依赖项都是最新的,并且我的凭据(oAuth client-id)都设置正确,我尝试了其他类似问题的解决方案,但没有一个解决我的问题,我还检查了用户是否已从设备中完全注销,并且问题不断重现。

这是我的登录活动:

public class Login extends Activity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks                                     

private static final String TAG = "LoginProcess";

SignInButton gsignInButton;
private static final int RC_SIGN_IN = 1;
DatabaseReference mRef;
FirebaseAuth mAuth;
FirebaseAuth.AuthStateListener mAuthListener;
GoogleSignInOptions gso;
GoogleApiClient mGoogleApiClient;


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

    mAuth = FirebaseAuth.getInstance();



    gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build();

    mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

    gsignInButton = findViewById(R.id.sib);

    gsignInButton.setColorScheme(SignInButton.COLOR_DARK); // wide button style
    gsignInButton.setOnClickListener(myhandler);




View.OnClickListener myhandler = new View.OnClickListener() 
    public void onClick(View v) 
       signIn();
    

;



public void signIn() 

    Intent signInIntent = mGoogleSignInClient.getSignInIntent();
    startActivityForResult(signInIntent, RC_SIGN_IN);


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

    if (requestCode == RC_SIGN_IN) 
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        try 
            // Google Sign In was successful, authenticate with Firebase
            GoogleSignInAccount account = task.getResult(ApiException.class);
            firebaseAuthWithGoogle(account);
         catch (ApiException e) 
            // Google Sign In failed, update UI appropriately
            Log.w(TAG, "Google sign in failed", e);  //this is where it always lands.
            Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show();
            // ...
        
    


登录活动的完整代码:https://pastebin.com/6Yi7vzD7

分级:

apply plugin: 'com.android.application'

android 
    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig 
        applicationId "com.example.sanchez.worldgramproject"
        minSdkVersion 21
        targetSdkVersion 28
        multiDexEnabled true
        versionCode 0
        versionName "0"


    
    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
        debug 
            debuggable true
        
    




dependencies 

    compile fileTree(dir: 'libs', include: ['*.jar'])
    api "com.google.android.material:material:1.0.0"

    implementation 'com.github.madrapps:pikolo:1.1.6'
    implementation 'com.google.android.gms:play-services-drive:16.0.0'
    implementation 'com.google.android.material:material:1.1.0-alpha02'
    implementation 'com.github.bumptech.glide:glide:3.8.0'
    implementation'com.firebaseui:firebase-ui-storage:2.3.0'
    implementation 'com.google.firebase:firebase-auth:16.1.0'
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.jakewharton:butterknife:8.8.1'
    implementation 'androidx.multidex:multidex:2.0.1'
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.6'
    implementation 'de.hdodenhof:circleimageview:2.2.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.exifinterface:exifinterface:1.0.0'
    implementation 'com.google.firebase:firebase-storage:16.0.5'
    implementation 'com.google.android.gms:play-services-maps:16.0.0'
    implementation 'com.google.firebase:firebase-database:16.0.5'
    testImplementation 'junit:junit:4.12'




apply plugin: 'com.google.gms.google-services'

我不知道问题的原因是什么,我该如何解决这个问题并弹出帐户选择窗口?

编辑 2.1.2019

我得到了这个错误,而不是上面的 ApiExeption:

W/LoginProcess: Google sign in failed
    com.google.android.gms.common.api.ApiException: 8: 
        at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(Unknown Source:4)
        at com.google.android.gms.auth.api.signin.GoogleSignIn.getSignedInAccountFromIntent(Unknown Source:8)
        at com.example.sanchez.worldgramproject.Login.onActivityResult(Login.java:162)
        at android.app.Activity.dispatchActivityResult(Activity.java:7548)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4485)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4532)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1752)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6938)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

我认为我设置 oAuth(由 Firebase 自动生成)的方式出了点问题

【问题讨论】:

Android Google Drive implementation : getting the exception "java.lang.ClassNotFoundException: com.google.android.gms.common.api.Scope"的可能重复 我在该线程上尝试了所有方法,但没有成功 这听起来不太可能,因为它显然是multidex 问题。 我在问题发生之前添加了启用的multidex,可能与androidx兼容性有关(我在新编辑中添加了完整的gradle文件) Niraj Niroula,它确实有效!您可以将其发布为答案,以便我可以给您积分吗?另外,还有没有办法使用我的旧图像(太大)但有不同的尺寸,所以我可以用它来登录? 【参考方案1】:

选项 1 - 确保在 Firebase 控制台的 Firebase 身份验证方法中启用了 Google 登录。默认情况下,未启用 Google 登录。

选项 2 - 在您的 AndroidManifest.xml 文件中,在标记下添加以下行以支持高内存支持,以防 Google 登录弹出窗口需要更多内存。 甚至可以在应用程序标签中使用此命令加载大图像 - largeHeap as true ~ 你的启动器图像在这个案例。

<application
    android:hardwareAccelerated="true"
    android:largeHeap="true" >

选项 3 - 尝试使用此代码使用 Firebase 实现 Google 登录,它应该可以工作。

public class LoginActivity extends AppCompatActivity 

private GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
private int permissions = 0;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    SignInButton authButton = findViewById(R.id.home_auth_button);
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken("xxxxxxxxxxxx.apps.googleusercontent.com").requestEmail().build();
    mAuth = FirebaseAuth.getInstance();
    mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    authButton.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            signIn();
        
    );


private void signIn() 
    Intent signInIntent = mGoogleSignInClient.getSignInIntent();
    startActivityForResult(signInIntent, 0);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0) 
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        try 
            GoogleSignInAccount account = task.getResult(ApiException.class);
            if (account != null) 
                firebaseAuthWithGoogle(account);
             else
                Log.w("AUTH", "Account is NULL");
                Toast.makeText(LoginActivity.this, "Sign-in failed, try again later.", Toast.LENGTH_LONG).show();
            
         catch (ApiException e) 
            Log.w("AUTH", "Google sign in failed", e);
            Toast.makeText(LoginActivity.this, "Sign-in failed, try again later.", Toast.LENGTH_LONG).show();
        
    


private void firebaseAuthWithGoogle(GoogleSignInAccount acct) 
    Log.d("AUTH", "firebaseAuthWithGoogle:" + acct.getId());
    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) 
                    if (task.isSuccessful()) 
                        Log.d("AUTH", "signInWithCredential:success");
                        startActivity(new Intent(LoginActivity.this, AnotherActivity.class));
                        Toast.makeText(LoginActivity.this, "Sign-in successful!", Toast.LENGTH_LONG).show();
                     else 
                        Log.w("AUTH", "signInWithCredential:failure", task.getException());
                        Toast.makeText(LoginActivity.this, "Sign-in failed, try again later.", Toast.LENGTH_LONG).show();
                    
                
            );
    

注意 GoogleSignInOptions.Builder,您需要将 requestIdToken("xxxx") 传递给构建器。这是一个 URL,您可以在 Firebase 身份验证选项卡 -> 登录方法 -> Google -> Web SDK 配置 -> Web 客户端 ID 下找到它。

希望这能回答您的问题。

【讨论】:

以上选项均不适用于我的情况。能帮我找到根本原因吗? 我不知道为什么其他一切都在工作,但是一旦第一次使用一个 gmail 帐户登录,然后第二次它会自动使用同一帐户登录,而不是显示 gmail 帐户列表或选项添加帐户。可能是什么问题?【参考方案2】:

正如预期的那样,这是由于

画布:试图绘制过大(256000000 字节)的位图。

您使用的启动器图标(也出现在帐户选择器对话框中)正在阻止对话框弹出。作为解决方案,您可以按照 Praveen 的回答( option2)关于使应用程序支持来自Manifest 的较大图像。 但我建议您压缩图像文件,因为帐户选择器对话框并不需要高分辨率图像,启动器图标也不需要那么大。看看this,将启动器图标缩放到那些尺寸(仅您需要的尺寸)并将它们放在各自的可绘制文件夹中,这样它也可以帮助您避免将来出现类似问题。

【讨论】:

以上是关于在 Android 应用中,Google 登录弹出窗口未加载的主要内容,如果未能解决你的问题,请参考以下文章

Google+ 登录无法正常工作

在 Android 应用中登录 Google 以使用 Cloud Endpoints 后端

我是不是需要 Firebase 才能在我的 Android 应用中使用 Google 登录? [复制]

如何在 Xamarin.Android 应用上集成新的 Google 登录?

Android 模拟器上的 Google Play 服务和 Google Play 游戏应用

如何在我的 Android 应用程序中集成 google+ 登录?