web-dev-qa-db-fra.com

Dans l'application Android, la connexion Google Sign-In ne se charge pas.

Chaque fois que j'essaie de me connecter en lançant l'intention de connexion de Google, il passe directement à onActivityResult sans que je puisse choisir un compte . Tout cela est atténué, mais la fenêtre permettant de sélectionner un compte ne ne s'affiche pas . La connexion échoue alors avec cette exception ApiException: 

Java.lang.ClassNotFoundException: com.google.Android.gms.common.api.Scope

et

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

(trace de pile complète: https://Pastebin.com/vBZeBLu0 )

Toutes mes dépendances utilisées sont à jour et mes informations d'identification (oAuth client-id) sont toutes configurées correctement. J'ai essayé de résoudre d'autres problèmes similaires, mais aucun d'eux n'a résolu mon problème. J'ai également vérifié si l'utilisateur était déconnecté. complètement de l'appareil et le problème a continué à se poser.

Ceci est mon activité de connexion:

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();
            // ...
        }
    }

}

code complet pour l'activité de connexion: https://Pastebin.com/6Yi7vzD7

Gradle:

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'

Je n'ai aucune idée de la cause du problème. Comment puis-je résoudre ce problème et faire apparaître la fenêtre de sélection de compte?

EDIT 2.1.2019

À la place de l'ApiExeption ci-dessus, j'obtiens cette erreur:

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)

Je crois que quelque chose a mal tourné avec la configuration de mon oAuth (Auto généré par Firebase)

3
Ale4303

Option 1 - Assurez-vous que la connexion à Google est activée dans les méthodes d'authentification Firebase de la console Firebase. Par défaut, Google Sign-in n'est pas activé.

Option 2 - Dans votre fichier AndroidManifest.xml, sous la balise, ajoutez les lignes suivantes pour prendre en charge la prise en charge de la mémoire haute au cas où la fenêtre contextuelle de connexion Google nécessiterait davantage de mémoire. Même les grandes images peuvent être chargées à l'aide de cette commande dans la balise d'application - _ ​​largeHeap/ _ ​​true ~ votre image de lancement dans ce cas.

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

Option 3 - Essayez ce code pour implémenter Google Sign-in à l'aide de Firebase et cela devrait fonctionner.

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();
                    }
                }
            });
    }
}

Recherchez le fichier GoogleSignInOptions.Builder où vous devez transmettre le requestIdToken ("xxxx") avec le générateur. C'est une URL que vous pouvez trouver sous l'onglet Authentification Firebase -> Méthodes de connexion -> Google -> Configuration du SDK Web -> ID client Web.

 requestIdToken Web Client ID

J'espère que cela répond à votre requête.

2

Donc, comme prévu, cela était dû à 

Canvas: essaye de dessiner un bitmap trop volumineux (256000000 octets).

L'icône de lanceur que vous avez utilisée, qui apparaît également dans la boîte de dialogue du sélecteur de compte, empêchait la boîte de dialogue de s'afficher.
En tant que solution, vous pouvez suivre la réponse de Praveen (option2) pour que l’application prenne en charge les images plus grandes de Manifest.
Mais je vous suggère de compresser le fichier image car la boîte de dialogue du sélecteur de compte n’a pas vraiment besoin d’une image haute résolution et l’icône du lanceur n’a pas besoin d’être aussi grande. Jetez un coup d'œil à this , adaptez les icônes du lanceur à ces tailles (uniquement celles dont vous avez besoin) et placez-les dans des dossiers pouvant être dessinés de manière à éviter des problèmes similaires à l'avenir.

3
Niraj Niroula

Veuillez ajouter le code ci-dessous dans le manifeste

<meta-data
            Android:name="com.google.Android.gms.version"
            Android:value="@integer/google_play_services_version" />

Et essayez de déplacer le bitmap splash (haute résolution) de drawable à drawable-xxhdpi était la solution.

J'ai eu le même problème. Je ne soupçonnais pas que mon écran de démarrage était le problème, car il s'affiche au démarrage de l'application, mais il s'est avéré que l'écran de démarrage est le problème.

L'écran de démarrage dans mon cas a une résolution de xxhdpi et a été placé par erreur dans le dossier pouvant être dessiné au lieu de drawable-xxhdpi. Cela a amené Android à supposer que l’écran de démarrage avait une résolution mdpi et à redimensionner l’image jusqu’à 3 fois sa taille requise et en essayant de créer un bitmap.

utiliser la classe Bitmap.Factory, ce lien vous aidera Chargement efficace des bitmaps volumineux

0
Viral Patel