Problems with parcelable custom object - Android - java

I am trying to pass a custom object from one activity to another one.
I found that we can use a bundle to pass data into the intent and that we need a parcelable interface implemented in our class.
In the following code I removed the useless stuff.
public class TravelCard implements Parcelable {
public static final Creator<TravelCard> CREATOR = new Creator<TravelCard>() {
#Override
public TravelCard createFromParcel(Parcel in) {
return new TravelCard(in);
}
#Override
public TravelCard[] newArray(int size) {
return new TravelCard[size];
}
};
private String travelTitle, travelCountry, dateRange, numOfPerson;
private List<TravelDay> days;
protected TravelCard(Parcel in) {
travelTitle = in.readString();
travelCountry = in.readString();
dateRange = in.readString();
numOfPerson = in.readString();
in.readTypedList(days, TravelDay.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.travelTitle);
dest.writeString(this.travelCountry);
dest.writeString(this.dateRange);
dest.writeString(this.numOfPerson);
dest.writeTypedList(this.days);
}
In this class I have a List of another custom object:
public class TravelDay implements Parcelable {
public static final Creator<TravelDay> CREATOR = new Creator<TravelDay>() {
#Override
public TravelDay createFromParcel(Parcel in) {
return new TravelDay(in);
}
#Override
public TravelDay[] newArray(int size) {
return new TravelDay[size];
}
};
public int current_day;
private String title, note, dateOfToday;
protected TravelDay(Parcel in) {
title = in.readString();
note = in.readString();
dateOfToday = in.readString();
current_day = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(note);
dest.writeString(dateOfToday);
dest.writeInt(current_day);
}
I think until here everything should be fine.
In my activity :
Intent intent = new Intent(MainActivity.this, TravelDayActivity.class);
Bundle data = new Bundle();
data.putParcelable(DataKey.TRAVEL_CARD_BUNDLE,item);
intent.putExtras(data);
startActivity(intent);
And then in the TravelDayActivity :
Intent intent = getIntent();
Bundle data = intent.getExtras();
TravelCard travelCard = data.getParcelable(DataKey.TRAVEL_CARD_BUNDLE);
Every time I tried to access the TravelDayActivity the app stop running.
I used the debug mode to search something wrong but I did not find anything.
Thank you in advance
EDIT :
In the MainActivity that's how I get the item variable:
mAdapter = new TravelCardAdapter(travelCards, new TravelCardAdapter.OnItemClickListener() {
#Override
public void onItemClick(TravelCard item) {
Intent intent = new Intent(MainActivity.this,TravelDayActivity.class);
Bundle data = new Bundle();
data.putParcelable(DataKey.TRAVEL_CARD_BUNDLE,item);
intent.putExtras(data);
startActivity(intent);
}
});
Whenever I click on one of the recycler view item this code above is executed.

After the suggestion of #BVantur, I solved my problem using the parceler library :
parceler library
It has been very helpful, easy to use and a good documentation! I highly recommend it.

Related

Utilising Parcelable to send Array across two activities

I'm trying to send a populated array of a created class called 'Exercise' between two activities, and I've read the best way to do so I utilising the Parcelable class.
Activity 2 crashes whenever it starts. I've followed tutorials online for this and this is how they treat the sending of the data.
Exercise Class:
import android.os.Parcel;
import android.os.Parcelable;
public class Exercise implements Parcelable {
public String Name = "";
public int Time = 0;
public boolean SwitchDirection = false;
Exercise(String n, int l, boolean s){
Name = n;
Time = l;
SwitchDirection = s;
}
protected Exercise(Parcel in) {
Name = in.readString();
Time = in.readInt();
SwitchDirection = in.readByte() != 0;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Name);
dest.writeInt(Time);
dest.writeByte((byte) (SwitchDirection ? 1 : 0));
}
public static final Creator<Exercise> CREATOR = new Creator<Exercise>() {
#Override
public Exercise createFromParcel(Parcel in) {
return new Exercise(in);
}
#Override
public Exercise[] newArray(int size) {
return new Exercise[size];
}
};
}
Activity 1:
Exercise[] Exercises = new Exercise[]{
new Exercise("Scisssors", 60, false),
new Exercise("Cross Knee Planks", 60, false),
new Exercise("Twisting Pistons", 30, false),
new Exercise("Accordion Crunches", 60, true),
new Exercise("Canoe Crunch", 30, false),
new Exercise("Upper Circle Crunches", 30, true)
};
Intent i = new Intent(this, Activity2.class);
i.putExtra("Exercises", Exercises);
startActivity(i);
Activity 2:
Exercise[] Exercises;
Exercises = (Exercise[]) getIntent().getParcelableArrayExtra("Exercises");
I think you don't should send and get an array of Parcelable. You should give an array for Parcelable, and get it in Activity 2.
I have an example that send a HashMap between 2 activities.
public class BaseData implements Parcelable {
protected HashMap<String, Object> mData;
public BaseData(HashMap<String, Object> data) {
mData = data;
}
protected BaseData(Parcel in) {
try {
mData = in.readHashMap(HashMap.class.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
public static final Creator<BaseData> CREATOR = new Creator<BaseData>() {
#Override
public BaseData createFromParcel(Parcel in) {
return new BaseData(in);
}
#Override
public BaseData[] newArray(int size) {
return new BaseData[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
try {
if (null == mData) {
return;
}
dest.writeValue(mData);
} catch (Exception e) {
}
}
public HashMap<String, Object> getData() {
return mData;
}
}
In Activty 1 you will send data like that:
HashMap<String, Object> hm = new HashMap<>();
hm.put("data_1", array_data_1);
hm.put("data_2",array_data_2);
BaseData baseData = new BaseData(hm);
BaseData baseData = new BaseData(data);
Bundle bundle = new Bundle();
bundle.putParcelable("base_data", baseData);
Intent intent = new Intent(context,Activity2.class)
intent.putExtra("data",bundle);
In Activy 2 you will receive a bundle, then get basedata from bundle and get HashMap from basedata.
Bundle bundle = getIntent().getBundleExtra("data");
BaseData baseData = bundle.getParcelable("base_data");
HashMap<String,Object> hm = baseData.getData();
You can replace HashMap by Array. If you can't implement it, please tell me I will send you a complete example.

How to pass a list from a class to an activity?

I declare a List object in a method of a java class, which gets filled with data inside this method. Now I want to pass the filled list to another activity. How should I do that?
if you are in a JAVA class and want to call the list in an Activity, them simply put the method return type as list and call it in the required Activity . Demo code is as follows
class ReturnList{
public List method(){
List list=new ArrayList();
return list;}
}
class ActivityDemo extends Activity{
onCreate(){
///activity code
ReturnList returnListObj=new ReturnList();
List listData= returnListObj.method();
//deal with list here
}}
First make your object class parcelable.
Pass data as a bundle
Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("data", yourObject);
intent.putExtras(bundle);
startActivity(intent);
Retrieving the data:
Bundle bundle = getIntent().getExtras();
yourObject = bundle.getParcelable("data");
Hope it helps :)
Define your class as below
public class CategoryEntity implements Parcelable{
public int id;
public String name;
public String imageOriginal;
public String imageThumb;
public String description;
public String status;
public String createdAt;
public String updatedAt;
public int imageDummy;
protected CategoryEntity(Parcel in) {
id = in.readInt();
name = in.readString();
imageOriginal = in.readString();
imageThumb = in.readString();
description = in.readString();
status = in.readString();
createdAt = in.readString();
updatedAt = in.readString();
imageDummy = in.readInt();
}
public static final Creator<CategoryEntity> CREATOR = new Creator<CategoryEntity>() {
#Override
public CategoryEntity createFromParcel(Parcel in) {
return new CategoryEntity(in);
}
#Override
public CategoryEntity[] newArray(int size) {
return new CategoryEntity[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeString(imageOriginal);
dest.writeString(imageThumb);
dest.writeString(description);
dest.writeString(status);
dest.writeString(createdAt);
dest.writeString(updatedAt);
dest.writeInt(imageDummy);
}
}
Pass your data using Bundle
startActivity(new Intent(CategoriesListingActivity.this, StoryDetailActivity.class)
.putExtra("List", your list with model class));
Handle your list in another activity
Bundle extra = getIntent().getExtras();
if (extra != null) {
storyList = (ArrayList<CategoryEntity>) extra.getParcelable("StoryListing");
}
Hope this will helps you.
Pass your list in intent.putExtra(), for example
Intent intent = new Intent(getApplicationContext() , YourNextActivity.class);
intent.putExtra("list" , (Serializable) yourList);
startActivity(intent);
and for retrieve list in NextActivity
Intent intent = getIntent();
intent.getSerializableExtra("list");

How to pass array list using intent in android

How can i pass array list from one activity to another activity using intent.
From activity
ArrayList<ServicesInfo> bookedService = new ArrayList<ServicesInfo>();`
Intent intent = new Intent(getActivity() , Proceedtocart.class);
intent.putExtra("Listview",bookedService);
startActivity(intent);
To activity
bookedService = (ArrayList<BookedInfo>) getIntent().getSerializableExtra("Listview");
while running am getting error as "java.lang.runtimeexception parcel unable to marshal value android"
Help to to fix this issue
Try this :
Intent intent = new Intent(this, NextActivity.class);
intent.putStringArrayListExtra("Listview", bookedService);
startActivity(intent);
and on NextActivity :
yourArrayList = getIntent().getStringArrayListExtra("Listview");
You can use
public class ContactInfo {
private String name;
private String surname;
private int idx;
// get and set methods
}
public class ContactInfo implements Parcelable {
private String name;
private String surname;
private int idx;
// get and set method
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(surname);
dest.writeInt(idx);
}
// Creator
public static final Parcelable.Creator CREATOR
= new Parcelable.Creator() {
public ContactInfo createFromParcel(Parcel in) {
return new ContactInfo(in);
}
public ContactInfo[] newArray(int size) {
return new ContactInfo[size];
}
};
// "De-parcel object
public ContactInfo(Parcel in) {
name = in.readString();
surname = in.readString();
idx = in.readInt();
}
}
Put
Intent i = new Intent(MainActivity.this, ActivityB.class);
// Contact Info
ContactInfo ci = createContact("Francesco", "Surviving with android", 1);
i.putExtra("contact", ci);
Get
Intent i = getIntent();
ContactInfo ci = i.getExtras().getParcelable("contact");
tv.setText(ci.toString()); // tv is a TextView instance

Getting items from parcelable array list

I'm having troubles with getting content from getParcelableArrayList.
I have data model class that extends parcelable
#DatabaseTable(tableName = "note")
public class Log implements Parcelable {
#DatabaseField(id = true, index = true)
UUID id;
#DatabaseField
String title;
#DatabaseField
String description;
public Log() {
}
#Override
public int describeContents() {
return 0;
}
public Log(Parcel in) {
this.title = in.readString();
this.description = in.readString();
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(title);
out.writeString(description);
}
public void readFromParcel(Parcel in){
title = in.readString();
description = in.readString();
}
public static final Parcelable.Creator<Log> CREATOR = new Parcelable.Creator<Log>(){
public Log createFromParcel(Parcel in){
return new FoodLog(in);
}
public Log[] newArray(int size){
return new FoodLog[size];
}
};
And I want make feature for editing entry in database.
I'm sending data from activity one to activity two via bundle like this
Activity one:
Intent intent = new Intent(LogList.this, AddLogActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("list", new ArrayList<>(mLog));
intent.putExtras(bundle);
startActivity(intent);
Receiving bundle via intent in Activity two:
Intent mIntent = getIntent();
if (mIntent != null) {
Bundle bundle = mIntent.getExtras();
if (bundle != null) {
mLogParcel = bundle.getParcelableArrayList("list");
}
}
So, my question is how to get data from passed arraylist in Activity two?
I have data saved inArrayList<Log> mLogParcel;, and I tried using readFromParcel on mLogParcel, but without positive results.
How to get data based on data model in this case?
Thanks a lot!

BadParcelableException: Launcher shortcut

I'm trying to pass in a custom Object into a shortcut I'm installing on the home screen, but I'm receiving a BadParcelableException when as soon as the shortcut is created. I've tried calling Bundle.setClassLoader, but the error persists.
Is there just a limitation with launchers that support home screen shortcuts?
public class Foo implements Parcelable {
public String title;
private Foo(Parcel in) {
title = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
}
public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
#Override
public Foo createFromParcel(Parcel in) {
return new Foo(in);
}
#Override
public Foo[] newArray(int size) {
return new Foo[size];
}
};
}
public static void installShortcut(Context context, Foo foo) {
final Bundle args = new Bundle();
args.setClassLoader(Foo.class.getClassLoader());
args.putParcelable(EXTRA_FOO, foo);
final Intent detail = new Intent(context, FooActivity.class);
detail.putExtras(args);
final Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, detail);
...
context.sendBroadcast(shortcut);
}

Categories

Resources