0
votes

I am developing an alarm app and I am trying to pass the realm object to alarm manager for setting an alarm

Caused by: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = io.realm.AlarmRealmProxy) at android.os.Parcel.writeSerializable(Parcel.java:1527) at android.os.Parcel.writeValue(Parcel.java:1475) at android.os.Parcel.writeArrayMapInternal(Parcel.java:724) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1408) at android.os.Bundle.writeToParcel(Bundle.java:1157) at android.os.Parcel.writeBundle(Parcel.java:764) at android.content.Intent.writeToParcel(Intent.java:8687) at android.os.Parcel.writeTypedArray(Parcel.java:1307) at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java:4653) at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:562) at android.app.PendingIntent.getBroadcast(PendingIntent.java:545) at in.kka.physiotherapy.model.Alarm.schedule(Alarm.java:143) at in.kka.physiotherapy.service.AlarmService.onStartCommand(AlarmService.java:99) at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3326) at android.app.ActivityThread.-wrap21(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6119)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)  Caused by: java.io.NotSerializableException: io.realm.AlarmRealmProxy$AlarmColumnInfo at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1224) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1584) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1549) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1472) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1218) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346) at android.os.Parcel.writeSerializable(Parcel.java:1522) at android.os.Parcel.writeValue(Parcel.java:1475)  at android.os.Parcel.writeArrayMapInternal(Parcel.java:724)  at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1408)  at android.os.Bundle.writeToParcel(Bundle.java:1157)  at android.os.Parcel.writeBundle(Parcel.java:764)  at android.content.Intent.writeToParcel(Intent.java:8687)  at android.os.Parcel.writeTypedArray(Parcel.java:1307)  at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java:4653)  at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:562)  at android.app.PendingIntent.getBroadcast(PendingIntent.java:545)  at in.kka.physiotherapy.model.Alarm.schedule(Alarm.java:143)  at in.kka.physiotherapy.service.AlarmService.onStartCommand(AlarmService.java:99)  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3326)  at android.app.ActivityThread.-wrap21(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6119)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

Here is my code my class implements Serializable but i'm not able to pass intent extra, i am getting error here myIntent.putExtra("alarm", this);

public void schedule(Context context) {
        Realm  realm = Realm.getDefaultInstance();

        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                setAlarmActive(true);
            }
        });


        Intent myIntent = new Intent(context, AlarmServiceBroadcastReciever.class);
        myIntent.putExtra("alarm", this);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,PendingIntent.FLAG_CANCEL_CURRENT);

        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        alarmManager.set(AlarmManager.RTC_WAKEUP, getAlarmTime().getTime(), pendingIntent);
    }
1

1 Answers

1
votes

You're trying to pass a managed, "live" realm object, which is based by a proxy implementation - you need to pass a "detached" unmanaged object to the intent. Change this line:

myIntent.putExtra("alarm", this);

To this:

myIntent.putExtra("alarm", realm.copyFromRealm(this));

Also, you should close the Realm instance, preferably wrapping the transaction and copyFromRealm call in a try-catch block:

Realm realm = null;
try {
    realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm transactionRealm) {
            setAlarmActive(true);
        }
    });
    Intent myIntent = new Intent(context, AlarmServiceBroadcastReciever.class);
    myIntent.putExtra("alarm", realm.copyFromRealm(this));
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, getAlarmTime().getTime(), pendingIntent);
} finally {
    if(realm != null) {
        realm.close();
    }
}