Внедрение BroadcastReceiver ClassNotFound Exception

У меня есть приложение, которое использует AlarmManager для планирования аварийных сигналов для уведомления пользователя. Я передаю экземпляр моего объекта Alarm в PendingIntent, который используется AlarmManager:

public void scheduleAlarms(List<Alarm> alarms) { for (Alarm alarm : alarms) { Log.d(Constants.EVERY_OTHER_ALARM_APP_LOG_TAG, "Setting alarm for: " + new Date(alarm.getTime()).toString() + " with an interval of " + IntervalEnumStringProvider.getIntervalStringInGivenFormat( alarm.getInterval(), true)); PendingIntent alarmScheduledPending = createPendingIntent(alarm); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarm.getTime(), (alarm.getInterval() * Constants.ONE_SECOND_IN_MILLIS), alarmScheduledPending); } } private PendingIntent createPendingIntent(Alarm alarm) { alarmBroadcastReceiverIntent = new Intent(context, AlarmBroadcastReceiver.class); alarmBroadcastReceiverIntent.putExtra(Constants.SCHEDULED_ALARM_TAG, alarm); return PendingIntent.getBroadcast(context, alarm.getIdForPendingIntent(), alarmBroadcastReceiverIntent, PendingIntent.FLAG_UPDATE_CURRENT); } 

Когда время будильника происходит, мой класс AlarmBroadcastReceiver корректно принимает широковещательную передачу, но LogCat предупреждает, что класс Alarm не найден:

 06-29 08:30:00.084: W/Intent(66): Failure filling in extras 06-29 08:30:00.084: W/Intent(66): java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object (name = com.fastplanet.everyotheralarmapp.alarm.Alarm) 06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readSerializable(Parcel.java:1890) 06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readValue(Parcel.java:1761) 06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readMapInternal(Parcel.java:1947) 06-29 08:30:00.084: W/Intent(66): at android.os.Bundle.unparcel(Bundle.java:169) 06-29 08:30:00.084: W/Intent(66): at android.os.Bundle.putAll(Bundle.java:242) 06-29 08:30:00.084: W/Intent(66): at android.content.Intent.fillIn(Intent.java:4530) 06-29 08:30:00.084: W/Intent(66): at com.android.server.am.PendingIntentRecord.send(PendingIntentRecord.java:185) 06-29 08:30:00.084: W/Intent(66): at android.app.PendingIntent.send(PendingIntent.java:400) 06-29 08:30:00.084: W/Intent(66): at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:636) 06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm 06-29 08:30:00.084: W/Intent(66): at java.lang.Class.classForName(Native Method) 06-29 08:30:00.084: W/Intent(66): at java.lang.Class.forName(Class.java:237) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2595) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1848) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:852) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2006) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:956) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2289) 06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2243) 06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readSerializable(Parcel.java:1884) 06-29 08:30:00.084: W/Intent(66): ... 8 more 06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.NoClassDefFoundError: com.fastplanet.everyotheralarmapp.alarm.Alarm 06-29 08:30:00.084: W/Intent(66): ... 18 more 06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader dalvik.system.PathClassLoader@4001ad90 06-29 08:30:00.084: W/Intent(66): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243) 06-29 08:30:00.084: W/Intent(66): at java.lang.ClassLoader.loadClass(ClassLoader.java:573) 06-29 08:30:00.084: W/Intent(66): at java.lang.ClassLoader.loadClass(ClassLoader.java:532) 06-29 08:30:00.084: W/Intent(66): ... 18 more 

Однако BroadcastReceiver успешно распаковывает объект Alarm из полученного намерения, и приложение работает должным образом.

Что происходит?

UPDATE – добавленный манифест:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fastplanet.everyotheralarmapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:name=".data.TheEveryOtherAlarmAppApplication" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <receiver android:name="com.fastplanet.everyotheralarmapp.alarm.AlarmBroadcastReceiver" > </receiver> <receiver android:name=".alarm.BootReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> </intent-filter> </receiver> <activity android:name=".TheEveryOtherAlarmAppActivity" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".NewAlarmActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Dialog" > </activity> <activity android:name=".About" android:screenOrientation="portrait" android:theme="@android:style/Theme.Dialog" > </activity> <activity android:name=".AlarmAlertDialogActivity" android:excludeFromRecents="true" android:noHistory="true" android:taskAffinity="" android:theme="@android:style/Theme.NoDisplay" > </activity> <activity android:name=".AlarmDetailsActivity" android:screenOrientation="portrait" > </activity> </application> </manifest> 

ОБНОВЛЕНИЕ 2 – добавление класса сигнализации

 public class Alarm implements Serializable { private static final long serialVersionUID = -5410846652701834321L; private int id = 0; private String name = ""; private long interval = 0; private long time; private String description; public Alarm(String name, long time, long interval, String description, int id) { this.name = name; this.time = time; this.interval = interval; this.description = description; this.id = id; } public void setInterval(long newAlarmInterval) { this.interval = newAlarmInterval; } public long getInterval() { return interval; } public void setTime(long time) { this.time = time; } public long getTime() { return time; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setDescription(String newAlarmDescription) { this.description = newAlarmDescription; } public String getDescription() { return description; } public int getIdForPendingIntent() { return id; } @Override public String toString() { return "name: " + name + ", time: " + new Date(time).toLocaleString() + ", interval: " + IntervalEnumStringProvider.getIntervalStringInGivenFormat(interval, true) + ", description: " + description + ", id: " + id; } @Override public Alarm clone() throws CloneNotSupportedException { return new Alarm(new String(name), time, interval, new String(description), id); } } 

Я боролся с этой проблемой. Решение (кредит на мазур здесь ):

Это недостаток в андроиде. Мой целевой API – 19, а минимальный API – 11. дефект вводится здесь: «ClassNotFoundException при использовании пользовательских Parcelable» https://code.google.com/p/android/issues/detail?id=6822

При регистрации тревоги:

 Bundle bundle = new Bundle(); bundle.putParcelable("com.foo.alarm", alert); mNotificationReceiverIntent.putExtra("com.foo.alarm",bundle); mNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this, 0, mNotificationReceiverIntent, 0); 

При получении сигнала тревоги,

  Bundle oldBundle = intent.getBundleExtra("com.foo.alarm"); Alert alert = oldBundle.getParcelable("com.foo.alarm"); 

в виде

 ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader <receiver android:name=".alarm.BootReceiver" > 

Если вы хотите передать свой объект тревоги как EXTRA в Intent, тогда ваш класс Alarm должен реализовать Parcelable, а не Serializable.

РЕДАКТИРОВАТЬ:

Кажется, что это не так. Похоже, вы можете использовать Serializable. Однако OP не может заставить это работать, и есть другие должности в SE, где у людей возникли проблемы с тем, чтобы это работало.

Работая с ADT17, у меня такая же проблема, НО BroadcastReceiver не запустится. Я попробовал материал, обсужденный на SO: пытался изменить конфигурацию Proguard, но оказывается, что Proguard отключен по умолчанию . Пытался реализовать Parcelable но проблема все еще остается. Единственное, что сработало, – это установить BroadCastReceiver в тот же пакет, где находится класс получаемого объекта. Обратите внимание, что исключение все еще отображается как предупреждение, как описывает OP.

У меня была та же проблема, Android 2.3.

Передача сериализуемого дополнения в BroadcastReceiver теперь работает для меня после внесения следующих изменений:

  • Создайте намерение со строкой Action для PendingIntent.
  • Зарегистрируйте мой BroadcastReceiver статически в AndroidManifest.
Intereting Posts
Измените текстовый формат переключателя и получите список всех стран и поместите его в spinner Android. Как получить возвращаемое значение из AsyncTask в главную активность? Android WebView не загружает файл JavaScript, но Android Browser загружает его в порядке FirebaseUI и Firebase, какая разница? Eclipse не признает импорт Распечатать иерархию представлений на устройстве Android SDK – camera2 – Нарисуйте прямоугольник над TextureView ListView получает позицию прокрутки? Как показать соответствующий значок в диалоговом окне Недопустимая ошибка имени файла в eclipse для изображений Как получить количество строк TextView? Decibel Sound Meter для Android Как добавить два атрибута android: name в тег приложения в файле манифеста? Как вы получаете эффект пульсации, чтобы расширить границы просмотров? Android: Listview дублирует себя, когда я запускаю новое действие и нажимаю обратно, чтобы вернуться к нему