Android Realm Google Maps Memory Leak - android

My main class application retrieves data using Retrofit and writes to a POJO ordinary Realm object. Then run the second Activity (MapsActivity) where I set the map, filter the contents of the Realm object for the relevant data. Everything works.
I will add that the Realm object contains over 6600 rows so it is big. And unfortunately I feel I have leaks of memory. Each time you start MapsActivity (going back to MainActivity, selecting another category, and passing it to MapsActivity), the heap looks awful. This is shown in the attached image. I will add that the application works much better when I do not use the Realm object at all, I only do the second Retrofit call in the MapsActivity class. This solution unfortunately doubles my work (in Main and Maps I do exactly the same thing) and I want to avoid this. Maybe someone will see where I have a leak and why the program is slowing down.
My Main:
package com.flex.sklepik;
public class MainActivity extends AppCompatActivity {
List<String> shopsNames;
ArrayList<RowModel> rowModels;
public static final int REQUEST_GOOGLE_PLAY_SERVICES = 1972;
public Realm mRealm;
#BindView(R.id.toolbar_layout)
CollapsingToolbarLayout toolbarLayout;
#BindView(R.id.app_bar)
AppBarLayout appBar;
private ShopsAdapter adapter;
#BindView(R.id.recycler_view)
RecyclerView recyclerView;
private ProgressDialog progressDialog;
private Dialog errorDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
ButterKnife.bind(this);
startRegistrationService();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ConnectionDetector connectionDetector = new ConnectionDetector(this);
if (!connectionDetector.isConnection()) {
finish();
}
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 123);
checkPlayServices();
rowModels = new ArrayList<>();
shopsNames = new ArrayList<>();
Realm.init(this);
mRealm = Realm.getDefaultInstance();
initCollapsingToolbar();
Glide.with(getApplicationContext()).load(R.drawable.shoplogo).
into((ImageView) findViewById(R.id.backdrop));
adapter = new ShopsAdapter(MainActivity.this, shopsNames);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
AsyncTaskRetro asyncTaskRetro = new AsyncTaskRetro();
asyncTaskRetro.execute();
}
private boolean checkPlayServices() {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (googleApiAvailability.isUserResolvableError(resultCode)) {
if (errorDialog == null) {
errorDialog = googleApiAvailability.getErrorDialog(this, resultCode, 2404);
errorDialog.setCancelable(false);
}
if (!errorDialog.isShowing())
errorDialog.show();
}
}
return resultCode == ConnectionResult.SUCCESS;
}
private class AsyncTaskRetro extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Czekaj...");
progressDialog.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.hide();
}
#Override
protected Void doInBackground(Void... voids) {
PlacesAPI.Factory.getInstance().getPlaces().enqueue(new Callback<Places>() {
#Override
public void onResponse(Call<Places> call, Response<Places> response) {
for (int i = 0; i < response.body().getPosts().size(); i++) {
RowModel rowModel = new RowModel(response.body().getPosts().get(i).getNazwa(),
Double.parseDouble(response.body().getPosts().get(i).getSzer()),
Double.parseDouble(response.body().getPosts().get(i).getDlug()));
rowModels.add(rowModel);
}
String oldName;
oldName = rowModels.get(0).getName();
shopsNames.add(rowModels.get(0).getName());
mRealm.beginTransaction();
mRealm.copyToRealm(rowModels);
mRealm.commitTransaction();
for (int j = 0; j < rowModels.size(); j++) {
if (rowModels.get(j).getName().equals(oldName)) {
continue;
}
oldName = rowModels.get(j).getName();
shopsNames.add(rowModels.get(j).getName());
}
//sortowanie listy z nazwami sklepow
Collections.sort(shopsNames);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<Places> call, Throwable t) {
}
});
return null;
}
}
#Override
protected void onResume() {
recyclerView.setAdapter(adapter);
super.onResume();
}
private void initCollapsingToolbar() {
final CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
collapsingToolbar.setTitle(" ");
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
appBarLayout.setExpanded(true);
// hiding & showing the title when toolbar expanded & collapsed
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
collapsingToolbar.setTitle(getString(R.string.app_name));
isShow = true;
} else if (isShow) {
collapsingToolbar.setTitle(" ");
isShow = false;
}
}
});
}
private void startRegistrationService() {
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int code = api.isGooglePlayServicesAvailable(this);
if (code == ConnectionResult.SUCCESS) {
onActivityResult(REQUEST_GOOGLE_PLAY_SERVICES, Activity.RESULT_OK, null);
} else if (api.isUserResolvableError(code) &&
api.showErrorDialogFragment(this, code, REQUEST_GOOGLE_PLAY_SERVICES)) {
// wait for onActivityResult call (see below)
} else {
Toast.makeText(this, api.getErrorString(code), Toast.LENGTH_LONG).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode == Activity.RESULT_OK) {
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
}
Map Class:
public class MapActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnMarkerClickListener
{
private GoogleMap mMap;
private double naviLat, naviLong;
private double latitude, longitude;
private GoogleApiClient mGoogleApiClient;
#BindView(R.id.adView)
AdView adView;
#BindView(R.id.butnavi)
ImageButton butnavi;
private Location location;
private RealmResults<RowModel> rowModels;
private String shopName;
private Bundle bundle;
private Realm realm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map2);
ButterKnife.bind(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(map);
mapFragment.getMapAsync(this);
bundle = getIntent().getExtras();
shopName = bundle.getString("shopName");
mapFragment.getMapAsync(this);
ActivityCompat.requestPermissions(MapActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 123);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
realm = Realm.getDefaultInstance();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMarkerClickListener(this);
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Uprawnienia nie przyznane", Toast.LENGTH_SHORT).show();
}
mMap.setMyLocationEnabled(true);
cameraMove();
//po wczytaniu mapy wyciągnij dane z bazy sklepów
realmDatabaseBuild();
}
private void addMarker(double lat, double lon) {
mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lon)));
}
#OnClick(R.id.butnavi)
public void btnNavi() {
if (naviLat + naviLong == 0)
Toast.makeText(this,
"Najpierw wybierz market", Toast.LENGTH_SHORT)
.show();
else {
Intent i = new Intent(Intent.ACTION_VIEW, Uri
.parse("google.navigation:q=" + naviLat + ","
+ naviLong));
startActivity(i);
finish();
System.exit(0);
}
}
private void moveCameraToActualPosition(double lat, double lon) {
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(lat, lon))
.zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
private void realmDatabaseBuild() {
rowModels = realm.where(RowModel.class).equalTo("name", shopName).findAll();
if (!rowModels.isEmpty()) {
for (int i = 0; i < rowModels.size(); i++) {
addMarker(rowModels.get(i).getLongitude(), rowModels.get(i).getLattitude());
}
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mapTypeNormal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.mapTypeSatellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.mapTypeTerrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.mapTypeHybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onBackPressed() {
super.onBackPressed();
mMap.clear();
rowModels = null;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onMarkerClick(Marker marker) {
LatLng gps = marker.getPosition();
//ustawienie lat i long dla nawigacji
naviLat = gps.latitude;
naviLong = gps.longitude;
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses;
try {
addresses = geocoder.getFromLocation(gps.latitude, gps.longitude, 1);
String adres = addresses.get(0).getAddressLine(0);
Toast.makeText(this, "Adres: " + adres, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public void cameraMove() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Uprawnienia nie przyznane", Toast.LENGTH_SHORT).show();
}
Location myLocation = locationManager.getLastKnownLocation(provider);
if (myLocation != null) {
LatLng ll = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(ll)
.zoom(11).build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
} else {
LatLng ll = new LatLng(52.230625, 21.013129);//WAWA
CameraPosition cp = new CameraPosition.Builder()
.target(ll)
.zoom(10).build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cp));
}
}
}
And Pojo:
public class RowModel extends RealmObject {
#Required
private String name;
#Required
private Double lattitude, longitude;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getLattitude() {
return lattitude;
}
public void setLattitude(Double lattitude) {
this.lattitude = lattitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public RowModel(String name, Double lattitude, Double longitude) {
this.name = name;
this.lattitude = lattitude;
this.longitude = longitude;
}
public RowModel() {
}
}

Related

How to add multiple pins to mapView after gettng JSON data

I'm making an app to display the five nearest Subway stations. I'm able to get the names of the stations back and populate a list view with the data.
I'm getting lng&lat from the API and would like to add pins to the map using these coordinates. I've got the map working, I'm able to display a single pin, but not multiple pins. A point in the correct direction would be much appreciated - Please see code below.
public class nearMe extends AppCompatActivity implements OnMapReadyCallback {
private MapView mapView;
public GoogleMap gmap;
private static final String MAP_VIEW_BUNDLE_KEY = "MapViewBundleKey";
// Location Co-ordinates
private String lat = "";
private String lng = "";
LocationManager locationManager;
LocationListener locationListener;
private List<Station> stationList = new ArrayList<>();
private RecyclerView recyclerView;
private stationAdapter mAdapter;
/* LOCATION STUFF */
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startListening();
}
}
public void startListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
}
}
public void updateLocationInfo(Location location) {
lat = "" + location.getLatitude();
lng = "" + location.getLongitude();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_location, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// int id = item.getItemId();
getNearestStations();
Toast.makeText(this, "Location Updated!", Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_near_me);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new stationAdapter(stationList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
// onClick
recyclerView.addOnItemTouchListener(new TouchListener(getApplicationContext(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
// Toast.makeText(getApplicationContext(), stationList.get(position).getStation() + "", Toast.LENGTH_SHORT).show();
String findStation = stationList.get(position).getStation();
// Toast.makeText(nearMe.this, bob, Toast.LENGTH_SHORT).show();
Uri gmmIntentUri = Uri.parse("google.navigation:q="+findStation+"underground station+London&mode=w");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
mapIntent.setFlags(mapIntent.FLAG_ACTIVITY_CLEAR_TOP);
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
}
}));
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
updateLocationInfo(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (Build.VERSION.SDK_INT < 23) {
startListening();
} else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
updateLocationInfo(location);
}
}
}
// insert Stations in to recycler
getNearestStations();
//map
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAP_VIEW_BUNDLE_KEY);
}
mapView = (MapView) findViewById(R.id.map_view);
mapView.onCreate(mapViewBundle);
mapView.getMapAsync(this);
}
// clear adapter before adding
public void clear() {
int size = this.stationList.size();
this.stationList.clear();
mAdapter.notifyItemRangeRemoved(0, size);
}
public void getNearestStations(){
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://transportapi.com/v3/uk/tube/stations/near.json?app_id=157c4895&app_key=091697cea8bae89519dd02ebb318fc51&lat=" + lat + "&lon=" + lng + "&rpp=5";
final StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("stations");
// Call 'Clear' method to clear mAdapter before adding new data
clear();
if (jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jObject = jsonArray.getJSONObject(i);
String station = jObject.getString("name");
Station newStation = new Station(station);
stationList.add(newStation);
mAdapter.notifyDataSetChanged();
double longitude = Double.parseDouble(lng);
double latitude = Double.parseDouble(lat);
gmap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.title(station));
}
}else{
Station newStation = new Station("No stations near");
stationList.add(newStation);
mAdapter.notifyDataSetChanged();
// Show a diaog
AlertDialog alertDialog = new AlertDialog.Builder(nearMe.this).create();
alertDialog.setTitle("No Stations Found");
alertDialog.setMessage("You are either not in London or you have no network connectivity.");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}); alertDialog.show();
}
} catch (JSONException e) { }
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
// maps
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAP_VIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAP_VIEW_BUNDLE_KEY, mapViewBundle);
}
mapView.onSaveInstanceState(mapViewBundle);
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
protected void onPause() {
mapView.onPause();
super.onPause();
}
#Override
protected void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onMapReady(GoogleMap googleMap) {
}
}
Let's say your API returns data in the markers array.
for(int i = 0 ; i < markers.size() ; i++ ) {
createMarker(markers.get(i).getLatitude(), markers.get(i).getLongitude(), markers.get(i).getTitle(), markers.get(i).getSnippet(), markers.get(i).getIconResID());
}
...
protected Marker createMarker(double latitude, double longitude, String title, String snippet, int iconResID) {
return googleMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title(title)
.snippet(snippet);
.icon(BitmapDescriptorFactory.fromResource(iconResID)));
}

Intent among three activities error

I searched all the question about android intent among three activities in stack overflow, but there were unfortunate without the expect occasion i faced, the first activity which include a simple button but it does't matter and through that activity i pass a data to the second activity, and i want to click the textView(a button) and pass some data to the third activity, the total program is too long and here is the snippet:
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_search:
Intent third = new Intent(this, ThirdActivity.class);
startActivity(third);
break;
default:
break;
}
}
what i expect is that click the button and jump to the third activity, but actually every click it back to the first activity, i am curious if i can not use intent in the second activity?but i think it's ridiculous. Is there any suggestion about this problem.
UPDATE:here is the whole class but there are many empty implementation, and SDK is gaode map, so don't care about the total logic and just pay attention on the onclick event:
public class AroundSearchActivity extends Activity implements AMap.OnMapClickListener,
AMap.OnMarkerClickListener, AMap.OnInfoWindowClickListener, AMap.InfoWindowAdapter,
View.OnClickListener, PoiSearch.OnPoiSearchListener, LocationSource, AMapLocationListener
{
private AMap map;
private MapView mapView;
private AMapLocation mapLocation;
private AMapLocationClient mapLocationClient;
private AMapLocationClientOption mapLocationClientOption;
private OnLocationChangedListener locationChangedListener;
private double latitude;
private double longitude;
private double previousLatitude = 0;
private Marker currentMarker;
private RelativeLayout detail;
private TextView name;
private TextView address;
private EditText input_text;
private PoiSearch poiSearch;
private PoiSearch.Query query;
private PoiResult result;
private ArrayList<PoiItem> poiItems;
private Marker mLastMarker;
private Marker detailMarker;
private MyPoiOverlay poiOverlay;
private String searchStr;
private int[] showMarkers = {
R.drawable.poi_marker_1,R.drawable.poi_marker_2,R.drawable.poi_marker_3,R.drawable.poi_marker_4,R.drawable.poi_marker_5,
R.drawable.poi_marker_6,R.drawable.poi_marker_7,R.drawable.poi_marker_8,R.drawable.poi_marker_9,R.drawable.poi_marker_10,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.poiaroundsearch_activity);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
init();
}
public void init(){
if (map == null){
map = mapView.getMap();
}
setUpMap();
map.setOnMapClickListener(this);
map.setOnMarkerClickListener(this);
map.setOnInfoWindowClickListener(this);
map.setInfoWindowAdapter(this);
TextView search = (TextView) findViewById(R.id.btn_search);
search.setOnClickListener(this);
setup();
}
public void setup(){
detail = (RelativeLayout) findViewById(R.id.poi_detail);
detail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//toggle detail click event
Toast.makeText(AroundSearchActivity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
name = (TextView) findViewById(R.id.poi_name);
address = (TextView) findViewById(R.id.poi_address);
input_text = (EditText) findViewById(R.id.input_edittext);
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
searchMap();
}
#Override
protected void onPause() {
super.onPause();
mapView.onDestroy();
deactivate();
}
public void setUpMap(){
map.setLocationSource(this);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
map.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
}
#Override
protected void onDestroy() {
super.onDestroy();
locationChangedListener = null;
if (mapLocationClient != null){
mapLocationClient.stopLocation();
mapLocationClient.onDestroy();
}
mapLocationClient = null;
}
#Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (locationChangedListener != null && aMapLocation != null){
if(aMapLocation.getErrorCode() == 0){
latitude = aMapLocation.getLatitude();
longitude = aMapLocation.getLongitude();
locationChangedListener.onLocationChanged(aMapLocation);
Log.i("CurrentLocation", "latitude is " + latitude + " ,longitude is:" + longitude);//get current latitude and longitude
if (currentMarker != null) currentMarker = null;
currentMarker = map.addMarker(new MarkerOptions().
position(new LatLng(latitude, longitude))
.icon(null)
.draggable(true));
currentMarker.showInfoWindow();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 16));
if (previousLatitude == 0){
searchMap();
}else{
String pre = String.valueOf(previousLatitude);
String a = pre.substring(pre.indexOf(".") + 1, pre.indexOf(".") + 4);
String cur = String.valueOf(latitude);
String b = cur.substring(cur.indexOf(".") + 1, cur.indexOf(".") + 4);
if (!a.equals(b)){
searchMap();
}
}
previousLatitude = latitude;
}else{
int errorCode = aMapLocation.getErrorCode();
Toast.makeText(this, "定位失败:"+errorCode, Toast.LENGTH_SHORT);
}
}
}
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
#Override
public void activate(OnLocationChangedListener onLocationChangedListener) {
locationChangedListener = onLocationChangedListener;
if (mapLocationClient == null){
mapLocationClient = new AMapLocationClient(this);
mapLocationClientOption = new AMapLocationClientOption();
mapLocationClient.setLocationListener(this);mapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
mapLocationClient.setLocationOption(mapLocationClientOption);
mapLocationClient.startLocation();
}
}
#Override
public void deactivate() {
locationChangedListener = null;
if (mapLocationClient != null){
mapLocationClient.stopLocation();
mapLocationClient.onDestroy();
}
mapLocationClient = null;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_search:
Intent third = new Intent(this, ThirdActivity.class);
startActivity(third);
break;
default:
break;
}
}
#Override
public void onInfoWindowClick(Marker marker) {
}
#Override
public void onMapClick(LatLng latLng) {
whetherToShowInfo(false);
if (mLastMarker != null){
resetLastMarker();
}
}
#Override
public boolean onMarkerClick(Marker marker) {
if (marker.getObject() != null){
//whether to show the marker detail information
whetherToShowInfo(true);
//get the current location
PoiItem currentItem = (PoiItem) marker.getObject();
//aim at the next marker and preserve the current marker
if (mLastMarker == null){
mLastMarker = marker;
}else {
resetLastMarker();
mLastMarker = marker;
}
detailMarker = marker;
detailMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.poi_marker_pressed));
setPoiMarkerContent(currentItem);
}else {
whetherToShowInfo(false);
resetLastMarker();
}
return true;
}
#Override
public void onPoiSearched(PoiResult poiResult, int errorCode) {
if (errorCode == 1000){
if (poiResult != null && poiResult.getQuery() != null){
if (poiResult.getQuery().equals(query)){//判断是不是同一组查询
result = poiResult;//将搜索结果赋值给result
poiItems = result.getPois();
//列出所有poi搜索结果
for (int i = 0; i < poiItems.size(); i++){
Log.i("result"+i, poiItems.get(i).getSnippet());
}
List<SuggestionCity> suggestionCities = result.getSearchSuggestionCitys();
if (poiItems != null && poiItems.size() > 0){
whetherToShowInfo(false);
if (mLastMarker != null) {
resetLastMarker();
}
if (poiOverlay != null){
poiOverlay.removeFromMap();
}
map.clear();
poiOverlay = new MyPoiOverlay(this, map, poiItems);
poiOverlay.addToMap();
poiOverlay.zoomToSpan();//move to the current scene
map.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.point4))
.draggable(false)
.position(new LatLng(latitude, longitude)));
}else{
if (suggestionCities != null && suggestionCities.size() > 0){
showSuggestCity(suggestionCities);
}
}
}
}else {
Toast.makeText(this, "Sorry! No result match your request", Toast.LENGTH_SHORT).show();
}
}else {
Log.e("errorInfo", "Search failed:" + errorCode);
}
}
#Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
public void whetherToShowInfo(boolean w){
if (w){
detail.setVisibility(View.VISIBLE);
}else{
detail.setVisibility(View.GONE);
}
}
public void resetLastMarker(){
int index = poiOverlay.getPoiIndex(mLastMarker);
if (index < 10){
mLastMarker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), showMarkers[index])));
}else{
mLastMarker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.marker_other_highlight)));
}
mLastMarker = null;
}
public void showSuggestCity(List<SuggestionCity> suggestionCities){
String information = "City information/n";
for (int i = 0; i < suggestionCities.size(); i++){
information += "City name" + suggestionCities.get(i).getCityName() +
", City administrative code::" + suggestionCities.get(i).getAdCode();
}
Toast.makeText(this, information, Toast.LENGTH_SHORT);
}
public void searchMap(){
Toast.makeText(this, searchStr, Toast.LENGTH_SHORT).show();
Intent intent = getIntent();
searchStr = intent.getStringExtra("keyword");
int currentPage = 0;
query = new PoiSearch.Query(searchStr.trim(), "", "Beijing");
query.setPageSize(20);
query.setPageNum(currentPage);
LatLonPoint lp = new LatLonPoint(latitude, longitude);
if (lp != null){
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.setBound(new PoiSearch.SearchBound(lp, 2000, true));
poiSearch.searchPOIAsyn();
}
}
public void setPoiMarkerContent(PoiItem item){
name.setText(item.getTitle());
address.setText(item.getSnippet());
}
}

On resume the fragment i am unable to view the marker and animated camera to a location in map

I am working on an app with google maps-v2. Everything is working fine but when i go from the map fragment to other fragment and get back to the map fragment its not adding any marker or animating the camera.
Following is the code for the fragment:
public class MapPane extends Fragment implements DirectionFinderListener {
private static final int PERMISSION_REQUEST_CODE = 1;
ProgressBar progressBar;
// Google Map
private static GoogleMap googleMap;
public static double latitude, longitude;
private Button btnFindPath;
private String sOrigin = "";
private String sDestination = "";
private List<Marker> originMarkers = new ArrayList<>();
private List<Marker> destinationMarkers = new ArrayList<>();
private List<Polyline> polylinePaths = new ArrayList<>();
private ProgressDialog progressDialog;
View v;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.map_pane, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.m_directions) {
Fragment frag3 = new DirectionActivity();
android.support.v4.app.FragmentTransaction ft3 = getActivity().getSupportFragmentManager().beginTransaction();
ft3.replace(R.id.content_frame, frag3);
ft3.commit();
}
return super.onOptionsItemSelected(item);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.e("MapPane", "onCreateView()");
v = inflater.inflate(R.layout.activity_maps, container, false);
progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
sOrigin = getArguments().getString("source");
sDestination = getArguments().getString("destination");
Log.e("MapPane ", "Source: " + sOrigin + "Destination: " + sDestination);
Geocoder geocoder = new Geocoder(getActivity());
List<Address> addresses = null;
if (sOrigin.equals(null)) {
Toast.makeText(getActivity(), "Source is empty!", Toast.LENGTH_SHORT).show();
} else {
try {
addresses = geocoder.getFromLocationName(sOrigin, 1);
} catch (IOException e) {
e.printStackTrace();
}
if (addresses.size() > 0) {
latitude = addresses.get(0).getLatitude();
longitude = addresses.get(0).getLongitude();
Log.e("Location Coordinates ", String.valueOf(latitude) + " ," + String.valueOf(longitude));
}
}
btnFindPath = (Button) v.findViewById(R.id.btnFindPath);
progressDialog = new ProgressDialog(v.getContext());
progressDialog.setCancelable(false);
progressDialog.setMessage("Please wait...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
try {
// Loading map
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
if (!checkPermission()) {
requestPermission();
} else {
zoomToOrigin();
}
btnFindPath.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendRequest();
}
});
return v;
}
private void zoomToOrigin() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
googleMap.setMyLocationEnabled(true);
} else {
// Show rationale and request permission.
}
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
CameraPosition cameraPosition = new CameraPosition.Builder().target(
new LatLng(latitude, longitude)).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Permission Granted, Now you can access location data.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "Permission Granted, Now you can access location data.", Toast.LENGTH_LONG).show();
}
break;
}
}
/**
* function to load map. If map is not created it will create it for you
*/
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getActivity().getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
private void sendRequest() {
try {
new DirectionFinder(this, sOrigin, sDestination).execute();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onResume() {
initilizeMap();
Log.e("MapPane", "onResume()" + latitude + " ," + longitude);
MarkerOptions marker = new MarkerOptions().position(new LatLng(latitude, longitude))
.title("Nagpur");
googleMap.addMarker(marker);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(latitude, longitude)).zoom(14).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
Fragment fragment = new BDashboard();
FragmentManager fm = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
return true;
}
return false;
}
});
super.onResume();
}
#Override
public void onDestroyView() {
Log.e("MapPane", "onDestroyView");
try {
MapFragment fragment = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
} catch (Exception e) {
}
super.onDestroyView();
}
#Override
public void onDirectionFinderStart() {
progressDialog = ProgressDialog.show(getActivity(), "Please wait.",
"Finding direction..!", true);
if (originMarkers != null) {
for (Marker marker : originMarkers) {
marker.remove();
}
}
if (destinationMarkers != null) {
for (Marker marker : destinationMarkers) {
marker.remove();
}
}
if (polylinePaths != null) {
for (Polyline polyline : polylinePaths) {
polyline.remove();
}
}
}
#Override
public void onDirectionFinderSuccess(List<Route> routes) {
progressDialog.dismiss();
polylinePaths = new ArrayList<>();
originMarkers = new ArrayList<>();
destinationMarkers = new ArrayList<>();
for (Route route : routes) {
((TextView) v.findViewById(R.id.tvDuration)).setText(route.duration.text);
((TextView) v.findViewById(R.id.tvDistance)).setText(route.distance.text);
originMarkers.add(googleMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.start_blue))
.title(route.startAddress)
.position(route.startLocation)));
destinationMarkers.add(googleMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green))
.title(route.endAddress)
.position(route.endLocation)));
PolylineOptions polylineOptions = new PolylineOptions().
geodesic(true).
color(Color.BLUE).
width(10);
for (int i = 0; i < route.points.size(); i++)
polylineOptions.add(route.points.get(i));
polylinePaths.add(googleMap.addPolyline(polylineOptions));
}
}
}
This is the only problem i am facing unless everything is working fine.
Please help me to solve this issue.
Thanks

I want to show Multiple Markers at runtime on the screen which have different id's that received from the server

I want to show Multiple Markers at runtime on the screen which have different id's that received from the server and longitude and latitude also change or save on server.
** Code work fine in 1 to 1 tracking but not work on multiple Id's PLEASE HELP ME..**
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
static final LatLng HAMBURG1 = new LatLng(74.3226214, 31.5003567);
static final LatLng HAMBURG = new LatLng(74.3229122, 31.5003193);
private static MainActivity instance;
private static final int ERROR_DIALOG_REQUEST = 9001;
GoogleMap mMap;
int i = 0;
protected static String longitudeServer;
protected static String latitudeServer;
protected static String uniqueidSserver;
protected static String latitudeLast;
protected static String logitudeLast;
protected static String uniqueidlast;
protected static double latilasdoublet;
protected static double longilastdouble;
double latitude = 0;
double longitude = 0;
private GoogleApiClient mLocationClient;
private com.google.android.gms.location.LocationListener mListener;
private Marker marker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (servicesOK()) {
setContentView(R.layout.activity_map);
if (initMap()) {
// gotoLocation(SEATTLE_LAT, SEATTLE_LNG, 15);
mLocationClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mLocationClient.connect();
mMap.setMyLocationEnabled(true);
} else {
Toast.makeText(this, "Map not connected!", Toast.LENGTH_SHORT).show();
}
} else {
setContentView(R.layout.activity_main);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//Add menu handling code
switch (id) {
case R.id.mapTypeNone:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.mapTypeNormal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.mapTypeSatellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.mapTypeTerrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.mapTypeHybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
}
return super.onOptionsItemSelected(item);
}
public boolean servicesOK() {
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(isAvailable, this, ERROR_DIALOG_REQUEST);
dialog.show();
} else {
Toast.makeText(this, "Can't connect to mapping service", Toast.LENGTH_SHORT).show();
}
return false;
}
private boolean initMap() {
if (mMap == null && i == 0) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mMap = mapFragment.getMap();
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
return (mMap != null);
}
private void gotoLocation(double lat, double lng, float zoom) {
LatLng latLng = new LatLng(lat, lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng, zoom);
mMap.moveCamera(update);
}
public void showCurrentLocation(MenuItem item) {
Location currentLocation = LocationServices.FusedLocationApi
.getLastLocation(mLocationClient);
if (currentLocation == null) {
Toast.makeText(this, "Couldn't connect!", Toast.LENGTH_SHORT).show();
} else {
LatLng latLng = new LatLng(
currentLocation.getLatitude(),
currentLocation.getLongitude()
);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(
latLng, 10
);
mMap.animateCamera(update);
}
}
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this, "Ready to map!", Toast.LENGTH_SHORT).show();
mListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
// mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
Toast.makeText(MainActivity.this, "Location : " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_LONG).show();
if (i == 0) {
gotoLocation(location.getLatitude(), location.getLongitude(), 15);
i = 1;
}
AppUtill.UniqueId();
if (AppStatus.getInstance(getContext()).isOnline()) {
new JSONAsyncTask().execute("http://ip/hajjapi/api/GPSLocator/GetLocations");
} else {
Toast.makeText(MainActivity.this, "Turn On your WIFI ", Toast.LENGTH_LONG).show();
}
///HOW I CAN DISPLAY MULTIPLE MARKERS WHICH HAVE DIFFERENT ID'S RECEIVED FROM THE SERVER PLEASE HELP ME PLEASE...
if (marker != null) {
marker.remove();
}
MarkerOptions options = new MarkerOptions().title("User Name").position(new LatLng(latilasdoublet, longilastdouble)).icon(BitmapDescriptorFactory.fromResource(R.drawable.female4));
marker = mMap.addMarker(options);
}
};
LocationRequest request = LocationRequest.create();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(5000);
request.setFastestInterval(5000);
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, request, mListener);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public void showcurrentLocation() {
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
i = 1;
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httpGet = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpGet);
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONArray jsonarray = new JSONArray(data);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
longitudeServer = obj.getString("longi");
latitudeServer = obj.getString("lati");
uniqueidSserver = obj.getString("uniqueid");
}
////LAST LONGITUDE AND LATITUDE THAT RECEIVED FROM SERVER
List<String> longitude = Arrays.asList(longitudeServer);
logitudeLast = longitude.get(longitude.size() - 1);
System.out.println(logitudeLast + " logitude ");
List<String> latitude = Arrays.asList(latitudeServer);
latitudeLast = latitude.get(latitude.size() - 1);
System.out.println(latitudeLast + " latitude ");
List<String> uniqueid = Arrays.asList(uniqueidSserver);
uniqueidlast = uniqueid.get(uniqueid.size() - 1);
System.out.println(uniqueidlast + " unique id ");
latilasdoublet = Double.parseDouble(latitudeLast);
longilastdouble = Double.parseDouble(logitudeLast);
return true;
}
//------------------>>
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
if (result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
#Override
protected void onStop() {
super.onStop();
startService(new Intent(getContext(), Services.class));
}
public MainActivity() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
you are using only two double variables for lat and lng. create an arrayList of LatLng objects. for all the urls you get in response, add the LatLng to the arrayList.
add a field
private ArrayList<LatLng> latLngList;
initialize in oncreate function
latLngList = new ArrayList<>();
instead of
latilasdoublet = Double.parseDouble(latitudeLast);
longilastdouble = Double.parseDouble(logitudeLast);
add
for(int i=0; i< latitude.size(); i++){
LatLng latLng = new LatLng(Double.parseDouble(latitude.get(i)), Double.parseDouble(longitude.get(i)));
latLngList.add(latLng);
}
in place of
MarkerOptions options = new MarkerOptions().title("User Name").position(new LatLng(latilasdoublet, longilastdouble)).icon(BitmapDescriptorFactory.fromResource(R.drawable.female4));
marker = mMap.addMarker(options);
use
ArrayList<MarkerOptions> list = new ArrayList<>();
for (LatLng object : latLngList){
MarkerOptions options = new MarkerOptions().title("User Name").position(object).icon(BitmapDescriptorFactory.fromResource(R.drawable.female4));
mMap.addMarker(options);
list.add(options); //if you want to keep track of all your markers
}
use mMap.clear() to clear all markers and clustering refer
More info on markers.

PlaceAutocomplete Widget on MapView Fragment

I am trying to create a mapview with a PlaceAutocomplete widget overlayed on it.
The function of this view is to calculate the distance from my current location to the location I have chosen in the PlaceAutocomplete widget.
To explain myself better, I need a similar fragment, as to the Google Maps app. For the time being I have created a fragment which displays the map. This view is then being overlayed by the PlaceAutocomplete widget.
Currently, I am able to get my current location when I start the mapview. (screenshot 1) However when I try to search for a destination (screenshot 2), the widget simply shows the destination I have chosen, without calling the Google Directions API to get the bus route from my location to the destination. (screenshot 3)
From my logcat, I can see that the method to construct the URL and call the Google Directions API is not even being called.
Here is my code:
public class GeoFragment extends Fragment implements PlaceSelectionListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleMap map;
SupportMapFragment mapFragment;
private LocationRequest lr;
private GoogleApiClient apiClient;
private static View view;
private Location location;
int PLACE_AUTOCOMPLETE_REQUEST_CODE = 1;
int RESULT_OK = 2;
int RESULT_CANCELED = 3;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
final String GOOGLE_KEY;
int PLACE_PICKER_REQUEST = 1;
double currentLatitude;
double currentLongitude;
SupportPlaceAutocompleteFragment searcher;
String placeString;
public GeoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
buildGoogleApiClient();
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.layout_map, container, false);
mapFragment = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapView));
searcher = (SupportPlaceAutocompleteFragment) this.getChildFragmentManager().findFragmentById(R.id.info_text);
//searcher.setBoundsBias(new LatLngBounds(new LatLng(), new LatLng()));
map = mapFragment.getMap();
map.getUiSettings().setAllGesturesEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
map.getUiSettings().setZoomControlsEnabled(false);
map.animateCamera(CameraUpdateFactory.zoomIn());
map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
MapsInitializer.initialize(this.getActivity());
} catch (InflateException e) {
Toast.makeText(getActivity(), "Problems inflating the view !",
Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
Log.e("GServices Error", e.toString());
}
return view;
}
protected synchronized void buildGoogleApiClient() {
apiClient = new GoogleApiClient.Builder(getActivity().getApplicationContext())
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
return false;
}
return true;
}
#Override
public void onStart() {
super.onStart();
if (apiClient != null) {
apiClient.connect();
}
}
#Override
public void onStop() {
super.onStop();
if (apiClient.isConnected()) {
apiClient.disconnect();
}
}
#Override
public void onPause() {
super.onPause();
stopLocationUpdates();
}
#Override
public void onResume() {
super.onResume();
checkPlayServices();
// Resuming the periodic location updates
if (apiClient.isConnected()) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
apiClient, lr, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
apiClient, this);
}
public void getCoordinates(){
location = LocationServices.FusedLocationApi.getLastLocation(apiClient);
if (location != null) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
}
}
#Override
public void onLocationChanged(Location loc) {
location = loc;
getCoordinates();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
}
#Override
public void onConnected(Bundle connectionHint) {
if (location == null) {
lr = LocationRequest.create();
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lr.setInterval(1000);
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, lr, this);
}
//getCoordinates();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("Map Connection Failed", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
public void onConnectionSuspended(int arg0) {
apiClient.connect();
}
public void SearchPlace(String place) throws GooglePlayServicesNotAvailableException, GooglePlayServicesRepairableException {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);
callPlaces(currentLongitude, currentLatitude, place);
}
public void callPlaces(final double longitude, final double latitude, final String destination) {
String tag_string_req = "req_places";
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + latitude + "," + longitude + "&destination="+ destination +"&alternatives=true&mode=transit&region=mt&key=" + getResources().getString(R.string.google_places_key);
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
drawPath(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", "Registration Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(strReq);
}
public void drawPath(String result){
try {
final JSONObject jsonObject = new JSONObject(result);
JSONArray routeArray = jsonObject.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
String statusString = jsonObject.getString("status");
Log.d("test: ", encodedString);
List<LatLng> list = decodePoly(encodedString);
LatLng last = null;
for (int i = 0; i < list.size()-1; i++) {
LatLng src = list.get(i);
LatLng dest = list.get(i+1);
last = dest;
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
Polyline line = map.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
.width(4)
.color(Color.GREEN));
}
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
}catch (JSONException e){
e.printStackTrace();
}
catch(ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException: "+ e.getMessage());
}
}
private List<LatLng> decodePoly(String encoded){
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0;
int length = encoded.length();
int latitude = 0;
int longitude = 0;
while(index < length){
int b;
int shift = 0;
int result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int destLat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
latitude += destLat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b > 0x20);
int destLong = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
longitude += destLong;
poly.add(new LatLng((latitude / 1E5),(longitude / 1E5) ));
}
return poly;
}
#Override
public void onPlaceSelected(Place place) {
Log.i("Destination", "Place Selected: " + place.getName());
placeString = place.getName().toString();
CharSequence attributions = place.getAttributions();
if (!TextUtils.isEmpty(attributions)) {
try {
SearchPlace(placeString);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
} else {
searcher.setText("Where shall we take you today?");
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
searcher.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onError(Status status) {
Log.e("TAG", "onError: Status = " + status.toString());
}
}
Can someone please help me with this issue?
Any help is appreciated :)
Edit: This fragment is part of a tabbed app, so I cannot use an activity instead of a fragment. Therefore the mapview and PlaceAutocomplete Widget need to be constructed in the fragment. I would also like to have the PlaceAutocomplete Widget overlay the map. I found tutorials having the PlaceAutocomplete Widget in a seperate activity. This is not the solution I am looking for.
For all of you having the same issue, I have managed to implement the project I intended to, however I used a custom AutoCompleteTextView and attached it to the Google Places API. This enabled me to create a request and get back a response.
Below is the code for all those brave souls who wish to create a call to the Google PlaceAutoComplete API, overlayed on a map.
public class GeoFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleMap map;
SupportMapFragment mapFragment;
AutoCompleteTextView destination;
GooglePlacesAutocompleteAdapter mAdapter;
ListView listView;
String dest;
private LocationRequest lr;
private GoogleApiClient apiClient;
private static View view;
private Location location;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
final String GOOGLE_KEY;
double currentLatitude;
double currentLongitude;
private static final String[] LOCATION_PERMS={
Manifest.permission.ACCESS_FINE_LOCATION
};
public GeoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (!canAccessLocation() || !canAccessLocation()) {
requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
}
buildGoogleApiClient();
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.layout_map, container, false);
mapFragment = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapView));
destination = (AutoCompleteTextView) view.findViewById(R.id.destinationTextView);
final CardView destinationCard = (CardView)view.findViewById(R.id._Cardview);
final CardView placesCard = (CardView)view.findViewById(R.id._cardPlaces);
mAdapter = new GooglePlacesAutocompleteAdapter(this.getActivity(), android.R.layout.simple_list_item_1);
listView = (ListView) view.findViewById(R.id.placeList);
listView.setAdapter(mAdapter);
listView.setTextFilterEnabled(true);
destination.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
placesCard.setVisibility(View.VISIBLE);
mAdapter.getFilter().filter(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dest = (String) parent.getItemAtPosition(position);
destination.setText(dest);
dest = dest.replace(" ", "%20");
try {
SearchPlace(dest);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
placesCard.setVisibility(View.INVISIBLE);
destinationCard.setVisibility(View.INVISIBLE);
}
});
map = mapFragment.getMap();
map.getUiSettings().setAllGesturesEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
map.getUiSettings().setZoomControlsEnabled(false);
map.animateCamera(CameraUpdateFactory.zoomIn());
map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
MapsInitializer.initialize(this.getActivity());
} catch (InflateException e) {
Toast.makeText(getActivity(), "Problems inflating the view !",
Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
Log.e("GServices Error", e.toString());
}
return view;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch(requestCode) {
case LOCATION_REQUEST:
if (canAccessLocation()) {
callLocationPerms();
}
break;
}
}
private void callLocationPerms() {
Toast.makeText(getActivity().getApplicationContext(),
"We need your permission to access you current location", Toast.LENGTH_SHORT).show();
}
private boolean canAccessLocation() {
return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
#TargetApi(Build.VERSION_CODES.M)
private boolean hasPermission(String perm) {
return(PackageManager.PERMISSION_GRANTED==getActivity().checkSelfPermission(perm));
}
protected synchronized void buildGoogleApiClient() {
apiClient = new GoogleApiClient.Builder(getActivity().getApplicationContext())
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
return false;
}
return true;
}
public void getCoordinates(){
location = LocationServices.FusedLocationApi.getLastLocation(apiClient);
if (location != null) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
}
}
#Override
public void onLocationChanged(Location loc) {
location = loc;
getCoordinates();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
}
#Override
public void onConnected(Bundle connectionHint) {
if (location == null) {
lr = LocationRequest.create();
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lr.setInterval(1000);
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, lr, this);
}
//getCoordinates();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("Map Connection Failed", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
public void onConnectionSuspended(int arg0) {
apiClient.connect();
}
public void SearchPlace(String place) throws GooglePlayServicesNotAvailableException, GooglePlayServicesRepairableException {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
//startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);
callPlaces(currentLongitude, currentLatitude, place);
}
public void callPlaces(final double longitude, final double latitude, final String destination) {
String tag_string_req = "req_places";
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + latitude + "," + longitude + "&destination="+ destination +"&alternatives=false&mode=transit&region=mt&key=" + getResources().getString(R.string.google_places_key);
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
parsePlace(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", "Registration Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(strReq);
}
}
Good luck and don't forget to vote-up please if this answer has helped you :)

Categories

Resources