IncompatibleClassChangeError después de actualizar a Android Build Tools 25.1.6 GCM / FCM

80

Desde que actualicé a Android SDK Tools 25.1.6 y Android Support Repository 32.0.0 (esta mañana), recibí el siguiente error, no cambié nada en mi código y todavía funciona en la computadora de mi colega (Android SDK Tools 25.1.1 + Repositorio de soporte de Android 30.0.0).

java.lang.IncompatibleClassChangeError: The method 
     'java.io.File android.support.v4.content.ContextCompat.getNoBackupFilesDir(android.content.Context)' 
     was expected to be of type virtual but instead was found to be of type direct 
     (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)

     at com.google.android.gms.iid.zzd.zzeb(Unknown Source)
     at com.google.android.gms.iid.zzd.<init>(Unknown Source)
     at com.google.android.gms.iid.zzd.<init>(Unknown Source)
     at com.google.android.gms.iid.InstanceID.zza(Unknown Source)
     at com.google.android.gms.iid.InstanceID.getInstance(Unknown Source)
     at com.xxxxxxx.utils.RegistrationIntentService.onHandleIntent(RegistrationIntentService.java:55)
     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:145)
     at android.os.HandlerThread.run(HandlerThread.java:61)

Aquí está el fragmento de código que falla:

InstanceID instanceID = InstanceID.getInstance(this); // <-- crash here
String instanceIDToken = instanceID.getToken(getString(R.string.google_app_id),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

Es cuando intento obtener un token de Google Cloud Messaging.

Estoy importando GCM en Gradle con servicios de juego divididos:

 compile 'com.google.android.gms:play-services-analytics:9.0.0' 
 compile 'com.google.android.gms:play-services-maps:9.0.0'
 compile 'com.google.android.gms:play-services-location:9.0.0' 
 compile 'com.google.android.gms:play-services-gcm:9.0.0' 
 compile 'com.google.android.gms:play-services-base:9.0.0'

EDITAR deshabilitar GCM solucionó el problema, por lo que supongo que debería migrar a Firebase Cloud Message

EDIT2 Mi dispositivo recibe Google Play Services 9.0 (ayer fue 8.4.x). Ahora ya no se bloquea, pero se queja del descriptor del módulo

 Failed to load module descriptor class: Didn't find class "com.google.android.gms.dynamite.descriptors.com.google.firebase.auth.ModuleDescriptor"
 Firebase API initialization failure.

¿Alguien tiene un error similar y cómo solucionarlo?

FIJO agradecimiento especial a @stegranet. ./gradlew -q app:dependencies --configuration compilete ayuda a identificar qué dependencias incluyen SDK 24.x

El problema principal es que algunas bibliotecas importan la biblioteca de soporte más reciente usando un +signo en lugar de una versión. Esto causa el problema, al incluir la última versión disponible.

Así que evita iniciar +sesión en dependencias;)

sonique
fuente
Aparentemente, Google Cloud Messaging se convirtió en Firebase Cloud Messaging: firebase.google.com/docs/cloud-messaging no estoy seguro de si está relacionado, todavía estoy investigando.
sonique
Siento que esto no es un problema de herramientas de construcción. Tiene que ver con el servicio Google Play. He estado usando la versión 9.0.0 y sigo recibiendo el error además de quejarse de que mi firma no es válida ...
Arnold Balliu
¿Cómo verifica la versión de los servicios de Google Play en su móvil? Veo Google Play Music, Juegos, etc. pero nada como los servicios de Play.
bschandramohan

Respuestas:

36

Usé el árbol de dependencia de Gradle para resolver este error por mí.

Simplemente ejecute gradle -q app:dependencies --configuration compile y verifique la salida para entradas como esta:

+--- com.mcxiaoke.viewpagerindicator:library:2.4.1
|    \--- com.android.support:support-v4:+ -> 24.0.0-beta1 (*)

Como dijo Diego Giorgini , esta versión es demasiado alta (> = 24). Así que actualiza las dependencias build.gradlecomo

compile('com.mcxiaoke.viewpagerindicator:library:2.4.1') {
    exclude module: 'support-v4';
}
compile 'com.android.support:support-v4:23.4.0'
Stegranet
fuente
El problema principal era la biblioteca de soporte de importación de algunos módulos mediante un +letrero (como en su ejemplo). Así que gradle incluye la última versión que no encaja en nuestro estuche. ¡Gracias!
sonique
1
No entiendo cómo Android puede deslizar> = 24 dependencias en nuestro proyecto si especificamos todo como a continuación 24. Este parece ser un nuevo problema que ahora ha bloqueado las versiones de depuración de mi aplicación y ha generado bastante confusión. mientras que la versión de la tienda con el mismo código parece estar bien
Daniel Wilson
Gracias stegranet por confirmar. Lanzamos una actualización para solucionar este problema. Pruebe la versión 9.0.1
Diego Giorgini
Complemento de Android Studio GradleView para analizar su proyecto.
Jignesh Patel
¿Dónde ejecuto el siguiente código? "gradle -q aplicación: dependencias - compilación de configuración"
Roee
34

actualización 27 de mayo:

acabamos de lanzar una actualización ( version 9.0.1) para corregir la incompatibilidad que mencioné en mi primera edición.
Actualice sus dependencias y háganos saber si esto sigue siendo un problema.

¡Gracias!


respuesta original 20 de mayo:

El problema que está experimentando se debe a una incompatibilidad entre
play-services / firebase sdk v9.0.0y com.android.support:appcompat-v7 >= 24
(la versión lanzada con android-N sdk)

Debería poder solucionarlo apuntando a una versión anterior de la biblioteca de soporte. Me gusta:

compile 'com.android.support:appcompat-v7:23.4.0'
Diego Giorgini
fuente
2
Esta es la única solución que parece haber funcionado, gracias. ¡Da un poco de miedo que errores como ese puedan entrar en lanzamientos de producción si no te importa que te lo diga!
Daniel Wilson
Lo hice, actualizado: - compile 'com.google.android.gms: play-services-gcm: 9.0.2' también com.google.gms: google-services: 3.0.0 'pero resulta en un error multidex. ¡¡Alguna idea!!
Rohit
'com.google.android.gms: play-services-gcm: 9.0.2' todavía tiene este problema
Tom Bevelander
Usando 9.0.2 para todos mis módulos 'play-services' y 'com.google.gms: google-services: 3.0.0' en la compilación del proyecto. También usando la biblioteca de soporte 24.0.0 lanzada recientemente. Pude eliminar el error reemplazando "compile 'com.google.android.gms: play-services-gcm: 9.0.2'" con "compile 'com.google.firebase: firebase-messaging: 9.0.2'"
c0deblooded
Recibí este error al intentar cambiar la versión a 9.0.1> Solucione el conflicto de versión actualizando la versión del complemento de servicios de Google (la información sobre la última versión está disponible en bintray.com/android/android-tools/… ) o actualizando la versión de com.google.android.gms a 9.0.0. @Diego Giorgini
Roger Alien
5

el mío trabajó con lo siguiente:

gradle de nivel de aplicación

dependencies {
 compile 'com.android.support:appcompat-v7:23.4.0'
 compile 'com.android.support:design:23.4.0'
 compile 'com.google.android.gms:play-services:9.0.0'
}

gradle nivel de raíz

dependencies {
    classpath 'com.google.gms:google-services:3.0.0'
}
macbee
fuente
2
Esto funcionó para mí ... Cambié todas las versiones 24.2.1 a 23.4.0 y getToken funciona de nuevo ... ¡Esto es terrible! Ahora tengo miedo de actualizar las versiones.
EZDsIt
5

Actualicé las dependencias de servicios de juego en build.gradle

dependencies {
    compile 'com.google.android.gms:play-services:9.0.0'
}

Para solucionar el conflicto de versiones actualizando la versión del complemento de servicios de Google, tuve que actualizar los servicios de Google en la build.gradlecarpeta raíz del proyecto.

dependencies {
    classpath 'com.google.gms:google-services:3.0.0'
}

Puede obtener la última actualización de los servicios de Google aquí .

Aunque no está evitando la excepción, ya no está bloqueando la aplicación en mi lado.

Actualizar

Podría evitar el bloqueo actualizando el estudio de Android desde Beta Channel. Luego actualice su platform/build-toolsSDK interno.

ingrese la descripción de la imagen aquí

Reaz Murió
fuente
Gracias, actualicé google-services a 3.0.0, pero no ayuda :(
sonique
En mi caso, obtengo la excepción en logcat, pero ya no se bloquea
Reaz Murshed
ok, gracias por tus comentarios. ¿Está utilizando las herramientas de compilación de Android 25.1.6?
sonique
tienes razón, funciona con play-services 9.0.0, pero no con servicios divididos :(
sonique
Lo hice, actualicé la compilación 'com.google.android.gms: play-services-gcm: 9.0.2' también com.google.gms: google-services: 3.0.0 'pero da como resultado un error multidex. ¡¡Alguna idea!!
Rohit
4

La actualización a la última versión de los servicios de Google Play solucionó el problema.

aplique el complemento: 'com.google.gms.google-services' en la parte inferior ...

dependencies {
    compile 'com.google.android.gms:play-services:9.0.0'
}

https://developers.google.com/android/guides/setup#add_google_play_services_to_your_project

sinatest
fuente
gracias. Actualicé 9.0.0también, pero todavía tengo el problema. Actualmente estoy usando splited gms. : compile 'com.google.android.gms:play-services-analytics:9.0.0' compile 'com.google.android.gms:play-services-maps:9.0.0' compile 'com.google.android.gms:play-services-location:9.0.0' compile 'com.google.android.gms:play-services-gcm:9.0.0' compile 'com.google.android.gms:play-services-base:9.0.0'
sonique
Traté de compilar con play-services:9.0.0, pero sigue siendo el mismo problema.
sonique
Estoy usando 'com.google.android.gms: play-services-gcm: 9.0.2' pero tengo el mismo problema
Tom Bevelander
1

Incluyendo todos los paquetes de servicios de juego

dependencies {
  compile 'com.google.android.gms:play-services:9.0.0'
}

suprime el error, pero el resultado final es que la recuperación del token de GCM no funciona ni podemos obtener una instancia de GCM. Entonces esta no es una solución en mis libros. Si alguien tiene alguna idea de lo que está pasando, infórmenos.

EDITAR:

Reemplacé GCM con firebase, actualicé Android Studio de 2.1 a 2.2 para solucionar el problema de ejecución instantánea con el análisis de Firebase, actualicé las herramientas de compilación a 24-rc4 y las herramientas de plataforma a 24-rc3, y mantuve la versión de mis bibliotecas de soporte en 23.4.0. Todo parece estar funcionando bien ahora.

Stilianos Tzouvaras
fuente
parece que tenemos que implementar FCM
sonique
Lo hice y sigo recibiendo el mismo error. Eliminé completamente GCM y lo reemplacé con FCM en base a esto: developers.google.com/cloud-messaging/android/… Algo está mal con la biblioteca de soporte, no con los paquetes GCM o FCM
Stilianos Tzouvaras
1

Tuve el mismo problema y volver del repositorio de soporte de Android 32.0.0 al repositorio de soporte de Android 31.0.0 lo resolvió.

BorisK
fuente
3
¿Cómo se revierte el repositorio de soporte de Android?
Pratama Nur Wijaya
2
Bueno, la única forma que encontré es copiar el antiguo repositorio en lugar del nuevo. El repositorio generalmente está debajo de la carpeta de Android a la que apunta su 'administrador de SDK' (si está usando una Mac, es probable que sea la ruta ~ / Library / Android / sdk / extras). En la carpeta de extras, reemplace las carpetas 'android y' google 'por las antiguas.
BorisK
Encontré el repositorio aquí: dl-ssl.google.com/android/repository/… , luego descomprimiéndolo en ../sdk/extras/android y eliminando el m2reposity existente parecía funcionar hasta ahora.
Tom Redman
1

Para notificaciones push de Android con GCM 2016:

1) en Android SDK-> SDK Tools verifique los servicios de Google Play

2) en gradle agregue dependencias solo una línea:

compile 'com.google.android.gms:play-services-gcm:9.4.0'

(no hay una ruta de clase específica y funciona para mí)

3) debe crear 3 clases (GCMPushReceiverService, GCMRegistrationIntentService, GCMTokenRefreshListenerService)

4.1) código para GCMTokenRefreshListenerService:

package com.myapp.android;

/**
 * Created by skygirl on 02/08/2016.
 */
import android.content.Intent;
import com.google.android.gms.iid.InstanceIDListenerService;

public class GCMTokenRefreshListenerService extends InstanceIDListenerService {

    //If the token is changed registering the device again
    @Override
    public void onTokenRefresh() {
        Intent intent = new Intent(this, GCMRegistrationIntentService.class);
        startService(intent);
    }
}

4.2) Código para GCMRegistrationIntentService (cambie la entidad autorizada con su número de proyecto):

package com.myapp.android;

/**
 * Created by Skygirl on 02/08/2016.
 */
import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;

public class GCMRegistrationIntentService extends IntentService {
    //Constants for success and errors
    public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
    public static final String REGISTRATION_ERROR = "RegistrationError";

    //Class constructor
    public GCMRegistrationIntentService() {
        super("");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        //Registering gcm to the device
        registerGCM();
    }

    private void registerGCM() {
        //Registration complete intent initially null
        Intent registrationComplete = null;

        //Register token is also null
        //we will get the token on successfull registration
        String token = null;
        try {
            //Creating an instanceid
            InstanceID instanceID = InstanceID.getInstance(this);
            String authorizedEntity = "XXXXXXXXXX"; //  your project number

            //Getting the token from the instance id
            token = instanceID.getToken(authorizedEntity, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

            //Displaying the token in the log so that we can copy it to send push notification
            //You can also extend the app by storing the token in to your server
            Log.w("GCMRegIntentService", "token:" + token);

            //on registration complete creating intent with success
            registrationComplete = new Intent(REGISTRATION_SUCCESS);

            //Putting the token to the intent
            registrationComplete.putExtra("token", token);
        } catch (Exception e) {
            //If any error occurred
            Log.w("GCMRegIntentService", "Registration error");
            registrationComplete = new Intent(REGISTRATION_ERROR);
        }

        //Sending the broadcast that registration is completed
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
    }
}

4.3) Código para GCMPushReceiverService:

package com.myapp.android;

/**
 * Created by Skygirl on 02/08/2016.
 */
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;

import com.google.android.gms.gcm.GcmListenerService;

//Class is extending GcmListenerService
public class GCMPushReceiverService extends GcmListenerService {

    //This method will be called on every new message received
    @Override
    public void onMessageReceived(String from, Bundle data) {
        //Getting the message from the bundle
        String message = data.getString("message");
        //Displaying a notiffication with the message
        sendNotification(message);
    }

    //This method is generating a notification and displaying the notification
    private void sendNotification(String message) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        int requestCode = 0;
        PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
        NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.your_logo)
                .setContentTitle("Your Amazing Title")
                .setContentText(message)
                .setPriority(Notification.PRIORITY_MAX)
                .setContentIntent(pendingIntent);
        noBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
    }
}

5) No olvide cambiar el nombre del paquete

6) En su mainActivity pegue este código:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Setup view
        setContentView(R.layout.main);
    mRegistrationBroadcastReceiver = new BroadcastReceiver() {

        //When the broadcast received
        //We are sending the broadcast from GCMRegistrationIntentService

        public void onReceive(Context context, Intent intent) {
            //If the broadcast has received with success
            //that means device is registered successfully
            if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_SUCCESS)){
                //Getting the registration token from the intent
                String token = intent.getStringExtra("token");
                //Displaying the token as toast
                Toast.makeText(getApplicationContext(), "Registration token:" + token, Toast.LENGTH_LONG).show();

                //if the intent is not with success then displaying error messages
            } else if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_ERROR)){
                Toast.makeText(getApplicationContext(), "GCM registration error!", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getApplicationContext(), "Error occurred", Toast.LENGTH_LONG).show();
            }
        }
    };

    //Checking play service is available or not
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

    //if play service is not available
    if(ConnectionResult.SUCCESS != resultCode) {
        //If play service is supported but not installed
        if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            //Displaying message that play service is not installed
            Toast.makeText(getApplicationContext(), "Google Play Service is not install/enabled in this device!", Toast.LENGTH_LONG).show();
            GooglePlayServicesUtil.showErrorNotification(resultCode, getApplicationContext());

            //If play service is not supported
            //Displaying an error message
        } else {
            Toast.makeText(getApplicationContext(), "This device does not support for Google Play Service!", Toast.LENGTH_LONG).show();
        }

        //If play service is available
    } else {
        //Starting intent to register device
        Intent itent = new Intent(this, GCMRegistrationIntentService.class);
        startService(itent);
    }
}

//Unregistering receiver on activity paused
@Override
public void onPause() {
    super.onPause();
    Log.w("MainActivity", "onPause");
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
}



    @Override
    public void onResume() {
 super.onResume();
        Log.w("MainActivity", "onResume");
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_SUCCESS));
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_ERROR));
    }

7) En su AndroidManifest.xml agregue las siguientes líneas:

<uses-permission android:name="android.permission.INTERNET" />

8) en tu consola logcat copia tu token y pégalo en este sitio agrega tu número de proyecto, tu token y un mensaje. Funciona bien para mí :)

chica del cielo
fuente
Hola @Skygirl Estoy siguiendo tu ejemplo, ¿algún requisito especial en el AndroidManifest? ¿Podría agregar esa parte del código? Gracias
ziniestro
0

Después de un día completo en esto, puedo confirmar al 100% que la biblioteca Optimizely también está chocando de alguna manera y causando este error. Para ser específico, estoy usando Optimizely a través de Fabric. Es imposible que Firebase se inicialice mientras se usa Optimizely de esta manera (¿tal vez de todas las formas?).

He publicado en su github al respecto y me pondré en contacto con ellos directamente ...

https://github.com/optimizely/Optimizely-Android-SDK/issues/11

Steven Elliott
fuente
0

Yo tuve el mismo problema. Actualicé las herramientas del SDK a 25.1.7 rc1, luego el problema desapareció.

Tony Lin
fuente
0

actualizó las herramientas del SDK a 25.1.7 y solucionó este problema.

Austin
fuente
0

Bueno, solo soy un principiante en el uso de Android. Quería probar la creación de usuarios enFirebase siguiendo las instrucciones que se proporcionan en el sitio web de Firebase.

Agregué esas líneas en los lugares indicados.

classpath 'com.google.gms: google-services: 3.0.0'

compile 'com.google.firebase: firebase-auth: 9.2.0'

aplicar complemento: 'com.google.gms.google-services'

Pero el método createUserWithEmailAndPassword siguió mostrando fallas en la creación de usuarios. Es por eso que visité esta pregunta para resolver mi problema. Leí todo y apliqué cada consejo. pero siguió mostrando fallas. Pero cuando actualizo Android Studio from 2.1.1 to 2.1.2, pude crear usuarios con éxito.

Pero cuando lo comprobé logcat, primero se mostró "Firebase API initialization failure"y luego se mostró "Inicialización de FirebaseApp exitosa".

07-09 18:53:37.012 13352-13352/jayground.firebasetest A/FirebaseApp: Firebase API initialization failure. How can I solve

¿esta? java.lang.reflect.InvocationTargetException en java.lang.reflect.Method.invokeNative (método nativo) en java.lang.reflect.Method.invoke (Method.java:515) en com.google.firebase.FirebaseApp.zza (Desconocido Fuente) en com.google.firebase.FirebaseApp.initializeApp (Fuente desconocida) en com.google.firebase.FirebaseApp.

Jayground
fuente
Okay. Gracias. Pensé que sería bueno compartir cómo resolví mi problema. (Solo que no estaba seguro de haberlo resuelto por completo. Podría crear un usuario con com.google.firebase: firebase-auth: 9.2.0 después de actualizar la versión de Android Studio, pero todavía tiene una falla de inicialización de la API de Firebase en logcat. Así que me preguntaba ) La próxima vez usaré el "botón HACER Pregunta".
Jayground
0

Me he enfrentado a este problema y cambio la versión de mi aplicación gradle de 1.5.0 a 2.0.0.

cambiar classpath

com.android.tools.build:gradle:1.5.0

a

classpath 'com.android.tools.build:gradle:2.0.0

Ankur
fuente
0

Solución 1:

dependencies {
 compile `com.android.support:appcompat-v7:23.4.0`
 compile `com.android.support:support-v4:23.4.0`
 compile `com.android.support:design:23.4.0`
 compile `com.google.android.gms:play-services:9.0.0`
}

Solución 2: detecte incompatibles en la carpeta .idie / libraries /. En algún momento declare play-services-ads: 8.4.0 concurrente con play-services-gcm: 9.0.0. Debe anular las bibliotecas incompatibles build.grade que detectó

Tho Pham
fuente