IncompatibleClassChangeError після оновлення до інструментів збірки Android 25.1.6 GCM / FCM


80

Оскільки я оновився до Android SDK Tools 25.1.6 та Android Support Repository 32.0.0 (сьогодні вранці), у мене з’явилася така помилка, я нічого не міняв у своєму коді, і він все ще працює на моєму колезі (Інструменти Android SDK 25.1.1 + сховище підтримки 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)

Ось фрагмент коду, який зазнав аварії:

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

Це коли я намагаюся отримати маркер із Google Cloud Messaging.

Я імпортую GCM у Gradle з роздільними послугами відтворення:

 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'

EDIT, відключивши GCM, вирішив проблему, тому, я думаю, мені слід перейти до Firebase Cloud Message

EDIT2 Мій пристрій отримає сервіси Google Play 9.0 (вчора було 8.4.x). Тепер він більше не аварійно працює, але скаржиться на дескриптор модуля

 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.

Хтось має подібну помилку і як її виправити?

Виправлено особливу подяку @stegranet. ./gradlew -q app:dependencies --configuration compileдопомагає визначити, які залежності включають SDK 24.x

Основна проблема полягає в тому, що деякі бібліотеки імпортують останню бібліотеку підтримки, використовуючи +знак замість версії. Це спричиняє проблему, включаючи останню доступну версію.

Тому уникайте +входу в залежності;)


Очевидно, Google Cloud Messaging стає Firebase Cloud Messaging: firebase.google.com/docs/cloud-messaging, не впевнений, що це пов’язано, все ще проводить розслідування.
sonique

Я відчуваю, що це не проблема інструментів побудови. Це пов’язано зі службою Google Play. Я використовую версію 9.0.0 і досі отримую помилку плюс скаргу на недійсність мого підпису ...
Арнольд Балліу

Як ви перевіряєте версію сервісів Google Play на своєму мобільному телефоні? Я бачу музику Google Play, ігри тощо, але нічого подібного до сервісів Play.
bschandramohan

Відповіді:


36

Я використав дерево залежностей gradle, щоб вирішити цю помилку для мене.

Просто запустіть gradle -q app:dependencies --configuration compile і перевірте вихідні дані для таких записів:

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

Як сказав Дієго Джорджіні, ця версія занадто висока (> = 24). Тож оновлюйте залежності в build.gradlelike

compile('com.mcxiaoke.viewpagerindicator:library:2.4.1') {
    exclude module: 'support-v4';
}
compile 'com.android.support:support-v4:23.4.0'

Основною проблемою було те, що бібліотека підтримки імпорту модулів використовує +знак (як у вашому прикладі). Отже, gradle включає останню версію, яка не підходить для випадку. Дякую!
sonique

1
Я не розумію, як Android може проскакувати> = 24 залежності в нашому проекті, якщо ми вказуємо все, як вказано нижче 24. Це, здається, нове питання, яке зараз замурувало налагоджувальні версії мого додатка і призвело до неабиякої плутанини - тоді як версія магазину з тим самим кодом здається чудовою
Даніель Вілсон,

Дякую stegranet за підтвердження. Ми просто випускаємо оновлення, щоб це виправити. Будь ласка, спробуйте версію 9.0.1
Дієго Джорджіні

Плагін Android Studio GradleView для аналізу вашого проекту.
Jignesh Patel

де я можу запустити такий код? "додаток gradle -q: залежності - компіляція конфігурації"
Roee

34

оновлення 27 травня:

ми щойно випустили оновлення ( version 9.0.1) для виправлення несумісності, про яку я згадав у своєму першому редагуванні.
Будь ласка, оновіть свої залежності та повідомте нас, якщо це все ще залишається проблемою.

Дякую!


оригінальна відповідь 20 травня:

Проблема, з якою ви стикаєтесь, пов’язана з несумісністю між
play-services / firebase sdk v9.0.0і com.android.support:appcompat-v7 >= 24
(версія, випущена з android-N sdk)

Ви зможете це виправити, орієнтуючись на попередню версію бібліотеки підтримки. Подібно до:

compile 'com.android.support:appcompat-v7:23.4.0'

2
Це єдине рішення, яке, здається, спрацювало, дякую. Трохи страшно, що такі помилки можуть потрапити у виробничі випуски, якщо ви не заперечите, що я скажу!
Даніель Вільсон

я зробив це, оновив: - компілюю 'com.google.android.gms: play-services-gcm: 9.0.2', а також com.google.gms: google-services: 3.0.0 ', але це призводить до помилки мультидекса. Будь-яка ідея !!
Рохіт

'com.google.android.gms: play-services-gcm: 9.0.2' все ще має цю проблему
Том Бевеландер,

Використання 9.0.2 для всіх моїх модулів «play-services» та «com.google.gms: google-services: 3.0.0» у збірці проекту. Також використовується нещодавно випущена бібліотека підтримки 24.0.0. Я зміг видалити помилку, замінивши "compile 'com.google.android.gms: play-services-gcm: 9.0.2'" на "compile 'com.google.firebase: firebase-messaging: 9.0.2'"
c0декривавований

Я отримав цю помилку при спробі змінити версію на 9.0.1> Виправте конфлікт версії або оновивши версію плагіна служби Google (інформація про останню версію доступна на bintray.com/android/android-tools/… ) або оновлення версії com.google.android.gms до 9.0.0. @Diego Giorgini
Roger Alien

5

шахта працювала з наступними:

додаток рівня

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'
}

кореневий рівень

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

2
Це спрацювало для мене ... Я змінив усі версії 24.2.1 на 23.4.0 і getToken знову працює ... Це жахливо! Зараз я боюся оновлювати версії.
EZD,

5

Я оновив залежності від play-services у build.gradle

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

Щоб виправити конфлікт версій або оновивши версію плагіна google-services - мені довелося оновити google-services у build.gradleкореневій папці проекту

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

Ви можете отримати найновіше оновлення сервісів Google тут .

Хоча це не уникає винятку, але воно більше не збиває додаток на моїй стороні.

Оновлення

Я міг уникнути збою, оновивши студію Android з Beta Channel. Потім оновіть свій platform/build-toolsвнутрішній SDK.

введіть тут опис зображення


Дякую, я оновив google-services до 3.0.0, але це не допомагає :(
sonique

У моєму випадку я отримую виняток у logcat, але він більше не
падає

добре, спасибі за відгук. Ви використовуєте Android Build Tools 25.1.6?
sonique

ти маєш рацію, це працює з play-сервісами 9.0.0, але не з роздвоєними сервісами :(
sonique

я зробив це, оновив компіляцію 'com.google.android.gms: play-services-gcm: 9.0.2', а також com.google.gms: google-services: 3.0.0 ', але це призводить до помилки мультидекса. Будь-яка ідея !!
Рохіт,

4

Оновлення до останньої версії служб Google Play вирішило проблему для мене.

застосувати плагін: 'com.google.gms.google-services' унизу ...

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


спасибі. Я теж зробив оновлення 9.0.0, але все ще маю проблему. В даний час я використовую спліт 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

Я намагався скомпілювати play-services:9.0.0, але все одно те саме питання.
sonique

Я використовую 'com.google.android.gms: play-services-gcm: 9.0.2', але маю ту саму проблему
Том Бевеландер,


1

Включаючи всі пакети ігрових послуг

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

Ви пригнічуєте помилку, але кінцевим результатом є те, що отримання маркера GCM не працює, і ми не можемо отримати екземпляр GCM. Тож це не рішення в моїх книгах. Якщо хтось уявляє, що відбувається, будь ласка, просвітліть нас.

РЕДАГУВАТИ:

Я замінив GCM на firebase, оновив андроїд-студію з 2.1 на 2.2, щоб виправити проблему миттєвого запуску з аналітикою firebase, оновив інструменти збірки до 24-rc4 та інструменти платформи до 24-rc3, і зберіг версію моєї бібліотеки підтримки до 23.4.0. Здається, зараз усе працює добре.


схоже, ми маємо впровадити FCM
sonique

я зробив це, і я все ще отримую ту ж помилку. Я повністю видалив GCM і замінив його на FCM виходячи з цього: developers.google.com/cloud-messaging/android/... Щось не так з бібліотекою підтримки, а не з пакетами GCM або FCM
Стіліанос Цуварас

1

У мене була та сама проблема, і повернення із сховища підтримки Android 32.0.0 до сховища підтримки Android 31.0.0 це вирішило.


3
як повернути сховище підтримки Android?
Пратама Нур Віджая

2
Ну, єдиний спосіб, який я знайшов, - це скопіювати старе сховище замість нового. Сховище зазвичай знаходиться в папці Android, на яку вказує ваш «менеджер SDK» (якщо ви використовуєте mac, це, швидше за все, це шлях ~ / Library / Android / sdk / extras). У папці extras замініть папки android та google на старі.
BorisK

Я знайшов репо тут: dl-ssl.google.com/android/repository/… , потім розпакував його в ../sdk/extras/android і видалив існуючий m2reposity, здавалося, працював дотепер.
Том Редман

1

Для push-сповіщення Android з GCM 2016:

1) в Android SDK-> SDK Tools перевірити служби Google Play

2) у gradle додайте у залежності лише один рядок:

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

(немає конкретного шляху до класу, і він працює для мене)

3) ви повинні створити 3 клас (GCMPushReceiverService, GCMRegistrationIntentService, GCMTokenRefreshListenerService)

4.1) код для 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) Код для GCMRegistrationIntentService (змініть санкціонований Entity на номер проекту):

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) Код для 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) Не забудьте змінити назву пакета

6) У свою mainActivity вставте цей код:

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) У своєму AndroidManifest.xml додайте такі рядки:

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

8) у вашій консолі logcat скопіюйте свій маркер і вставте на цей сайт, додайте номер проекту, свій маркер та повідомлення. Для мене це добре працює :)


Привіт @Skygirl. Я беру за вашим прикладом будь-яку особливу вимогу в AndroidManifest? Не могли б ви додати цю частину коду? Дякую
ziniestro

0

Після цілого дня я можу на 100% підтвердити, що бібліотека Optimizely також певним чином зіткнеться і спричинить цю помилку. Якщо конкретно, я використовую Optimizely через Fabric. Неможливо змусити Firebase ініціалізуватись, використовуючи Optimizely таким чином (можливо, всіма способами?).

Я писав про це на їхньому github і зв’яжусь з ними безпосередньо ...

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


0

У мене була та сама проблема. Я оновив інструменти SDK до версії 25.1.7 rc1, тоді проблема зникла.


0

оновив інструменти SDK до версії 25.1.7 та виправив цю проблему.


0

Ну, я лише новачок у використанні Android. Я хотів протестувати створення користувачів, Firebaseдотримуючись інструкцій, які містяться на веб-сайті Firebase.

Я додав ці рядки у зазначених місцях.

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

компілювати 'com.google.firebase: firebase-auth: 9.2.0'

застосувати плагін: 'com.google.gms.google-services'

Але метод createUserWithEmailAndPassword постійно демонстрував невдачі у створенні користувачів. Ось чому я відвідав це питання, щоб з’ясувати свою проблему. Я прочитав усі і застосував кожну пораду. але ІТ постійно демонстрували невдачі. Але під час оновлення Android Studio from 2.1.1 to 2.1.2я міг успішно створювати користувачів.

Але коли я перевірив logcat, він спочатку показав, "Firebase API initialization failure"а потім показав "Ініціалізація FirebaseApp успішна".

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

це? java.lang.reflect.InvocationTargetException у java.lang.reflect.Method.invokeNative (власний метод) у java.lang.reflect.Method.invoke (Method.java:515) на com.google.firebase.FirebaseApp.zza (Невідомо Джерело) на com.google.firebase.FirebaseApp.initializeApp (невідоме джерело) на com.google.firebase.FirebaseApp.


Гаразд. Дякую. Я подумав, що було б непогано поділитися, як я вирішив свою проблему. (Тільки я не був впевнений, що вирішив це повністю. Я міг створити користувача за допомогою com.google.firebase: firebase-auth: 9.2.0 після оновлення версії Android Studio, але він все ще має помилку ініціалізації Firebase API в logcat. Так що мені було цікаво ) Наступного разу я скористаюся кнопкою "ЗАПИТАТИ запитання".
Jayground

0

Я зіткнувся з цією проблемою, і я змінив версію програми gradle з 1.5.0 на 2.0.0.

змінити шлях до класу -

com.android.tools.build:gradle:1.5.0

до

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


0

Рішення 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`
}

Рішення 2: виявити несумісне в папці .idie / libraries / .деколи ви оголошуєте play-services-ads: 8.4.0 одночасно з play-services-gcm: 9.0.0. Ви повинні перевизначити виявлені несумісні бібліотеки build.grade, які ви виявили

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.