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 +
'}';
}
}
Related
I know it's a commonly asked question and I looked at the solutions online, but I am having a difficulty implementing this on my own.
I have a class which contains three variables: Location, Date and Uri.
I have an Arraylist which consists of multiple Arraylists that contains said class.
For instance:
ArrayList<ArrayList<class>>
I am trying to pass this onto another activity, yet unsuccessful.
I tried both Parcelable and Serializable but none worked.
Edit: Source code added.
Class documentation:
public class imageHolder implements Parcelable
{
private Uri uri;
private Date date;
private Location loc;
public imageHolder(Uri uriAdd, Date dateAdded,Location imgLoc)
{
this.uri = uriAdd;
this.date = dateAdded;
this.loc = imgLoc;
}
public static final Creator<imageHolder> CREATOR = new Creator<imageHolder>() {
#Override
public imageHolder createFromParcel(Parcel in) {
return new imageHolder(in);
}
#Override
public imageHolder[] newArray(int size) {
return new imageHolder[size];
}
};
public Uri getURI() { return this.uri; }
public Date getDate() {return this.date; }
public Location getLocation() {return this.loc; };
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeSerializable(date);
parcel.writeParcelable(uri,i);
parcel.writeParcelable(loc, i);
}
protected imageHolder(Parcel in) {
date = (java.util.Date) in.readSerializable();
uri = in.readParcelable(Uri.class.getClassLoader());
loc = in.readParcelable(Location.class.getClassLoader());
}
}
First activity:
ArrayList<ArrayList<imageHolder>> sepImages = new ArrayList<ArrayList<imageHolder>>();
sepImages = groupPics(images);
Intent nextActivity = new Intent(loadImages.this, storiesScreen.class);
nextActivity.putExtra("images",images);
startActivity(nextActivity);
finishActivity(0);
Second activity:
ArrayList<ArrayList<imageHolder>> sepImages =
(ArrayList<ArrayList<imageHolder>>) getIntent().getParcelableExtra("images");
Log.d("stories","test");
I think the best thing to do here would be to create a new class that implements Parcelable and pass instances of this new class between activities.
public class ParcelableListOfLists implements Parcelable {
private ArrayList<ArrayList<imageHolder>> listOfLists;
public ParcelableListOfLists(ArrayList<ArrayList<imageHolder>> listOfLists) {
this.listOfLists = listOfLists;
}
public ArrayList<ArrayList<imageHolder>> getListOfLists() {
return listOfLists;
}
// parcelable implementation here
}
Once you have this class, you can be in full control of how your data is parceled, and that lets you do some things that you won't be able to do with the Android built-in offerings.
Here's one way you could parcel a list of lists:
#Override
public void writeToParcel(Parcel dest, int flags) {
if (listOfLists != null) {
dest.writeInt(listOfLists.size());
for (ArrayList<imageHolder> list : listOfLists) {
dest.writeTypedList(list);
}
} else {
dest.writeInt(-1);
}
}
And on the other side, you can recreate the list of lists like this:
public ParcelableListOfLists(Parcel in) {
int size = in.readInt();
if (size != -1) {
this.listOfLists = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
ArrayList<imageHolder> list = in.createTypedArrayList(imageHolder.CREATOR);
listOfLists.add(list);
}
} else {
this.listOfLists = null;
}
}
With all of this together, you can pass your list of lists between activities like this:
Intent nextActivity = new Intent(loadImages.this, storiesScreen.class);
nextActivity.putExtra("images", new ParcelableListOfLists(images));
startActivity(nextActivity);
and retrieve them in the next activity like this:
ParcelableListOfLists plol = getIntent().getParcelableExtra("images");
ArrayList<ArrayList<imageHolder>> images = plol.getListOfLists();
I think that you can use Gson too.
In your build.gradle
implementation 'com.google.code.gson:gson:2.8.4'
In the first activity
Gson gson = new Gson();
String json = gson.toJson(yourObject);
intent.putExtra("yourKey", json);
In the second activity
Gson gson = new Gson();
YourObject yourObject = gson.fromJson(getIntent().getStringExtra("yourKey"), YourObject.class);
Easy and fast.
Ok.
Your Model
public class ImageHolder implements Serializable {
// Use String here, to avoid serialization problems
private String uri;
private Date date;
private Location loc;
public ImageHolder() {
}
public ImageHolder(String uri, Date date, Location loc) {
this.uri = uri;
this.date = date;
this.loc = loc;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Location getLoc() {
return loc;
}
public void setLoc(Location loc) {
this.loc = loc;
}
#Override
public String toString() {
return "ImageHolder{" +
"uri=" + uri +
", date=" + date +
", loc=" + loc +
'}';
}
}
Create a Container class
public class Container implements Serializable {
private ArrayList<ImageHolder> list;
public Container() {
}
public Container(ArrayList<ImageHolder> list) {
this.list = list;
}
public ArrayList<ImageHolder> getList() {
return list;
}
public void setList(ArrayList<ImageHolder> list) {
this.list = list;
}
#Override
public String toString() {
return "Container{" +
"list=" + list +
'}';
}
}
Your First Activity
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
ImageHolder imageHolder0 = new ImageHolder("http://www.stackoverflow.com", new Date(), new Location("test0"));
ImageHolder imageHolder1 = new ImageHolder("http://www.google.com", new Date(), new Location("test1"));
ArrayList<ImageHolder> list = new ArrayList<>();
list.add(imageHolder0);
list.add(imageHolder1);
Container container = new Container(list);
Gson gson = new Gson();
String json = gson.toJson(container);
Intent intent = new Intent(MainActivity.this, TestActivity.class);
intent.putExtra("yourKey", json);
startActivity(intent);
}
}
Your second activity
public class TestActivity extends AppCompatActivity {
public static final String TAG = TestActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Gson gson = new Gson();
Container container = gson.fromJson(getIntent().getStringExtra("yourKey"), Container.class);
Log.d(TAG, "OK?" + container.getList().toString());
// Here convert String uri Fields to Uri Objects
// Example:
Uri uri = Uri.parse(container.getList().get(0).getUri());
}
}
Logcat result: 08-01 11:10:22.097 6671-6671/it.darksurfer.english.template D/TestActivity: OK?[ImageHolder{uri=http://www.stackoverflow.com, date=Wed Aug 01 11:10:21 GMT+02:00 2018, loc=Location[test0 0,000000,0,000000 acc=??? t=?!? et=?!?]}, ImageHolder{uri=http://www.google.com, date=Wed Aug 01 11:10:21 GMT+02:00 2018, loc=Location[test1 0,000000,0,000000 acc=??? t=?!? et=?!?]}]
Obviously you can put an undefined number of others ArrayList in the list of Container class!
This code works but I do not pass the data contained in the arrayList.
public class Percorso implements Parcelable {
int id;
String nome;
double distanza;
int numero_commenti;
double valutazione;
ArrayList<Commento> commenti;
ArrayList<Cordinate> cordinate;
public Percorso(){
}
protected Percorso(Parcel in) {
id = in.readInt();
nome = in.readString();
distanza = in.readDouble();
numero_commenti = in.readInt();
valutazione = in.readDouble();
}
public static final Creator<Percorso> CREATOR = new Creator<Percorso>() {
#Override
public Percorso createFromParcel(Parcel in) {
return new Percorso(in);
}
#Override
public Percorso[] newArray(int size) {
return new Percorso[size];
}
};
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public double getDistanza() {
return distanza;
}
public void setDistanza(double distanza) {
this.distanza = distanza;
}
public int getNumero_commenti() {
return numero_commenti;
}
public void setNumero_commenti(int numero_commenti) {
this.numero_commenti = numero_commenti;
}
public double getValutazione() {
return valutazione;
}
public void setValutazione(double valutazione) {
this.valutazione = valutazione;
}
public ArrayList<Commento> getCommenti() {
return commenti;
}
public void setCommenti(ArrayList<Commento> commenti) {
this.commenti = commenti;
}
public ArrayList<Cordinate> getCordinate() {
return cordinate;
}
public void setCordinate(ArrayList<Cordinate> cordinate) {
this.cordinate = cordinate;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(nome);
parcel.writeDouble(distanza);
parcel.writeInt(numero_commenti);
parcel.writeDouble(valutazione);
}
}
//
public class Cordinate implements Parcelable {
double latitudine;
double longitudin;
public Cordinate(){}
protected Cordinate(Parcel in) {
latitudine = in.readDouble();
longitudin = in.readDouble();
}
public static final Creator<Cordinate> CREATOR = new Creator<Cordinate>() {
#Override
public Cordinate createFromParcel(Parcel in) {
return new Cordinate(in);
}
#Override
public Cordinate[] newArray(int size) {
return new Cordinate[size];
}
};
public double getLatitudine() {
return latitudine;
}
public void setLatitudine(double latitudine) {
this.latitudine = latitudine;
}
public double getLongitudin() {
return longitudin;
}
public void setLongitudin(double longitudin) {
this.longitudin = longitudin;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeDouble(latitudine);
parcel.writeDouble(longitudin);
}
}
INTENT
Percorso percorsoClick = listaPercorsi.get(i);
Intent intent = new Intent(getBaseContext(), PercorsoActivity.class);
intent.putExtra("percorso", percorsoClick);
startActivity(intent);
GET INTENT
percorso = getIntent().getParcelableExtra("percorso");
System.out.println(percorso.getNome());
getNome() work because is not a arrayList.
instead get getCordinate not work.
percorso.getCordinate().size() // null
I hope it was clear. I have set the Parcelable implementation on all classes.
Thank you very much for the help
ArrayList<Cordinate> cordinate; is not being parcelled. You still have to take care of write/read in/from Parcel parcel. Eg
protected Percorso(Parcel in) {
id = in.readInt();
nome = in.readString();
distanza = in.readDouble();
numero_commenti = in.readInt();
valutazione = in.readDouble();
cordinate = new ArrayList<Cordinate>();
in.readList(cordinate,Cordinate.class.getClassLoader());
}
and
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(nome);
parcel.writeDouble(distanza);
parcel.writeInt(numero_commenti);
parcel.writeDouble(valutazione);
parcel.writeList(cordinate);
}
It's one day work with no solution,
I would to passed data beetween activity, I implement Parcelable but from called activity I receive the ListFileMedia with a size=0.
When I mistake?
Class ListFileMedia (Extended of ArrayList)
public class ListFileMedia extends ArrayList<FileMedia> implements Parcelable{
public ListFileMedia(){.....}
// for test i have cancel all methods and var, sure i tested also with...
//Interface Parcelable
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
//dest.writeInt(countIntestazioni);
// Add inner class
dest.writeParcelable(this.add(FileMedia),flags);
}
public ListFileMedia(Parcel in) {
}
public final static Parcelable.Creator <ListFileMedia>CREATOR = new Creator<ListFileMedia>() {
#Override
public ListFileMedia createFromParcel(Parcel source) {
return new ListFileMedia(source);
}
#Override
public ListFileMedia[] newArray(int size) {
return new ListFileMedia[size];
}
};
}
Custom objects in FileListMedia
public class FileMedia implements Comparable,Parcelable{
public String getPath() {return path;}
public String getBucket() {
return bucket;
}
public String getMimeType() { return mimeType; }
private String path;
private String bucket;
private String mimeType;
private int giorno;
private int mese;
private int anno;
public FileMedia(int giorno,int mese,int anno, String path,String bucket,String mimeType){
....
}
public int compareTo(Object o) {
.....
}
//Interface Parcelable
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.path);
dest.writeString(this.bucket);
dest.writeString(this.mimeType);
dest.writeInt(this.giorno);
dest.writeInt(this.mese);
dest.writeInt(this.anno);
}
public FileMedia(Parcel in) {
this.path = in.readString();
this.bucket=in.readString();
this.mimeType=in.readString();
this.giorno=in.readInt();
this.mese=in.readInt();
this.anno=in.readInt();
}
public final static Parcelable.Creator <FileMedia>CREATOR = new Creator<FileMedia>() {
#Override
public FileMedia createFromParcel(Parcel source) {
return new FileMedia(source);
}
#Override
public FileMedia[] newArray(int size) {
return new FileMedia[size];
}
};}
Call activity
ListFileMedia test=new ListFileMedia();
ArrayList arrayList=new ArrayList();
test.add(new FileMedia(10,12,2016,"t","t","t"));
b.putParcelable("list",test);
intent.putExtras(b);
startActivity(intent);
Called activity
Intent intent = this.getIntent();
Bundle b=intent.getExtras();
ListFileMedia listFileMedia (ListFileMedia)b.getParcelable("list"); //size==0 !!!
But if i passed only b.putParcelable("list",new FileMedia(10,12,2016,"t","t","t") work correctely!!
Sorry for my English..
This question already has answers here:
How to pass ArrayList<CustomeObject> from one activity to another? [duplicate]
(3 answers)
Closed 7 years ago.
I try pass an object to new activity but I have a problem. My ArrayList use another class in this way:
ArrayList<ListData> myList = new ArrayList<>();
All is great, I'm adding to mList a few objects and my listview work fine.
I try pass an object after click in this way:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
ListData listdata = myList.get(position);
ListData dataToSend = new ListData();
dataToSend.setStrefa(listdata.getStrefa());
dataToSend.setDzielnica(listdata.getDzielnica());
dataToSend.setAdres(listdata.getAdres());
dataToSend.setKryteria(listdata.getKryteria());
dataToSend.setTelefon(listdata.getTelefon());
dataToSend.setData(listdata.getData());
Intent intent = new Intent(Zlecenia.this, Zlecenie.class);
intent.putExtra("myData", dataToSend);
startActivity(intent);
overridePendingTransition(R.anim.fade_in, R.anim.no_animation);
}
});
Here is a problem because "bundle.putParcelableArrayList("listdata", listdata);" is marked on red. This forces on me using extends Parcelable in ListData Class but when I added this extends then my ArrayList is empty. What schould I do?
My ListData:
public class ListData implements Parcelable{
String Strefa;
String Adres;
String Kryteria;
String Telefon;
String Data;
String Dzielnica;
String Ilosc;
/* Zlecenia */
public String getStrefa() {
return Strefa;
}
public void setStrefa(String strefa) {
this.Strefa = strefa;
}
public String getAdres() {
return Adres;
}
public void setAdres(String adres) {
this.Adres = adres;
}
public String getKryteria() {
return Kryteria;
}
public void setKryteria(String kryteria) {
this.Kryteria = kryteria;
}
public String getTelefon() {
return Telefon;
}
public void setTelefon(String telefon) {
this.Telefon = telefon;
}
public String getData() {
return Data;
}
public void setData(String data) {
this.Data = data;
}
/* Statystyki */
public String getDzielnica() {
return Dzielnica;
}
public void setDzielnica(String dzielnica) {
this.Dzielnica = dzielnica;
}
public String getIlosc() {
return Ilosc;
}
public void setIlosc(String ilosc) {
this.Ilosc = ilosc;
}
public ListData() {
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Strefa);
dest.writeString(Dzielnica);
dest.writeString(Adres);
dest.writeString(Kryteria);
dest.writeString(Telefon);
dest.writeString(Data);
}
private ListData(Parcel in) {
Strefa = in.readString();
Dzielnica = in.readString();
Adres = in.readString();
Kryteria = in.readString();
Telefon = in.readString();
Data = in.readString();
}
public static final Parcelable.Creator<ListData> CREATOR
= new Parcelable.Creator<ListData>() {
#Override
public ListData createFromParcel(Parcel in) {
return new ListData(in);
}
#Override
public ListData[] newArray(int size) {
return new ListData[size];
}
};
}
Try this in your class
public class ListData implements Serializable
I have a problems getting parameters using parcelables. When I call getIntent().getExtras().getParcelable("map"); I have a problem because of a problem with a Vector.
I have 2 parcelable classes:
public class Point implements Parcelable{
private double x;
private double y;
private double z;
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public Point(Parcel in ) {
readFromParcel( in );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Point createFromParcel(Parcel in ) {
return new Point( in );
}
public Point[] newArray(int size) {
return new Point[size];
}
};
public void readFromParcel(Parcel in){
x = in.readDouble();
y = in.readDouble();
z = in.readDouble();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeDouble(x);
dest.writeDouble(y);
dest.writeDouble(z);
}
}
And Map:
public class Map implements Parcelable{
private Point start;
private Point finish;
private java.util.Vector <Point> travel;
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public Map(Parcel in ) {
readFromParcel( in );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Map createFromParcel(Parcel in ) {
return new Map( in );
}
public Map[] newArray(int size) {
return new Map[size];
}
};
public void readFromParcel(Parcel in){
start = in.readParcelable(Point.class.getClassLoader());
finish = in.readParcelable(Point.class.getClassLoader());
Point[] travel = (Point[]) in.readParcelableArray(Point.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(start, flags);
dest.writeParcelable(finish, flags);
dest.writeParcelableArray(travel.toArray(new Point[travel.size()]), flags);
}
}
Then, how can I receive travel? I always have problems in readParcelableArray.
Someone could help me please??
When is almost impossible to find a solution often the problem is the base of this solution.
In my case, the solution consists in using a List instead of a Vector.
Then, in the class Map, I changed the methods readFromParceo and writeToParcel like these:
public void readFromParcel(Parcel in){
start = in.readParcelable(Point.class.getClassLoader());
finish = in.readParcelable(Point.class.getClassLoader());
travel = in.readArrayList(Point.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(start, flags);
dest.writeParcelable(finish, flags);
dest.writeList(travel);
}
I hope it'll help somebody in the future.