Velogiraptor Velogiraptor - 1 month ago 8
Android Question

getParcelableExtra always null on Pending Intent, but not Intent

I'm new to Java let alone Android development. I have no coding background, but thought I'd start with something 'simple' like an alarm clock. So now I'm writing an alarm clock, and I want to update the alarms to be inactive if they aren't repeating after they go off. When I pass a parcelable AlarmClass (my alarm object) to the alarm set screen with an intent, it passes just fine.
When I pass the same AlarmClass to an intent, and put it in a PendingIntent in the Alarm Manager and then try to get it from the screen where you can dismiss the alarm, the AlarmClass object that I'm calling and populating the exact same way is always null.

Here's my alarm class:

package com.example.wakeme;

import java.util.Calendar;

import android.os.Parcel;
import android.os.Parcelable;

public class AlarmClass implements Parcelable{
Calendar cal = Calendar.getInstance();
private long id = 1;
private int active = 1;
private long time = cal.getTimeInMillis();
private int repeating = 0;
private int skipweekends = 0;
private int skipweekdays = 0;
private int alarmnumber = -1;


public long getId(){
return id;
}

public void setId(long id) {
this.id = id;
}

public int getActive(){
return active;
}

public void setActive(int active) {
this.active = active;
}

public int getRepeating(){
return repeating;
}

public void setRepeating(int repeating){
this.repeating = repeating;
}

public void setTime(long time){
this.time = time;
}

public long getTime(){
return time;
}

public int getSkipWeekends(){
return skipweekends;
}

public void setSkipWeekends(int skipweekends){
this.skipweekends = skipweekends;
}

public int getSkipWeekdays(){
return skipweekdays;
}

public void setSkipWeekdays(int skipweekdays){
this.skipweekdays = skipweekdays;
}

public void setAlarmNumber(int alarmnumber){
this.alarmnumber = alarmnumber;
}

public int getAlarmNumber(){
return alarmnumber;
}

@Override
public int describeContents(){
return 0;
}

private AlarmClass(Parcel in){
this.id = in.readLong();
this.active = in.readInt();
this.repeating = in.readInt();
this.skipweekdays = in.readInt();
this.skipweekends = in.readInt();
this.time = in.readLong();
this.alarmnumber = in.readInt();
}

AlarmClass() {
return;
}

public void writeToParcel(Parcel out, int flags) {
out.writeLong(this.id);
out.writeInt(this.active);
out.writeInt(this.repeating);
out.writeInt(this.skipweekdays);
out.writeInt(this.skipweekends);
out.writeLong(this.time);
out.writeInt(this.alarmnumber);
}

public static final Parcelable.Creator<AlarmClass> CREATOR = new Parcelable.Creator<AlarmClass>(){
public AlarmClass createFromParcel(Parcel in){
return new AlarmClass(in);
}
public AlarmClass[] newArray(int size) {
return new AlarmClass[size];
}
};


From here, I can pass my object to an alarm setter to update it just fine:

public void startSet(View view){
Intent set = new Intent(this, SetAlarm.class);
set.putExtra("alarm", new AlarmClass());
startActivity(set);
}


And I recieve it on my time setter right here just fine. It's non-null:

public class SetAlarm extends MainActivity {
AlarmClass passAlarm = new AlarmClass();


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm_set);
setAlarmSetListener();
setDeleteListener();
passAlarm = (AlarmClass) getIntent().getParcelableExtra("alarm");
if(passAlarm.getAlarmNumber() != -1){
TimePicker picker = (TimePicker) findViewById(R.id.timePicker1);
Calendar passedTime = Calendar.getInstance();
passedTime.setTimeInMillis(passAlarm.getTime());
picker.setCurrentHour(passedTime.get(Calendar.HOUR_OF_DAY));
picker.setCurrentMinute(passedTime.get(Calendar.MINUTE));
String ampm = (passedTime.get(Calendar.HOUR_OF_DAY) > 12 ? "pm" : "am");
String message = "Passed Time is: " + (passedTime.get((Calendar.HOUR_OF_DAY)%12)!=0?(passedTime.get(Calendar.HOUR_OF_DAY)%12):12) + ":" + passedTime.get(Calendar.MINUTE) + " " + ampm;
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
else{
// Do Nothing
}

}


But when sent via PendingIntent as so:

private void newAlarm(AlarmClass alarmclass){
Intent intent = new Intent(getBaseContext(), Alarm.class);
intent.putExtra("alarm", alarmclass);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(alarmclass.getTime());
AlarmsDataSource alarm = new AlarmsDataSource(this);
alarm.open();
AlarmClass alarmObject = new AlarmClass();
alarmObject = alarm.createAlarm(true, cal.getTimeInMillis(), false, false, false);
PendingIntent torpedo = PendingIntent.getBroadcast(this,alarmObject.getAlarmNumber(),intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager goOff = (AlarmManager) getSystemService(ALARM_SERVICE);
goOff.set(AlarmManager.RTC_WAKEUP, alarmObject.getTime() ,torpedo);
Toast.makeText(getApplicationContext(), "Alarm Number " + alarmObject.getAlarmNumber(), Toast.LENGTH_LONG).show();
alarm.close();
}


And received in the same way on the alarm activity as so:

public class Boom extends MainActivity{
AlarmClass boomAlarm = new AlarmClass();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Window wake = getWindow();
wake.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
setContentView(R.layout.boom);
setTheme(R.style.AlarmStyle);
overridePendingTransition(android.R.anim.fade_in,5000);
boomAlarm = (AlarmClass) getIntent().getParcelableExtra("alarm");
// Vibrator buzz = (Vibrator) getSystemService(VIBRATOR_SERVICE);
// buzz.vibrate(1000);
snoozeListener();
dismissListener();
}


The passed parcelable object that I'm passing into boomAlarm is always null.

Does anyone know why a parcelable object would work just fine in an intent, but come out null on the other side of a PendingIntent?

Answer

It turns out that the ParcelableExtra was getting dropped at the broadcast receiver! I was indeed passing it, BUT, when the broadcast receiver fired off the activity, it did not re-attach the extras; resulting in a null in the activity when it tried to getParcelableExtras.