0

I'm creating an Android map app by getting venue from Foursquare and using Google Map.

I have set my MainActivity to get the venue results, a MapFragmentClass and a VenueModel.

I keep all the JSON result from Foursquare into a List venueModelList in the MainActivity.

What I want to do is to add markers in the MapFragmentClass based on the coordinates received from Foursquare.

However, I am stuck trying to pass the venueModelList to the MapFragmentClass.

Any help is appreciated. Thanks.

MainActivity.java

public class MainActivity extends AppCompatActivity implements LocationListener{
private final String VENUE_URL = "https://api.foursquare.com/v2/venues/search?ll=";

private final int LIMIT = 40;

private final double RADIUS = 50000;

private String MOSQUE_URL;
private String RES_URL;

public static final String CLIENT_ID = "";
public static final String CLIENT_SECRET = "";

private static final long MIN_TIME_BW_UPDATES = 20000;
private static final float MIN_DISTANCE_CHANGE_FOR_UPDATES = 1;
private LocationManager locationManager;
private Location lastLocation;
private Location location;
private boolean receivedLocation = false;
private double lt;
private double lg;
private boolean canGetLocation;
private boolean isGPSEnabled;
private boolean isNetworkEnabled;
private boolean updateSettings = false;
private String TAG = "TAG";
private ListView lvVenues;
private Bundle bundle;
private ArrayList<VenueModel> venueModelList;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lvVenues =  (ListView) findViewById(R.id.lvVenues);

    String t = timeMilisToString(System.currentTimeMillis());

    Bundle extras = getIntent().getExtras();
    if (extras != null)
    {
        lt = extras.getDouble("LATITUDE");
        lg = extras.getDouble("LONGITUDE");
        receivedLocation = true;
    }
    else
    {
        receivedLocation = false;
    }

    location = getLocation();
    if (location != null)
    {
        if(receivedLocation)
        {
            location.setLatitude(lt);
            location.setLongitude(lg);
        }
        else
        {
            lt = location.getLatitude();
            lg = location.getLongitude();
            Log.d("LAT", "Latitude: " + lt);
            Log.d("LONG", "Longitude: " + lg);
        }
    }

    double lt = 3.142182;
    double lg = 101.710602;

    MOSQUE_URL = VENUE_URL + lt + "," + lg
            + "&client_id=" + CLIENT_ID
            + "&client_secret=" + CLIENT_SECRET
            + "&v=" + t
            + "&categoryId=4bf58dd8d48988d138941735"
            + "&radius=" + RADIUS
            + "&limit=" + LIMIT;

    RES_URL = VENUE_URL + lt + "," + lg
            + "&client_id=" + CLIENT_ID
            + "&client_secret=" + CLIENT_SECRET
            + "&v=" + t
            + "&categoryId=52e81612bcbc57f1066b79ff"
            + "&radius=" + RADIUS
            + "&limit=" + LIMIT;
}

public class JSONTask extends AsyncTask<String, String, List<VenueModel>>
{
    @Override
    public List<VenueModel> doInBackground(String... params)
    {
        HttpURLConnection connection = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

            String finalJson = buffer.toString();

            JSONObject parentObject = new JSONObject(finalJson);
            JSONObject secondObject = parentObject.getJSONObject("response");
            JSONArray parentArray = secondObject.getJSONArray("venues");

            venueModelList = new ArrayList<>();

            for (int i = 0; i < parentArray.length(); i++)
            {
                JSONObject finalObject = parentArray.getJSONObject(i);
                JSONObject thirdObject = finalObject.getJSONObject("location");

                try {
                    VenueModel venueModel = new VenueModel();
                    venueModel.setId(finalObject.getString("id"));
                    venueModel.setName(finalObject.getString("name"));
                    venueModel.setAddress(thirdObject.optString("address"));
                    venueModel.setPostalCode(thirdObject.optString("postalCode"));
                    venueModel.setCity(thirdObject.optString("city"));
                    venueModel.setState(thirdObject.optString("state"));
                    venueModel.setDistance(thirdObject.getInt("distance"));
                    venueModel.setLat(thirdObject.getDouble("lat"));
                    venueModel.setLng(thirdObject.getDouble("lng"));
                    LatLng coordinate = new LatLng(thirdObject.getDouble("lat"), thirdObject.getDouble("lng"));
                    venueModel.setCoordinate(coordinate);

                    venueModelList.add(venueModel);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            Collections.sort(venueModelList);

            return venueModelList;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(List<VenueModel> result)
    {
        super.onPostExecute(result);
        VenueAdapter adapter = new VenueAdapter(getApplicationContext(), R.layout.row, result);
        lvVenues.setAdapter(adapter);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    int id = item.getItemId();

    if (id == R.id.action_mosque)
    {
        new JSONTask().execute(MOSQUE_URL);
        FragmentManager fmanager = getSupportFragmentManager();
        FragmentTransaction FT = fmanager.beginTransaction();
        MapFragmentClass mfc = new MapFragmentClass();
        FT.add(R.id.mapLayout, mfc);
        FT.commit();

        return true;
    }

    if (id == R.id.action_restaurant)
    {
        new JSONTask().execute(RES_URL);

        FragmentManager fmanager = getSupportFragmentManager();
        FragmentTransaction FT = fmanager.beginTransaction();
        MapFragmentClass mfc = new MapFragmentClass();
        FT.add(R.id.mapLayout, mfc);
        FT.commit();

        return true;
    }

    return super.onOptionsItemSelected(item);
}

private String timeMilisToString(long milis)
{
    SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(milis);
    return sd.format(calendar.getTime());
}

public Location getLocation()
{
    try
    {
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled)
        {
            Log.v(TAG, "No network provider enabled");
        }
        else
        {
            this.canGetLocation = true;
            if (isNetworkEnabled)
            {
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d(TAG, "Network Enabled");

                if(locationManager != null)
                {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                }
            }

            if (isGPSEnabled)
            {
                if (location == null)
                {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d(TAG, "GPS Enabled");

                    if(locationManager != null)
                    {
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return location;
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
public void onLocationChanged(Location location)
{
    lastLocation = location;
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider)
{
    Log.v(TAG, "onProviderEnabled");
}

@Override
public void onProviderDisabled(String provider)
{
    Log.v(TAG, "onProviderDisabled");
}

public LatLng setCoordinate()
{
    LatLng coordinate = new LatLng(getLocation().getLatitude(), getLocation().getLongitude());
    LatLng coordinate = new LatLng(lt, lg);
    return coordinate;
}
}

VenueModel.java

public class VenueModel implements Comparable<VenueModel>, Parcelable
{
private String id;
private String name;
private String address;
private String postalCode;
private String city;
private String state;
private Integer distance;
private double lat;
private double lng;
private LatLng coordinate;
private List<VenueModel> venueModelList;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public int getDistance() {
    return distance;
}

public void setDistance(int distance) {
        this.distance = distance;
}

public double getLat() {
    return lat;
}

public void setLat(double lat) {
    this.lat = lat;
}

public double getLng() {
    return lng;
}

public void setLng(double lng) {
    this.lng = lng;
}

public String getPostalCode() {
    return postalCode;
}

public void setPostalCode(String postalCode) {
    this.postalCode = postalCode;
}

public String getState() {
    return state;
}

public void setState(String state) {
    this.state = state;
}

public void setVenueModelList(List<VenueModel> venueModelList)
{
    this.venueModelList = venueModelList;
}

public List<VenueModel> getVenueModelList()
{
    return venueModelList;
}

public LatLng getCoordinate() {
    return coordinate;
}

public void setCoordinate(LatLng coordinate)
{
    this.coordinate = coordinate;
}

@Override
public int compareTo(VenueModel venueModel) {

    return this.distance.compareTo(venueModel.distance);
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.id);
    dest.writeString(this.name);
    dest.writeString(this.address);
    dest.writeString(this.postalCode);
    dest.writeString(this.city);
    dest.writeString(this.state);
    dest.writeValue(this.distance);
    dest.writeDouble(this.lat);
    dest.writeDouble(this.lng);
    dest.writeParcelable(this.coordinate, flags);
    dest.writeList(this.venueModelList);
}

public VenueModel() {
}

protected VenueModel(Parcel in) {
    this.id = in.readString();
    this.name = in.readString();
    this.address = in.readString();
    this.postalCode = in.readString();
    this.city = in.readString();
    this.state = in.readString();
    this.distance = (Integer) in.readValue(Integer.class.getClassLoader());
    this.lat = in.readDouble();
    this.lng = in.readDouble();
    this.coordinate = in.readParcelable(LatLng.class.getClassLoader());
    this.venueModelList = new ArrayList<VenueModel>();
    in.readList(this.venueModelList, VenueModel.class.getClassLoader());
}

public static final Parcelable.Creator<VenueModel> CREATOR = new Parcelable.Creator<VenueModel>() {
    @Override
    public VenueModel createFromParcel(Parcel source) {
        return new VenueModel(source);
    }

    @Override
    public VenueModel[] newArray(int size) {
        return new VenueModel[size];
    }
};
}

MapFragmentClass.java

public class MapFragmentClass extends Fragment implements OnMapReadyCallback
{
private MainActivity mA;
private GoogleMap gmap;
private static final LatLng coordinate = new LatLng(3.152182, 101.710602);
private LatLng coordinate2;
private ArrayList<VenueModel> venueModelList;


@Override
public void onAttach(Context context)
{
    super.onAttach(context);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View v = inflater.inflate(R.layout.activity_maps, container, false);
    SupportMapFragment supportMapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    supportMapFragment.getMapAsync(this);

    return v;
}

@Override
public void onMapReady(GoogleMap googleMap)
{
    gmap = googleMap;
    gmap.addMarker(new MarkerOptions().position(coordinate).title("Your location").draggable(true));
    gmap.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinate, 14));
}

}

Trancol
  • 227
  • 1
  • 4
  • 15

2 Answers2

1

Convert that Object to JSON string using GSON and then reconvert that string again to Object of list again.

MapFragment.getInstance(new Gson().toJson(venuList));

public static final getInstance(String venusStringListObj) {}
Bundle argument = new Bundle();
argument.putString("VENUES", venusStringListObj);
MapFragment fragment = new MapFragment();
fragment.setArgument(argument);
return fragment;
}

onCreate(...) {
    private List<VenueModel> venueList;
 Type listType = new TypeToken<ArrayList<VenueModel>>() {}.getType();
String venueStringRecvFromFragArg = getArguments().getString("VENUES");
            venueList = new Gson().fromJson(venueStringRecvFromFragArg, listType);
}
silentsudo
  • 6,730
  • 6
  • 39
  • 81
0
MapFragmentClass mfc = new MapFragmentClass();
Bundle b = new Bundle();
b.putParcelableArrayList("Parcel", list);
mfc.setArguments(b);
FT.add(R.id.mapLayout, mfc);
FT.commit();

To access arrayList in MapFragment use this

ArrayList<VenueModel> myList = getArguments().getParcelableArrayList("Parcel");
Haris Aftab
  • 259
  • 1
  • 9
  • I'm assuming "list" refers to venueModelList cast as an ArrayList? Also, how am I to get the bundle inside the MapFragmentClass? – Trancol Apr 18 '16 at 06:40
  • Yes this is same arrayList you created in MapActivity class. – Haris Aftab Apr 18 '16 at 06:41
  • You mean MainActivity, right? Because I have a MapActivity class but I did not post it here. Still, how am I to get the bundle in the MapFragmentClass? – Trancol Apr 18 '16 at 06:44
  • Yes it is `MainActivity` not `MapActivity`. Kindly see edited answer – Haris Aftab Apr 18 '16 at 06:45
  • I added the code you gave and I also add gmap.addMarker(new MarkerOptions().position(venueModelList.get(0).getCoordinate()).title("Venue")); but now I get a NullPointerException. – Trancol Apr 18 '16 at 06:50
  • @G.Masoncan you check my answer – silentsudo Apr 18 '16 at 06:53
  • Did you add code on both `R.id.action_mosque` and `R.id.action_restaurant` ? Also check `getArguments() != null` in MapFragment class. Please share code in comment for adding and accessing if it doesn't solve your problem. – Haris Aftab Apr 18 '16 at 06:54
  • @Haris Aftab getArguments doesn't return null so there's apparently value in it. What other code do you want me to share? I have already shared the important codes above. – Trancol Apr 18 '16 at 07:23
  • Did you add code on both `R.id.action_mosque` and `R.id.action_restaurant` ? Also make sure that key `"Parcel"` or whatever you use is same on both ends. Where exactly you are getting `NULL Pointer Exception` – Haris Aftab Apr 18 '16 at 07:26
  • I've added code on both item. Key is exactly the same. I'm getting NULL Pointer Exception on MapFragmentClass. Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference – Trancol Apr 18 '16 at 07:36
  • according to this your list is null – Haris Aftab Apr 18 '16 at 07:37
  • Is the error because of ArrayList? I'm getting confused between List and ArrayList. Initially, I used List but I did not know how to bundle List so I change parts of the code to ArrayList. – Trancol Apr 18 '16 at 07:41
  • It is because venueModelList has no data or where you are actually putting this arrayList that is null. List is interface and ArrayList is actual implmentation so it is better to use List as interface while declaring and use its implementation like you have done before. But it didnot make any impact in current situation on your application if you use only ArrayList – Haris Aftab Apr 18 '16 at 07:50