0
votes

I have made my own class called Alarm. I then made a List called AlarmList. I wish to send this list between two Activities, but nothing seems to get sent.

Here is my code:

The Alarm class:

public class Alarm {
    private String Name;
    private List<String> Days;
    private String Id;
    private int Hour;
    private int Minute;
    private Uri Ringtone;

public Alarm(String newId, String newName, int newHour, int newMinute, Uri newRingtone, List<String> newDaysList){
    setId(newId);
    setName(newName);
    setHour(newHour);
    setMinute(newMinute);
    setRingtone(newRingtone);
    setDays(newDaysList);
}

public String getName(){
    return Name;
}
public void setName(String newName){
    Name = newName;
}

public List<String> getDays(){
    return Days;
}
public void setDays(List<String> newDaysList){
    Days = newDaysList;
}
public void addDay(String newDay){
    Days.add(newDay);
}

public String getId(){
    return Id;
}
public void setId(String newId){
    Id = newId;
}

public int getHour(){
    return Hour;
}
public void setHour(int newHour){
    Hour = newHour;
}

public int getMinute(){
    return Minute;
}
public void setMinute(int newMinute){
    Minute = newMinute;
}

public Uri getRingtone(){
    return Ringtone;
}
public void setRingtone(Uri newRingtone){
    Ringtone = newRingtone;
}
}

MainActivity:

private List<Alarm> AlarmList;

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
    setupViewPager(mViewPager);

    TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    Intent intent = getIntent();
    if(intent.hasExtra("AlarmList")){
        AlarmList = (List<Alarm>) intent.getSerializableExtra("AlarmList");
        Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_SHORT).show();
    }
    else{
        AlarmList = new ArrayList();

        // This part is for debugging purposes
        Uri myUri = Uri.parse("http://www.google.com");
        List<String> rList = new ArrayList<>();

        Alarm tempAlarm = new Alarm("id1", "name1", 10, 20, myUri, rList);
        AlarmList.add(tempAlarm);
        tempAlarm = new Alarm("id2", "name3", 11, 21, myUri, rList);
        AlarmList.add(tempAlarm);
        tempAlarm = new Alarm("id3", "name3", 12, 22, myUri, rList);
        AlarmList.add(tempAlarm);
        // This part is for debugging purposes
    }

public void addAlarm_Click(View v) {
    Intent intent = new Intent(this, AddAlarmActivity.class);
    intent.putExtra("AlarmList", (Serializable) AlarmList);
    startActivity(intent);
}

public void deleteAlarm_Click(View v) {
    for (Alarm x: AlarmList) {
        Toast.makeText(MainActivity.this, "" + x.getId(), Toast.LENGTH_SHORT).show();
    }
}

AddAlarmActivity:

@Override
@SuppressWarnings("unchecked")
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_addalarm);

    Intent intent = getIntent();
    AlarmList = (List<Alarm>) intent.getSerializableExtra("AlarmList");

    MyTimePicker = (TimePicker) findViewById(R.id.timePicker);
    MyTimePicker.setIs24HourView(true);

    ringtoneLabel = (EditText)findViewById(R.id.EditText_RingtoneUri);
    ringtoneLabel.setEnabled(false);

    ringtoneUri = null;


    for (Alarm x: AlarmList) {
        // Debugging
        Toast.makeText(AddAlarmActivity.this, "" + x.getId(), Toast.LENGTH_SHORT).show();
    }
}

I want to take my List, send it with the Intent, recieve it in the other Activity and check it's contents with the loop. I later want to send the list back to MainActivity after modifying it.

I added some dummy data to the list, just to see if anything gets sent at all. But now the app just crashes whenever I click on the "AddAlarm" button.

In order to make sure that some other Intent isn't starting the Activity and messing everything up I added the check intent.hasExtra("AlarmList") I figured that that would make sure that I don't get some strange data.

I am currently using my DeleteAlarm Button for debugging. If I run the app and click on the DeleteAlarm Button it starts toasting "id1", "id2", "id3" - so that part works as intended.

Here is the crash log:

09-17 11:03:19.958 28930-28930/com.example.alarmclock E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.alarmclock, PID: 28930 java.lang.IllegalStateException: Could not execute method for android:onClick at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) at android.view.View.performClick(View.java:4793) at android.view.View$PerformClick.run(View.java:19959) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5596) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) at android.view.View.performClick(View.java:4793)  at android.view.View$PerformClick.run(View.java:19959)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5596)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)  Caused by: java.lang.RuntimeException: Parcel: unable to marshal value com.example.persson.peter.alarmclock.Alarm@3982ba66 at android.os.Parcel.writeValue(Parcel.java:1343) at android.os.Parcel.writeList(Parcel.java:717) at android.os.Parcel.writeValue(Parcel.java:1290) at android.os.Parcel.writeArrayMapInternal(Parcel.java:644) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1320) at android.os.Bundle.writeToParcel(Bundle.java:1036) at android.os.Parcel.writeBundle(Parcel.java:669) at android.content.Intent.writeToParcel(Intent.java:7531) at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2447) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1496) at android.app.Activity.startActivityForResult(Activity.java:3843) at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79) at android.app.Activity.startActivityForResult(Activity.java:3797) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859) at android.app.Activity.startActivity(Activity.java:4114) at android.app.Activity.startActivity(Activity.java:4082) at com.example.persson.peter.alarmclock.MainActivity.addAlarm_Click(MainActivity.java:65) at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)  at android.view.View.performClick(View.java:4793)  at android.view.View$PerformClick.run(View.java:19959)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5596)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

2
Try to let Alarm class implement Serializable .KeLiuyue
@KeLiuyue I added "implements Serializable". Still crashes. Seems to be same crash log.user6334610
You can try my answer.@PhrosenKeLiuyue

2 Answers

0
votes

Don't use serializable because you can serialize you model Alarm but inside your alarm, you are using Uri object.

Uri object is Parcelable not Serializable so it like boilerplate.

You better implement Parcelable in your Alarm class.

Your Alarm class should be like this:

public class Alarm implements Parcelable {
    public static final Creator<Alarm> CREATOR = new Creator<Alarm>() {
        @Override
        public Alarm createFromParcel(Parcel in) {
            return new Alarm(in);
        }

        @Override
        public Alarm[] newArray(int size) {
            return new Alarm[size];
        }
    };
    private String Name;
    private List<String> Days;
    private String Id;
    private int Hour;
    private int Minute;
    private Uri Ringtone;

    public Alarm(String newId, String newName, int newHour, int newMinute, Uri newRingtone, List<String> newDaysList) {
        setId(newId);
        setName(newName);
        setHour(newHour);
        setMinute(newMinute);
        setRingtone(newRingtone);
        setDays(newDaysList);
    }

    protected Alarm(Parcel in) {
        Name = in.readString();
        Days = in.createStringArrayList();
        Id = in.readString();
        Hour = in.readInt();
        Minute = in.readInt();
        Ringtone = in.readParcelable(Uri.class.getClassLoader());
    }

    public String getName() {
        return Name;
    }

    public void setName(String newName) {
        Name = newName;
    }

    public List<String> getDays() {
        return Days;
    }

    public void setDays(List<String> newDaysList) {
        Days = newDaysList;
    }

    public void addDay(String newDay) {
        Days.add(newDay);
    }

    public String getId() {
        return Id;
    }

    public void setId(String newId) {
        Id = newId;
    }

    public int getHour() {
        return Hour;
    }

    public void setHour(int newHour) {
        Hour = newHour;
    }

    public int getMinute() {
        return Minute;
    }

    public void setMinute(int newMinute) {
        Minute = newMinute;
    }

    public Uri getRingtone() {
        return Ringtone;
    }

    public void setRingtone(Uri newRingtone) {
        Ringtone = newRingtone;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(Name);
        dest.writeStringList(Days);
        dest.writeString(Id);
        dest.writeInt(Hour);
        dest.writeInt(Minute);
        dest.writeParcelable(Ringtone, flags);
    }
}

You can get the Arraylist at receiver activity like this:

ArrayList<Alarm> parcelableArrayListExtra = getIntent().getParcelableArrayListExtra("");
0
votes

Try this .

  1. Let Alarm class implement Parcelable .

  2. use Intent and Bundle

    Intent intent = new Intent(this, AddAlarmActivity.class);
    Bundle bundle = new Bundle();  
    //add list to Bundle
    bundle.putParcelableArrayList("AlarmList", AlarmList);  
    // add Bundle to intent
    intent.putExtras(bundle);  
    startActivity(intent); 
    
  3. In the next Activity

    Bundle bundle = getIntent().getExtras();
    ArrayList<Alarm> list = bundle.getParcelableArrayListExtra("AlarmList");