3

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

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 [email protected] 
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> 

UPDATE 2 - добавление класса Alarm

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); 
    } 
} 
+1

пожалуйста предоставить файл манифеста ... –

+0

проявляется в настоящее время добавлено – barry

+0

Проблема с классом Alarm. Отправьте код для этого. –

ответ

0

в

ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader 

<receiver android:name=".alarm.BootReceiver" > 
+0

в манифесте AlarmBroadcastReceiver уже определяет как приемник – rajpara

+0

Приемник BootReceiver используется для перехвата запуска устройства. Объект «Тревога» не является приемником, просто простым объектом, который передается в AlarmBroadcastReceiver. – barry

+0

это класс, который у вас есть «Тревога» – rajpara

0

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

EDIT:

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

+0

Я использую 'public Intent putExtra (String name, Serializable value)' , который принимает Serializable – barry

+0

Как вы извлекаете дополнительные из намерения, когда получаете его? –

+0

'Alarm alarmJustSounded = (Alarm) intent.getExtras(). GetSerializable (Constants.SCHEDULED_ALARM_TAG);' – barry

0

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

0

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

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

  • Создание Intent с строкой действий для PendingIntent.
  • Зарегистрируйте мой BroadcastReceiver статически в AndroidManifest.
8

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

Это недостаток в андроиде. Мой целевой 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"); 
+0

Я просто отладил аналогичную проблему с ClassNotFound при распаковке дополнительных функций из намерения. Я обнаружил, что проблема проявляется (не каламбур), когда Intent транслируется из другого потока, а затем принимается в основном потоке (UI). Перемещение трансляции намерения в поток пользовательского интерфейса, так что трансляция не перемещается по потокам, устранена проблема! – RobP

+0

Похож на мою проблему, м, используя Serializable, не являющийся возможным – barry

Смежные вопросы