In order to create a precise alert with some information, I tried to pass a simple POJO through the extra data of an Intent
, nested into a PendingIntent
. I gave this latter to the AlertManager
service class.
I tried to implement Serializable
, I ended up with null
s when receiving the PendingIntent
. I then tried to implement Parcelable
and adding all the needed methods and members, still ending in getting null
s.
I succeeded by doing a work-around, consisting in copying the ParcelableUtil
class found here and putting the marshalled data as a byte array. This worked, for some reason.
private void scheduleAlert(Element element) {
Intent intent = new Intent(this.context, ReminderReceiver.class);
// Serializes the element and puts it into the extra intent data.
// ---- TRY 1 (tried with Serializable & Parcelable)
intent.putExtra("extra key", element);
// --------
// ---- TRY 2
Bundle extras = new Bundle();
extras.putSerializable("extra key", element);
intent.putExtras(extras);
// --------
// ---- TRY 3
Bundle extras = new Bundle();
bundle.putParcelable("extra key", element);
intent.putExtras(extras);
// --------
// ---- WORKAROUND
byte[] bytes = ParcelableUtil.marshall(element);
intent.putExtra("extra key", bytes);
// --------
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, element.getRequestCode(), intent, 0);
AlarmManager alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE);
long reminderPeriodMillis = element.getReminderPeriod() * 1000;
long firstAlarmMillis = SystemClock.elapsedRealtime() + reminderPeriodMillis;
// Creates the alarm.
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstAlarmMillis, pendingIntent);
}
The Element class can be found bellow.
public class Element implements Serializable, Parcelable {
private static final long serialVersionUID = 1L;
private String title;
private int reminderPeriod;
private int requestCode;
public Element(String title, int reminderPeriod, int requestCode) {
this.title = title;
this.reminderPeriod = reminderPeriod;
this.requestCode = requestCode;
}
public Element(Parcel in) {
this.title = in.readString();
this.reminderPeriod = in.readInt();
this.requestCode = in.readInt();
}
public static final Creator<Element> CREATOR = new Creator<Element>() {
@Override
public Element createFromParcel(Parcel source) {
return new Element(source);
}
@Override
public Element[] newArray(int size) {
return new Element[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.title);
dest.writeInt(this.reminderPeriod);
dest.writeInt(this.requestCode);
}
public String getTitle() {
return this.title;
}
public int getReminderPeriod() {
return this.reminderPeriod;
}
public int getRequestCode() {
return this.requestCode;
}
}
And the code receiving the alarm:
@Override
public void onReceive(Context context, Intent intent) {
// TRY 1 (with Serializable)
Element element = (Element) intent.getSerializableExtra("extra key");
// --------
// TRY 1 (with Parcelable)
Element element = (Element) intent.getParcelableExtra("extra key");
// --------
// TRY 2
Bundle extras = intent.getExtras();
Element element = (Element) extras.getSerializable("extra key");
// --------
// TRY 3
Bundle extras = intent.getExtras();
Element element = extras.getParcelable("extra key");
// --------
// ---- WORKAROUND
Bundle bundle = intent.getExtras();
Parcel parcelIn = ParcelableUtil.unmarshall(bundle.getByteArray("extra key"));
Element element = new Element(parcelIn);
// --------
// [...]
}
TL;DR: Why is my data not kept as Parceled and Serialized extra, but kept if passed as an extra byte array?