I wrote a code to draw a path from gpx file. If the user turns the smartphone, the path is cleared, then I created a ArrayList<MyLatLng> where every MyLatLng object is:
public class MyLatLng implements Parcelable {
private double latitude;
private double longitude;
public MyLatLng(double lat, double lon) {
latitude = lat;
longitude = lon;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int arg) {
parcel.writeDouble(latitude);
parcel.writeDouble(longitude);
}
public static final Parcelable.Creator<MyLatLng> CREATOR = new Creator<MyLatLng>() {
#Override
public MyLatLng createFromParcel(Parcel parcel) {
double latitude = parcel.readDouble();
double longitude = parcel.readInt();
return new MyLatLng(latitude, longitude);
}
#Override
public MyLatLng[] newArray(int size) {
return new MyLatLng[size];
}
};
//Metodi get/set
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}
And using onSaveInstanceState I avoid the cancellation of the path. But this method introduces a non-elegance in my code because every time I need to create a LatLng object from MyLatLng object. Do you have any advice about this? Thanks a lot :)
Related
I tried to save this object using Realm But I got this error
Error:(24, 9) error: Type
java.util.ArrayList of field
savedPath is not supported
Here is my code :
public class TrackingInfo extends RealmObject {
private int order_id;
private double savedDistance;
private double savedDuration;
private ArrayList <LatLng>savedPath;
public int getOrder_id() {
return order_id;
}
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
public double getSavedDistance() {
return savedDistance;
}
public void setSavedDistance(double savedDistance) {
this.savedDistance = savedDistance;
}
public double getSavedDuration() {
return savedDuration;
}
public void setSavedDuration(double savedDuration) {
this.savedDuration = savedDuration;
}
public ArrayList<LatLng> getSavedPath() {
return savedPath;
}
public void setSavedPath(ArrayList<LatLng> savedPath) {
this.savedPath = savedPath;
}
public TrackingInfo(){}}
Thanx in advance
Both List and LatLng cannot be stored in Realm directly. You will need to create a model object for LatLng and then use a RealmList object containing your model objects.
public class Location extends RealmObject {
public Location() { }
double latitude;
double longitude;
}
RealmList<Location> savedPath = new RealmList<Location>();
//Add location objects to savedPath and store it in your TrackingInfo object
You will need to manually convert objects of the LatLng class to the Location class when you are inserting/retrieving from the database.
I have a Linked List in one activity (A) that I want to share with another Activity (B).
The list contains a username of type string and contains coordinates of type LatLng. I am also using Intent and bundle to share data between activities. I tried using Parcelable but unable to figure out how to use it. Here is the code I have:
data.java
public class data implements Parcelable{
private LatLng coordinates;
private String name;
public data() {
name = null;
coordinates = null;
}
public data(String name, LatLng coordinates)
{
this.name = name;
this.coordinates = coordinates;
}
public data(Parcel in) {
coordinates = in.readParcelable(LatLng.class.getClassLoader());
name = in.readString();
}
public static final Creator<data> CREATOR = new Creator<data>() {
#Override
public data createFromParcel(Parcel in) {
return new data(in);
}
#Override
public data[] newArray(int size) {
return new data[size];
}
};
public LatLng getLatLng () {
return coordinates;
}
#Override
public int describeContents() {
return hashCode();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeParcelable(coordinates, flags);
}
}
Activity A
public class A extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
GoogleMap.OnMyLocationButtonClickListener,
ActivityCompat.OnRequestPermissionsResultCallback {
Button switchToSeek;
double mLatitude;
double mLongitude;
LinkedList<data> storedData = new LinkedList<>();
protected void onCreate(Bundle savedInstanceState) {
...
switchToSeek.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getCurrentLocation();
Intent intent = new Intent(A.this, B.class);
Bundle xy = new Bundle();
xy.putDouble("x", mLatitude);
xy.putDouble("y", mLongitude);
xy.putParcelable("list", storedData); <---------- error: wrong second arugment
intent.putExtra("xy", xy);
A.this.startActivity(intent);
}
});
Activity B
public class B extends FragmentActivity implements OnMapReadyCallback {
double mLatitude;
double mLongitude;
LatLng current;
GoogleMap gMap;
LinkedList <data> copyData = new LinkedList<>();
#Override
public void onMapReady(GoogleMap googleMap) {
gMap = googleMap;
...
Intent intent = getIntent();
Bundle xy = intent.getBundleExtra("xy");
if (xy != null) {
mLatitude = xy.getDouble("x");
mLongitude = xy.getDouble("y");
}
/***** Call linked list here and set equal to copyData *****/
current = new LatLng(mLatitude, mLongitude);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(current, 18.0f));
}
There is no easy way to do that, since LinkedList does not implement serializable or parcelable.
You CAN implement your own linked list class and make it a serializable/parcelable object which can then be passed.
Or you can convert its content into another data type such as an array and then recreate the linkedlist.* THIS IS HIGHLY INEFFICIENT
I believe there are other ways but this is a standard problem in android dev. Maybe try using fragments if possible and passing the linkedlist through a setter()
If the list is not huge, you can do it using the following helper class:
public class ParcelableLinkedList<E extends Parcelable> implements Parcelable {
private final LinkedList<E> linkedList;
public final Creator<ParcelableLinkedList> CREATOR = new Creator<ParcelableLinkedList>() {
#Override
public ParcelableLinkedList createFromParcel(Parcel in) {
return new ParcelableLinkedList(in);
}
#Override
public ParcelableLinkedList[] newArray(int size) {
return new ParcelableLinkedList[size];
}
};
public ParcelableLinkedList(Parcel in) {
// Read size of list
int size = in.readInt();
// Read the list
linkedList = new LinkedList<E>();
for (int i = 0; i < size; i++) {
linkedList.add((E)in.readParcelable(ParcelableLinkedList.class.getClassLoader()));
}
}
public ParcelableLinkedList(LinkedList<E> linkedList) {
this.linkedList = linkedList;
}
LinkedList<E> getLinkedList() {
return linkedList;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
// Write size of the list
parcel.writeInt(linkedList.size());
// Write the list
for (E entry : linkedList) {
parcel.writeParcelable(entry, flags);
}
}
}
In your onClick() method, add the data to the Bundle like this:
xy.putParcelable("list", new ParcelableLinkedList<data>(storedData));
To extract the data from the Bundle, do this:
copyData = ((ParcelableLinkedList<data>)xy.getParcelable("list")).getLinkedList();
I haven't actually compiled and tested this code, but it should work.
If the list is really huge, you are better off storing it in a static member variable in one class and then just referencing it from the other. This isn't normally the way you want to do things in Android, but it is sometimes more expedient to do this than to serialize and deserialize a huge amount of data just to pass it between 2 activities that have access to the same memory space.
I am trying to get the onPostExecute() method invoked after finishing the doInBackground() method and then passed the custom arrayList<ItemDTO> to the Map activity but onPostExecute method is not being invoked. I am not getting any Output in the Logcat as asign that it was invoked. How can I fix it?
I have debugged it and I can see the data in the ArrayList data object.
I appreciate any help.
GetLLRD class
public class GetLLRD {
Context mContext;
public void post_selected(String json, Context context) {
new MyAsyncTask().execute(json);
context = this.mContext;
}
class MyAsyncTask extends AsyncTask<String, Integer, List<ItemDTO>> {
#Override
protected List<ItemDTO> doInBackground(String... params) {
.
.
.
.
Gson gson = new Gson();
Type listType = new TypeToken<List<ItemDTO>>() {
}.getType();
ArrayList<ItemDTO> data = gson.fromJson(sb.toString(), listType);
.
.
.
.
return data;
}
protected void onPostExecute(ArrayList<ItemDTO> result) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
new MyAsyncTask().execute();
System.out.println("The method onPostExcute() in GETLLRD class was invoked again");
}
}, 1*30 * 1000);
if (result != null) {
Intent intent = new Intent(mContext, Map.class);
intent.putExtra("list",result);
mContext.startActivity(intent);
}else{
Log.e("123", "Avoiding null pointer, the dat is null in the GETLLRD class!!!");
}
}
}
}
MapDataJSON class with the inner class ItemDTo which I need to get the data from the JSON string that I am getting from the Server.
public class MapDataJSON {
ArrayList<ItemDTO> items;
public MapDataJSON(ArrayList<ItemDTO> items) {
super();
this.items = items;
}
public ArrayList<ItemDTO> getItems() {
return items;
}
public void setItems(ArrayList<ItemDTO> items) {
this.items = items;
}
public static class ItemDTO implements Serializable {
private static final long serialVersionUID = 1L;
double latitude;
double longitude;
int route;
String direction;
public ItemDTO(double latitude, double longitude, int route,
String direction) {
super();
this.latitude = latitude;
this.longitude = longitude;
this.route = route;
this.direction = direction;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public int getRoute() {
return route;
}
public String getDirection() {
return direction;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public void setRoute(int route) {
this.route = route;
}
public void setDirection(String direction) {
this.direction = direction;
}
}
}
Your not actually overriding the correct method signature of AsyncTask
it should be
protected void onPostExecute(List<ItemDTO> result)
by specifying ArrayList you're changing the method signature. This is why it's useful to use the Override annotation as your ide or compiler will tell you the method signature doesn't match.
What Im trying to achieve is display points on a map using postcode. I found a script that does this for one postcode, but I would like to display a few at once. So I was thinking of changing the code around a little so the map was created in the first class.
My question is, how do I transfer the values of Class B to Class A?
2 values 'lng' and 'lat' need to be an array
My full code is here if that makes more sense http://pastebin.com/L6tcuPW9
Any help would be great
Class A extents FragmentActivity
{
}
This class gets retrieves the lng and lat values
Class B
{
public static double[] lat;
public static double[] lng;
public void retrievePost( String post)
{
// does a search and retrieves lng and lat
setLat(lat);
setLng(lng);
}
public static void setLat(double lat2)
{
// How do I get this value back into Class A
}
public static void setLng(double lng2)
{
// How do I get this value back into Class A
}
}
Try this:
public interface MyInterface {
public void setLat(double lat);
public void setLng(double lng);
}
class A extends FragmentActivity implements MyInterface{
#Overwrite
public void setLat(double lat) {
//Do Something
}
#Overwrite
public void setLng(double lng){
//Do Something
}
}
Class B
{
private MyInterface interface;
public B(MyInterface interface){
this.interface = interface;
}
public void retrievePost( String post){
interface.setLat(lat);
interface.setLng(lng);
}
}
I have an ArrayList of type GeoPoint.
private List<GeoPoint> points = new ArrayList<GeoPoint>();
I want to pass points to another Activity and retrive the data in that activity. How do I do it? I know I have to use the parcelable but I searched, but could not find a way to pass ArrayLists.
This function will help you: http://developer.android.com/reference/android/content/Intent.html#putParcelableArrayListExtra(java.lang.String, java.util.ArrayList<? extends android.os.Parcelable>)
But the problem is, that GeoPoint is not Parcelable. Well, you can do a workaround here:
1) Create a class, that implements Parcelable:
public class ParcelableGeoPoint implements Parcelable {
private GeoPoint geoPoint;
public ParcelableGeoPoint(GeoPoint point) {
geoPoint = point;
}
public GeoPoint getGeoPoint() {
return geoPoint;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(geoPoint.getLatitudeE6());
out.writeInt(geoPoint.getLongitudeE6());
}
public static final Parcelable.Creator<ParcelableGeoPoint> CREATOR
= new Parcelable.Creator<ParcelableGeoPoint>() {
public ParcelableGeoPoint createFromParcel(Parcel in) {
return new ParcelableGeoPoint(in);
}
public ParcelableGeoPoint[] newArray(int size) {
return new ParcelableGeoPoint[size];
}
};
private ParcelableGeoPoint(Parcel in) {
int lat = in.readInt();
int lon = in.readInt();
geoPoint = new GeoPoint(lat, lon);
}
}
2) when sending to the other activity (points is your List<GeoPoint>:
ArrayList<ParcelableGeoPoint> pointsExtra = new ArrayList<ParcelableGeoPoint>();
foreach(GeoPoint point: points) {
pointsExtra.add(new ParcelableGeoPoint(point));
}
intent.putExtra("geopoints", pointsExtra);
3) in the called activity:
ArrayList<ParcelableGeoPoint> pointsExtra = getIntent().getParcelableArrayListExtra("geopoints");
ArrayList<GeoPoint> points = new ArrayList<GeoPoint>();
foreach(ParcelableGeoPoint point: pointsExtra) {
points.add(point.getGeoPoint());
}
code should work, but is untested.