Utilising Parcelable to send Array across two activities - java

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.

Related

How to implement Parcelable for double ArrayList?

I got a JSON with an array of doubles and another for Strings. I am trying to create a Parcelable model class with the relevant methods. When the methods are created automaticaly, no line for the doubles' array list is created.
I looked for relevant questions and information, but, surprisingly, couldn't find any. I also added a jar file that was supposed to assist: android-parcelable-intellij-plugin.jar. Don't know what it's supposed to do and couldn't find information on how to use it.
My question is what should I write in the methods in order to get the array of doubles in a List.
The code:
public class Country implements Parcelable {
...
private List<String> timezones;
private List<Double> latlng;
protected Country(Parcel in) {
timezones = in.createStringArrayList();
this.latlng = new ArrayList<>(); // from jsonschema2pojo.org
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(timezones);
//nothing for the double array
}
public List<Double> getLatlng() {
return latlng;
}
public void setLatlng(List<Double> latlng) {
this.latlng = latlng;
}
public List<String> getTimezones() {
return timezones;
}
public void setTimezones(List<String> timezones) {
this.timezones = timezones;
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Country> CREATOR = new Creator<Country>() {
#Override
public Country createFromParcel(Parcel in) {
return new Country(in);
}
#Override
public Country[] newArray(int size) {
return new Country[size];
}
};
}
...
Thanks.
Try this below, it works for me :
public class Country implements Parcelable {
private List<String> timezones;
private List<Double> latlng;
public Country(List<String> timezones, List<Double> latlng) {
this.timezones = timezones;
this.latlng = latlng;
}
protected Country(Parcel in) {
timezones = in.createStringArrayList();
double[] doubleArray = in.createDoubleArray();
latlng = new ArrayList<>();
if (doubleArray != null) {
for (double ele : doubleArray) {
latlng.add(ele);
}
}
}
public static final Creator<Country> CREATOR = new Creator<Country>() {
#Override
public Country createFromParcel(Parcel in) {
return new Country(in);
}
#Override
public Country[] newArray(int size) {
return new Country[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(timezones);
double[] doubleArray = new double[latlng == null ? 0 : latlng.size()];
for (int i=0, len=latlng.size(); i<len; i++) {
doubleArray[i] = latlng.get(i);
}
dest.writeDoubleArray(doubleArray);
}
#Override
public String toString() {
return "Country{" +
"timezones=" + timezones +
", latlng=" + latlng +
'}';
}
}

Problems with parcelable custom object - Android

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.

Multiple putextra Unmarshalling unknown type code

I want to pass a custom object between my activities. I implemented Parceable for this class and put it in a extra. It works like a charm. Except if I put some other extras. In this case the app crash with this error : Unmarshalling unknown type code.
I have 2 class : A and B. A has a private field B. et my class B has a nested enum Enum. I implemented Parceable for A, B and Enum.
There is my code, I have rewritten it to be more concise.
A.java
public class A implements Parcelable {
B objectB;
String myString;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(myString);
out.writeParcelable(objectB, flags);
}
public static final Parcelable.Creator<Adresse> CREATOR = new Parcelable.Creator<Adresse>() {
public A createFromParcel(Parcel in) {
return new Adresse(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
private Adresse(Parcel in) {
myString = in.readString();
objectB = in.readParcelable(B.class.getClassLoader());
}
}
B.java
public class B implements Parceable {
Bitmap bitmap;
String otherString;
Enum enum;
public enum Enum implements Parceable {
ONE ("One")
TWO ("Two")
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(ONE.name);
out.writeString(TWO.name);
}
public static final Parcelable.Creator<Identifiant> CREATOR = new Parcelable.Creator<Enum>() {
public Enum createFromParcel(Parcel in) {
return Enum.values()[in.readInt()];
}
public Enum[] newArray(int size) {
return new Enum[size];
}
};
}
public B(Parcel in) {
readFromParcel(in);
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(otherString);
out.writeParcelable(bitmap, flags);
out.writeParcelable(enum, flags);
}
private void readFromParcel(Parcel in) {
otherString = in.readString();
bitmap = in.readParcelable(Bitmap.class.getClassLoader());
enum = in.readParcelable(Enum.class.getClassLoader());
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
#Override
public int describeContents() {
return 0;
}
MyActivity.java
Intent intent = new Intent(A.this, B.class);
Bundle bundle = new Bundle();
A objectA = new A();
bundle.putParcelable("A", a);
bundle.putInt("Int", 1); //If I comment this line it works
intent.putExtras(bundle);
startActivityForResult(intent, 1);

Passing multiple Objects between activities (using parcelable)

So what I am trying to do is pass ObjectB from the first activity to the second. ObjectB contains another object, ObjectA. I am getting really confused as to how to implement this. Also, I am using a list in ObjectA because I am going to have multiple integer values instead of just the 1 in this example. Here is the first activity:
private ObjectB objB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
objB = new ObjectB();
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("KEY", objB);
startActivity(intent);
}
and the second activity:
private ObjectB objB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
objB = new ObjectB();
TextView tv = (TextView) findViewById(R.id.TextView1);
Bundle b = getIntent().getExtras();
objB = b.getParcelable("KEY");
tv.setText(objB.obj.stage1Count);
}
Class for ObjectB:
public class ObjectB implements Parcelable{
public ObjectA obj;
public ObjectB() { obj = new ObjectA(); }
public ObjectA getObj() {
return obj;
}
public ObjectB(Parcel in) {
readFromParcel(in);
}
public void setObj(ObjectA obj) {
this.obj = obj;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(obj, flags);
}
private void readFromParcel(Parcel in) {
obj = in.readParcelable(ObjectA.class.getClassLoader());
}
public static final Parcelable.Creator CREATOR =
new Parcelable.Creator() {
public ObjectB createFromParcel(Parcel in) {
return new ObjectB(in);
}
public ObjectB[] newArray(int size) {
return new ObjectB[size];
}
};
}
Class for ObjectA:
public class ObjectA implements Parcelable{
public int stage1Count = 1;
public ObjectA() { ; };
public ObjectA(Parcel in) {
readFromParcel(in);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
List<Integer> iList = new ArrayList<Integer>();
iList.add(stage1Count);
dest.writeList(iList);
}
private void readFromParcel(Parcel in) {
List<Integer> iList = new ArrayList<Integer>();
iList = in.readArrayList(Integer.class.getClassLoader());
stage1Count = iList.get(0);
}
public static final Parcelable.Creator CREATOR =
new Parcelable.Creator() {
public ObjectA createFromParcel(Parcel in) {
return new ObjectA(in);
}
public ObjectA[] newArray(int size) {
return new ObjectA[size];
}
};
}
Try this in first activity:
List<ObjectB> list = new ArrayList<ObjectB>;
intent.putParcelableArrayListExtra("key", list);
And in second activity
List<ObjectB> list = new ArrayList<ObjectB>;
list = bundle.getParcelableArrayList("key");
From list get your objectB
This was a really dumb question but I figured it out after a really long time haha. The problem is tv.setText(objB.obj.stage1Count);because objB.obj.stage1Count is actually an integer but for some reason it does not ring any bells when you try to use it as a string, idk maybe its something with the parceing.

How to use Intent.putParcelableArrayListExtra() method and the Parcelable interface, I just want to transfer data in between two activity

Look at my code, wheather wrong in it.
Activity one:
Intent intent = new Intent(SendActivity.this, PickContactsActivity.class);
startActivityForResult(intent, 20);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
ArrayList<PickBean> cons = data.getParcelableArrayListExtra("data");
for (int i = 0; i < cons.size(); i++) {
JLog.e(LOG_TAG, "displayName:" + cons.get(i).displayName + "displayNumber" + cons.get(i).displayNumber);
}
}
}
Activity two:
Intent data = new Intent();
ArrayList<PickBean> cons = new ArrayList<PickBean>();
for (int i = 0; i < conData.size(); i++) {
cons.add(new PickBean(conData.get(i).displayName, conData.get(i).displayNumber));
}
}
data.putParcelableArrayListExtra("data", cons);
setResult(RESULT_OK, data);
finish();
The PickBean code:
public class PickBean implements Parcelable {
public String displayName;
public String displayNumber;
public boolean selected = false;
public PickBean() {
super();
}
public PickBean(String displayName, String displayNumber) {
super();
this.displayName = displayName;
this.displayNumber = displayNumber;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(displayName);
dest.writeString(displayNumber);
}
public final Parcelable.Creator<PickBean> CREATOR = new Parcelable.Creator<PickBean>() {
#Override
public PickBean createFromParcel(Parcel source) {
return new PickBean(source.readString(), source.readString());
}
#Override
public PickBean[] newArray(int size) {
return new PickBean[size];
}
};
}
It will always throws
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=20,
result=-1, data=Intent { (has extras) }} to activity
{com.chishacai.smscenter/com.chishacai.smscenter.SendActivity}: java.lang.NullPointerException: expected receiver of type
com.chishacai.smscenter.bean.PickBean, but got null
Caused by: java.lang.NullPointerException: expected receiver of type
com.chishacai.smscenter.bean.PickBean, but got null
Please help me how to deal with this problem, thanks.
Pass the data :
Intent intent = new Intent(SendActivity.this, PickContactsActivity.class);
Bundle bundle;
bundle.putParcelableArrayList("data", cons); // Be sure con is not null here
intent.putExtras(bundle);
Get the data :
ArrayList<PickBean> arrayParents = intent.getParcelableArrayListExtra("data");
Replace you method newArray with :
public final Parcelable.Creator<PickBean> CREATOR = new Parcelable.Creator<PickBean>() {
#Override
public PickBean createFromParcel(Parcel source) {
return new PickBean(source);
}
#Override
public PickBean[] newArray(int size) {
return new PickBean[size];
}
};
public PickBean(Parcel data) {
this.displayName = data.readString();
this.displayNumber = data.readString();
}
//DataModel Class
package com.DEECOUP.DataModel;
import android.os.Parcel;
import android.os.Parcelable;
public class OrderedData implements Parcelable {
private String _title, _subtitle, _person_type, _processed_name;
private Integer _price, _quantity;
public OrderedData(String title, String subtitle , String person_type, String processed_name,
Integer price, Integer quantity)
{
_title = title;
_subtitle =subtitle ;
_person_type = person_type;
_processed_name = processed_name;
_price = price;
_quantity = quantity;
}
public OrderedData(Parcel in) {
// TODO Auto-generated constructor stub
String[] data = new String[6];
in.readStringArray(data);
_title = data[0];
_subtitle = data[1];
_person_type= data[2];
_processed_name = data[3];
_price = Integer.parseInt(data[4]);
_quantity = Integer.parseInt(data[5]);
}
public String getTitle()
{
return _title;
}
public String getSubTitle()
{
return _subtitle;
}
public String getPersonType()
{
return _person_type;
}
public String getProcessedName()
{
return _processed_name;
}
public Integer getPrice()
{
return _price;
}
public Integer getQuantity()
{
return _quantity;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {
this._title,
this._subtitle,
this._person_type,
this._processed_name,
String.valueOf(this._price),
String.valueOf(this._quantity)
});
}
public static final Parcelable.Creator<OrderedData> CREATOR = new Parcelable.Creator<OrderedData>() {
public OrderedData createFromParcel(Parcel in) {
return new OrderedData(in);
}
public OrderedData[] newArray(int size) {
return new OrderedData[size];
}
};
}
//button click to send data on second activity
case R.id.btnOrderDetails:
Intent intent = new Intent(SenderActiviry.this,
RecieverActivity.class);
intent.putParcelableArrayListExtra("data", orderedDataList);
startActivity(intent);
break;
// Add data to datamodel from first addtivity
global list
ArrayList<OrderedData> orderedDataList = new ArrayList<OrderedData>();
and in on create
orderedDataList.add(new OrderedData(_title, _subTitle,_person_Type, _processName,_pRice,getFinalQuantity));

Categories

Resources