How to pass a Parcelable Extra to another activity - android

I'm trying to pass a Parceble Extra to another activity using this example, but when I try get it on my second activity NullPointerExeception shows up, could somebody help me?
My Parcelable class:
public class MetaDados implements Parcelable {
private int codigoInstituicao;
// . . .
public MetaDados(int codigoInstituicao, int ano, String offlineUuid, String sigla, String nameInst,
String startedDate, String name, String finishedDate, long size) {
this.codigoInstituicao = codigoInstituicao;
// . . .
}
public int getCodigoInstituicao() {
return codigoInstituicao;
}
public void setCodigoInstituicao(int codigoInstituicao) {
this.codigoInstituicao = codigoInstituicao;
}
//getters and setters . . .
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(codigoInstituicao);
// . . .
}
public static final Parcelable.Creator<MetaDados> CREATOR = new Parcelable.Creator<MetaDados>() {
public MetaDados createFromParcel(Parcel in) {
return new MetaDados(in);
}
public MetaDados[] newArray(int size) {
return new MetaDados[size];
}
};
private MetaDados(Parcel in) {
codigoInstituicao = in.readInt();
//. . .
}
}
My AsynkTask how start my other activity:
ArrayList<MetaDados> metaDadosFull = new ArrayList<MetaDados>();
ArrayList<MetaDados> metaDadosPres = new ArrayList<MetaDados>();
Intent it = new Intent(activity, DownloadSelectionActivity.class);
it.putExtra("metaDadosFull", metaDadosFull);
it.putExtra("metaDadosPres", metaDadosPres);
activity.startActivity(it);
And my DownloadSelectionActivity where I try to get it:
ArrayList<MetaDados> fullList = (ArrayList<MetaDados>) getIntent().getParcelableExtra("metaDadosFull");
for (MetaDados metaDados : fullList) {
Log.d(Constants.DOWNLOAD_SELECTED_ACTIVITY, metaDados.getName());
}
ArrayList<MetaDados> presList = (ArrayList<MetaDados>) getIntent().getParcelableExtra("metaDadosPres");
for (MetaDados metaDados : presList) {
Log.d(Constants.DOWNLOAD_SELECTED_ACTIVITY, metaDados.getName());
}

Use Intent.putParcelableArrayListExtra() instead of putExtra(), and getParcelableArrayListExtra() instead of getParcelableExtra(). You can lose the casts as well, that may be where it's blowing up.

Related

How use object in multiple classes?

Im fighting with this some time and still don't know how to make it work. So i have class Player with constructor
Player(String playerName, double playerCash)
{
this.playerName = playerName;
this.playerCash = playerCash;
}
In MainActivity i make a player object
Player player = new Player("player", 100);
And now in TextView in SecondActivity i would like to use
playerCash = (TextView) findViewById(R.id.playerCash);
playerCash.setText(player.getPlayerCash());
Can someone explain me how i can make it works? I get cannot resolve symbol player. Thanks in advance
You can implement Parcelable interface for Player class and then pass instance of it from the MainActivity through Intent to the SecondActivity.
I am unsure if what you have posted is your entire class, or if you obviated a part of it. I will write this answer, assuming that is your entire class.
So, here is the deal: you need to create methods in your class for you to get and set data to/from it.
public class Player() implements Parcelable {
private String playerName;
private String playerCash;
public Player(String playerName, String playerCash) {
this.playerName = playerName;
this.playerCash = playerCash;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerCash() {
return playerCash;
}
public void setPlayerCash(String playerCash) {
this.playerCash = playerCash;
}
public Player(Parcel in) {
String[] data = new String[2];
in.readStringArray(data);
this.playerData = data[0];
this.playerCash = data[1];
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {this.playerName,
this.playerCash});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Player createFromParcel(Parcel in) {
return new Player(in);
}
public Player[] newArray(int size) {
return new Player[size];
}
};
}
edit
I didn't read the part where you say you want to share it between Activities. I only noticed it because someone mentioned implementing Parcelable, which does help your problem.
Anyway, I edited my code to implement it.
To share data between Activities you will also need an intent, and there you can share the data stored on your Player class:
Intent i = new Intent();
i.putExtra("player", new Player("Jhon", "Over 9000!");
And in your 2nd Activity, to get it you would do:
Bundle b = getIntent().getExtras();
Player player = b.getParcelable("player");
Hope that helps.

How to make nested ArrayLists parcelable

To pass an arrayList of objects to a fragment, I have to make the list objects parcelable.
public mObjectClass implements Parcelable {
// Some code
}
The problem is that one of the attributes in my list objects is another object-based arrayList.
public mObjectClass implements Parcelable {
// Some code
private ArrayList<someOtherObject> anotherArrayList;
}
How can I make mObjectClass parcelable?
someOtherObject has to implement Parcelable (not extend has in your question) too. Then you can call parcel.writeTypedList(anotherArrayList); to write it and parcel.readTypedList(yourList, someOtherObject.CREATOR) to read it back. You can read more here
This solution is heavily influenced by some Stackoverflow posts, including
this.
Essentially make both Classes parcelable and make use of someOtherClasses Parcelable.Creator.
mObjectClass:
public class mObjectClass implements Parcelable {
private ArrayList<someOtherObject> anotherArrayList;
//add getter + setter...
public mObjectClass() {
anotherArrayList = new ArrayList<someOtherObject>();
}
public mObjectClass(Parcel in) {
anotherArrayList = new ArrayList<someOtherObject>();
in.readTypedList(anotherArrayList, someOtherObject.CREATOR);
}
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeTypedList(anotherArrayList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public mObjectClass createFromParcel(Parcel in) {
return new mObjectClass(in);
}
#Override
public mObjectClass[] newArray(int size) {
return new mObjectClass[size];
}
};
}
someOtherObject:
public class someOtherObject implements Parcelable {
String someString;
//add getter + setter...
public void writeToParcel(Parcel out, int flags) {
out.writeString(someString);
}
public static final Parcelable.Creator<someOtherObject> CREATOR = new Parcelable.Creator<someOtherObject>() {
public someOtherObject createFromParcel(Parcel in) {
return new someOtherObject(in);
}
public someOtherObject[] newArray(int size) {
return new someOtherObject[size];
}
};
public int describeContents() {
return 0;
}
public someOtherObject(Parcel in) {
someString = in.readString();
}
public someOtherObject() {
}
public someOtherObject(String someString) {
this.someString = someString;
}
}
Tada, you are now able to add mObjectClass as extra to your intents after initialising it and using a setter to set the Arraylist with other someOtherObjects.

Android | java.lang.RuntimeException: Parcel android.os.Parcel#1219dd0f: Unmarshalling unknown type code 6881396 at offset 660

Please help me how to solve this issue ?
Parcelable interface i was implemented in customer pojo object. please help me how to read customer object in activity 2 ?
Customer.java
public Customer implements Parcelable{
private String name;
private String phone;
private List<AccountDetails> accoutDetails;
/getter and setters
public int describeContents() {
return 0;
}
public Customer(Parcel in) {
name= in.readString();
phone= in.readString();
accoutDetails= new ArrayList<AccountDetails>();
in.readList(accoutDetails,null);
}
public static final Parcelable.Creator<Customer> CREATOR = new Parcelable.Creator<Customer>() {
public Customer createFromParcel(Parcel in) {
return new Customer(in);
}
public Customer[] newArray(int size) {
return new Customer[size];
}
};
#Override
public void writeToParcel(Parcel dest, int arg1) {
// TODO Auto-generated method stub
dest.writeString(this. name);
dest.writeString(this.phone);
dest.writeList(accoutDetails);
}
}
In activity 1 used below code:
Customer selected_row=(Customer) parent.getAdapter().getItem(position);
Intent intent = new Intent(getApplicationContext(), Activity2.class);
Bundle bundle = new Bundle();
bundle.putParcelable("selected_customer", selected_row);
intent.putExtras(bundle);
startActivity(intent);
Activity 2:
Customer cust_object = getBundle.getParcelable("selected_customer");
Please find the below exception:
java.lang.RuntimeException: Parcel android.os.Parcel#1219dd0f: Unmarshalling unknown type code 6881396 at offset 660
at android.os.Parcel.readValue(Parcel.java:2228)
at android.os.Parcel.readListInternal(Parcel.java:2526)
at android.os.Parcel.readList(Parcel.java:1661)
Please help me how to read customer object in activity 2 ?
Serialization, although supported, is not recommended for Android. See for example this post.
I think that your issue is on this line of code:
in.readList(accoutDetails,null);
Since accountDetails is a List of custom AccountDetails objects you need AccountDetails to also implement Parcelable.
Do that, and then change the above line of code to:
in.readTypedList(accoutDetails, AccountDetails.CREATOR);
EDIT 1
Also, change:
public Customer(Parcel in) {
name= in.readString();
phone= in.readString();
accoutDetails= new ArrayList<AccountDetails>();
in.readTypedList(accoutDetails,null);
}
to:
public Customer(Parcel in) {
name= in.readString();
phone= in.readString();
in.readTypedList(accoutDetails, AccountDetails.CREATOR);
}
And change:
#Override
public void writeToParcel(Parcel dest, int arg1) {
// TODO Auto-generated method stub
dest.writeString(this. name);
dest.writeString(this.phone);
dest.writeList(accoutDetails);
}
To:
#Override
public void writeToParcel(Parcel dest, int arg1) {
dest.writeString(this.name);
dest.writeString(this.phone);
dest.writeTypedList(accoutDetails);
}
EDIT 2
public Customer implements Parcelable{
private String name;
private String phone;
private List<AccountDetails> accoutDetails = new ArrayList<AccountDetails>();

EXTRA with parcelable comes out NULL but without its fine

I am getting a bit frustrated with an issue that I cannot seem to fully understand.
I have a listview with items and when I click them I want to pass an object (Parcelable) to a new activity. This is the code below:
lv_Entries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent getItchesScreen = new Intent(Home.this, Itches.class);
getItchesScreen.putExtra("i", 3);
Entry e = entries.get(position);
getItchesScreen.putExtra("entry", e);
startActivity(getItchesScreen);
}
});
Now, I have the "i" extra there for debugging purposes. I was just sending "entry" and when I got the intent on the activity it didn't work. Code below:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_itches);
tv_date = (TextView) findViewById(R.id.tv_date);
Bundle b = getIntent().getExtras();
entry = b.getParcelable("entry");
tv_date.setText(entry.getDate());
itches = entry.getItches();
itchesAdapter = new ItchAdapter(this, itches);
ListView lv_Itches = (ListView) findViewById(R.id.lv_itches);
lv_Itches.setAdapter(itchesAdapter);
}
So when I read my bundle there is nothing at all. No "entry" key and no "i" key (I debugged to read i using watch feature)
BUT! If I don't send "entry" and only send "i" and I debug to catch "i" I do get it!
I have no idea why sending entry is ruining things but I cannot find any answer. I debugged the object and it does find it though .get(position).
Hope anyone can give me any ideas, and sorry for any trouble.
EDIT
Below is the code for Entry:
public class Entry implements Parcelable{
private String date;
private ArrayList<Itch> itches;
public Entry(String date){
this.date = date;
itches = new ArrayList<Itch>();
}
// PARCELABLE
public Entry(Parcel source){
date = source.readString();
source.readTypedList(itches, Itch.CREATOR);
}
public void AddItch(Itch itch){
itches.add(itch);
}
// get intensity average for the itches
public int IntensityAverage(){
int intensity = 0;
for(Itch i : itches){
intensity += i.getIntensity();
}
return intensity/itches.size();
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public ArrayList<Itch> getItches() {
return itches;
}
public void setItches(ArrayList<Itch> itches) {
this.itches = itches;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(date);
dest.writeTypedList(itches);
}
public static final Parcelable.Creator<Entry> CREATOR =
new Parcelable.Creator<Entry>() {
public Entry createFromParcel(Parcel source) {
return new Entry(source);
}
public Entry[] newArray(int size) {
return new Entry[size];
}
};
}
Itch class is also Parceable. I am populating correctly (no crashes on Android at least) the ListView with it.
For convenience I place the code here aswell:
public class Itch implements Parcelable{
private String time;
private String local;
private int intensity;
public Itch(String time, String local, int intensity){
this.time = time;
this.local = local;
this.intensity = intensity;
}
// PARCELABLE
public Itch(Parcel source){
time = source.readString();
local = source.readString();
intensity = source.readInt();
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getLocal() {
return local;
}
public void setLocal(String local) {
this.local = local;
}
public int getIntensity() {
return intensity;
}
public void setIntensity(int intensity) {
this.intensity = intensity;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(time);
dest.writeString(local);
dest.writeInt(intensity);
}
public static final Parcelable.Creator<Itch> CREATOR =
new Parcelable.Creator<Itch>() {
public Itch createFromParcel(Parcel source) {
return new Itch(source);
}
public Itch[] newArray(int size) {
return new Itch[size];
}
};
}
Alright so... What was the problem? Simple.
The reason why the parcelable always came out null was because a stupid error was occurring. Which error?
Well, okay so take a look at this piece of code:
entry = b.getParcelable("entry");
What is it saying? It is saying that entry will be equal to the parcelable "entry" key. But what does that really mean? Look at entry constructor.
// PARCELABLE
public Entry(Parcel source){
date = source.readString();
source.readTypedList(itches, Itch.CREATOR);
}
So when you say that entry is equals to a parcelable, then you will call this constructor in the Entry class that I have posted. But why is it wrong you might ask?
Well, so take a look. We're giving ArrayList itches to the method readTypeList. but... wait a second. If that is a constructor that means that we're building from 0... So... is itches initiated? No it is not! Because I was only initiating itches in the "normal" constructor!
public Entry(String date){
this.date = date;
itches = new ArrayList<Itch>();
}
So the solution is...
// PARCELABLE
public Entry(Parcel source){
date = source.readString();
//add this if condition!
if (itches == null) {
itches = new ArrayList<Itch>();
}
source.readTypedList(itches, Itch.CREATOR);
}
And thats it. That fixes our problem! :)
If other error occurs please be aware:
Make SURE that your key is correct. So check out for any typos in your getting extras.
entry = b.getParcelable("entyr");
as instead of
entry = b.getParcelable("entry");
And any other type of error like that.
That is not a good practive, you should have a variable that has the "entry" written on it so you never have this type of error mistakes. I have it in my code because I am fast-programming to build up a prototype :)
Happy coding!
have you tried doing this in onCreate()
Intent i = getIntent();
if(i.hasExtra("entry")){
entry = i.getParcelableExtra("entry");
}else{
Log.v("EXTRAS", "entry not found");
}

Passing ArrayLists in Android

I'm trying to pass array lists between activities in Android. The lists contains strings. I've read a lot about Parcelable. Would I need to create a Parcelable to pass a String array list? As of now I am using putStringArrayListExtra() and getSringArrayListExtra() to pass the lists through intents.
Here is some of my code.
Intent load = new Intent(getApplicationContext(), HelloTabWidget.class);
load.putStringArrayListExtra("albums", albums);
load.putStringArrayListExtra("songs", songs);
load.putStringArrayListExtra("artists", artists);
load.putStringArrayListExtra("fileName", fileName);
This is my onCreate method for the acticity which obtains the array list.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.songlist);
Bundle extras = getIntent().getExtras();
isArtists = extras.getBoolean("artists");
isAlbums = extras.getBoolean("albums");
isSongs = extras.getBoolean("songs");
Intent get = getIntent();
songs = get.getStringArrayListExtra("songs");
artists = get.getStringArrayListExtra("artists");
albums = get.getStringArrayListExtra("albums");
fileName = get.getStringArrayListExtra("fileName");
if(isArtists == true)
updateArtistsList();
else if(isAlbums == true)
updateAlbumsList();
else if(isSongs == true)
updateSongList();
}
The class which retrieves the list is supposed to create a listView from the data in the lists. Whenever I run the code i get nullPointerExceptions when trying to make the lists. I know that my listView code works, so I have narrowed down the problem to the intents which pass the array lists.
Thanks in advance.
EDIT:
Here are the first few lines from the logcat.
12-28 03:03:42.313: E/AndroidRuntime(873): FATAL EXCEPTION: main
12-28 03:03:42.313: E/AndroidRuntime(873): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.HelloTabWidget}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.MakeListActivity}: java.lang.NullPointerException
It depends on the type of arraylist
putIntegerArrayListExtra(String name, ArrayList<Integer> value)
putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)
putStringArrayListExtra(String name, ArrayList<String> value)
putCharSequenceArrayListExtra(String name, ArrayList<CharSequence> value)
Then you can read from you next activity by replacing put with get with key string as argument,eg
myIntent.getStringArrayListExtra("arrayListName");
Here is how you can pass an ArrayList :
MyListClass.java - Custom class
public class MyListClass implements Parcelable{
private int test;
public MyListClass()
{}
public MyListClass(Parcel read){
test = read.readInt();
}
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public static final Parcelable.Creator<MyListClass> CREATOR =
new Parcelable.Creator<MyListClass>() {
#Override
public MyListClass createFromParcel(Parcel source) {
return new MyListClass(source);
}
#Override
public MyListClass[] newArray(int size) {
return new MyListClass[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel arg0, int arg1) {
arg0.writeInt(test);
}
}
MyParcelable.java
public class MyParcelable implements Parcelable {
private List<MyListClass> arrList = new ArrayList<MyListClass>();
private int myInt = 0;
private String str = null;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public List<MyListClass> getArrList() {
return arrList;
}
public void setArrList(List<MyListClass> arrList) {
this.arrList = arrList;
}
public int getMyInt() {
return myInt;
}
public void setMyInt(int myInt) {
this.myInt = myInt;
}
MyParcelable() {
// initialization
arrList = new ArrayList<MyListClass>();
}
public MyParcelable(Parcel in) {
myInt = in.readInt();
str = in.readString();
in.readTypedList(arrList, MyListClass.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeInt(myInt);
outParcel.writeString(str);
outParcel.writeTypedList(arrList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
#Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
MainAcitivty.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arrList.add(new MyListClass());
arrList.get(0).setTest(200);
MyParcelable object = new MyParcelable();
object.setMyInt(100);
object.setArrList(arrList);
Intent intent = new Intent(MainActivity.this,ReceiverParcel.class);
intent.putExtra("parcel", object);
startActivity(intent);
}
ReceiverParcel.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
MyParcelable object = b.getParcelable("parcel");
System.out.println(object.getArrList().get(0).getTest());
System.out.println(object.getMyInt());
}

Categories

Resources