Custom Map Tile Work in Chrome but not Android - android

I'm building an Android app that uses custom map tiles. I started out with a set that worked fine but only had limited zoom levels and area. Then I switched to another tile set that covered much more area but simply refuses to display in Android. I can see them in the Javascript Maps and there are no errors in my LogCat so I'm not sure what's going on.
Are there only certain image formats that the Android Map overlays support?
For reference, here are the two tile sets:
This one works both on the web and in Android:
http://mooproductions.org/vfrs/local.html
This one works on the web but simply doesn't render on Android:
http://mooproductions.org/vfrs/national.html
Here's he code I'm using to provide the tile sets:
public class VfrTileProvider extends UrlTileProvider
{
// private static final String BASE_URL = "http://www.mooproductions.org/vfrs/%d/%d/%d.png";
// private static final String BASE_URL = "http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/%d/%d/%d.jpg";
private static final String BASE_URL = "http://vfrmap.com/20170914/tiles/vfrc/%d/%d/%d.jpg";
public VfrTileProvider (int width, int height)
{
super(width, height);
}
#Override
public URL getTileUrl (int x, int y, int zoom)
{
int reversedY = (1 << zoom) - y - 1;
// String tileUrl = String.format(Locale.US, BASE_URL, zoom, x, reversedY);
String tileUrl = String.format(Locale.US, BASE_URL, zoom, reversedY, x);
Log.d("Tile Provider", tileUrl);
URL url = null;
try { url = new URL(tileUrl); }
catch (MalformedURLException e) { e.printStackTrace(); }
return url;
}
}
You can see commented out are the other URLs for tile sets that I use that work just fine. The creation of the tileUrl is a little different because this new tile set transposes the x and y in their url.
Here is the code I use to display the custom tiles:
#Override
public void onMapReady (GoogleMap googleMap)
{
_map = googleMap;
_map.setMapType(GoogleMap.MAP_TYPE_NONE);
VfrTileProvider tileProvider = new VfrTileProvider(256, 256);
_map.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
Criteria criteria = new Criteria();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_LOCATION_PERMISSION);
return;
}
Location location = _locationManager.getLastKnownLocation(_locationManager.getBestProvider(criteria, false));
if (location != null)
{
_map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 13));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location.getLongitude()))
.zoom(10)
.build();
_map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}

This is because wrong "User-Agent" property settings of URL url object in VfrTileProvider.getTileUrl(). You can set it to correct by setRequestProperty():
URL url = null;
try {
url = new URL(tileUrl);
try {
url.openConnection().setRequestProperty("User-Agent","<correct user agent name>");
} catch (IOException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
or just add System.setProperty("http.agent", ""); call to your public void onMapReady ():
#Override
public void onMapReady (GoogleMap googleMap)
{
System.setProperty("http.agent", "");
_map = googleMap;
...
}
I prefer second (System.setProperty("http.agent", "");) case.

Related

Many GeoJSON or shapefile points as Geofences in Android?

I have a GEOJSON (I could convert it into Shapefile or another georeferenced file) with many points (a few hundreds) and I want to create geofences on all of them. How do I do this? I have the whole code to get a geofence of one point but how do I create geofences on many points?
When clicking long on the screen, a marker will be added which gets automatically a geofence
public void onMapLongClick(LatLng latLng) { // lange Klicken, bis Marker scheint
if (Build.VERSION.SDK_INT >= 29) {
// We need background permission (Manifest.xml)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) { // wenn permission granted
tryAddingGeofence(latLng);
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)){
//We show a dialog and ask for permission
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
} else {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
}
}
} else {
tryAddingGeofence(latLng);
}
}
private void tryAddingGeofence(LatLng latLng) {
mMap.clear();
addMarker(latLng);
addCircle(latLng, GEOFENCE_RADIUS);
addGeofence(latLng, GEOFENCE_RADIUS);
}
private void addGeofence(LatLng latLng, float radius){
Geofence geofence = geofenceHelper.getGeofence(GEOFENCE_ID, latLng, radius,
Geofence.GEOFENCE_TRANSITION_ENTER |
// Geofence.GEOFENCE_TRANSITION_DWELL |
Geofence.GEOFENCE_TRANSITION_EXIT); // wann wird geofence getriggert? -> reinlaufen, darin laufen oder rausgehen
GeofencingRequest geofencingRequest = geofenceHelper.getGeofencingRequest(geofence);
PendingIntent pendingIntent = geofenceHelper.getPendingIntent();
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Geofence Added...");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
String errorMessage = geofenceHelper.getErrorString(e);
Log.d(TAG, "onFailure: " + errorMessage);
}
});
}
private void addMarker(LatLng latLng) {
MarkerOptions markerOptions = new MarkerOptions().position(latLng);
mMap.addMarker(markerOptions);
}
private void addCircle(LatLng latLng, float radius){
CircleOptions circleOptions = new CircleOptions();
circleOptions.center(latLng);
circleOptions.radius(radius);
circleOptions.strokeColor(Color.argb(255,255,0,0));
circleOptions.fillColor(Color.argb(64,255,0,0));
circleOptions.strokeWidth(4);
mMap.addCircle(circleOptions);
} ```
I found an easy solution for anyone who will have this problem:
We need to create a list of all the coordinates. So at first we need to get the coordinates from the geojson file. In the followed solution I had a KML file but at the end it gets the same result.
I created a method which reads a txt file (you have to convert geojson or kml into .txt first and then copy it into src/main/res/raw. In my case I have "monitoring.txt" So dont forget to change the name into your filename.)
In the first part it reads the .txt and saves it into a String.
In the scond part it reads from it that String that is in between coordinates> and </coordinates. "(.*?)" shows that it takes everything that is between. When you have a GeoJson remember to look between what Strings the coordinates are. Then I take this String (means the coordinates), split them and parse Latitude and Longitude into double so that I can then safe it as LatLng Object. It has to be in a loop so that every coordinate in the kml/geojson/txt file will be taken and stored into the list "dangerousArea".
private List<LatLng> dangerousArea = new ArrayList<>();
private void readCoordinatesFromKml() throws IOException {
InputStream inputStream = getResources().openRawResource(R.raw.monitoring);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1)
{
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Pattern pattern = Pattern.compile("<coordinates>(.*?)</coordinates>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(byteArrayOutputStream.toString());
while (matcher.find()) {
String[] str = matcher.group(1).split(",");
double Longitude = Double.parseDouble(str[0]);
double Latitude = Double.parseDouble(str[1]);
dangerousArea.add(new LatLng(Latitude, Longitude));
}
}
Then you can just add the coordinates which are stored in the list as Geofences. This depends on what you called your method which creates a Geofence around your points:
dangerousArea.forEach(coordinate -> {tryAddingGeofence(coordinate);});
For the last thing you have to look at your code where to do this. Normally it is under a function which already made sure that you are allowed to get the location of the user.

Android google map Marker won't Show

I'm new at android development. I'm trying to add a Google marker at my App map but it won't show. I can set a Marker if the Marker's lat & lng is a double number,but when i put the API data in it it won't show.Any suggestion? Thanks a lot.
#Override
public void onMapReady(final GoogleMap googleMap) {
this.googleMap = googleMap;
// Add a marker in Sydney and move the camera
getLocation();
// This marker will show at my app screen !
LatLng latLng = new LatLng(24.9992666, 121.5082287);
googleMap.addMarker(new MarkerOptions().position(latLng)
.title("This is office Marker")
);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
this.googleMap.setMyLocationEnabled(true);
HttpUtil.sendHttpRequest("http://113.10.198.159/appapi/getWIFIList", new HttpCallbackListener() {
#Override
public void onFinish(String response) {
Gson gson = new Gson();
JsonBean jsonBean = gson.fromJson(response, JsonBean.class);
Log.d(TAG, "【】【id】【】" + jsonBean.getResult().get(0).getId());
Log.d(TAG, "【】【merchant_id】【】" + jsonBean.getResult().get(0).getMerchant_id());
Log.d(TAG, "【】【merchant_name】【】" + jsonBean.getResult().get(0).getMerchant_name());
Log.d(TAG, "【】【city】【】" + jsonBean.getResult().get(0).getCity());
Log.d(TAG, "【】【area】【】" + jsonBean.getResult().get(0).getArea());
Log.d(TAG, "【】【address】【】" + jsonBean.getResult().get(0).getAddress());
Log.d(TAG, "【】【lat】【】" + jsonBean.getResult().get(0).getLat());
Log.d(TAG, "【】【lng】【】" + jsonBean.getResult().get(0).getLng());
Log.d(TAG, "【】【addTime】【】" + jsonBean.getResult().get(0).getAddTime());
Log.d(TAG, "【】【dlat】【】" + jsonBean.getResult().get(0).getDlat());
Log.d(TAG, "【】【dlng】【】" + jsonBean.getResult().get(0).getDlng());
Log.d(TAG, "【】【wificode】【】" + jsonBean.getResult().get(0).getWificode());
Log.d(TAG, "【】【upstream】【】" + jsonBean.getResult().get(0).getUpstream());
Log.d(TAG, "【】【downstream】【】" + jsonBean.getResult().get(0).getDownstream());
//// This marker can not show at my app screen
LatLng latLng = new LatLng(jsonBean.getResult().get(0).getDlat(), jsonBean.getResult().get(0).getDlng());
Marker marker = googleMap.addMarker(new MarkerOptions().position(latLng)
.title("This is Test Marker")
);
}
#Override
public void onError(Exception e) {
}
});
}
public class HttpUtil {
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
new Thread(new Runnable() {
#Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
String s1 = "lat";
String s2 = "24.9992666";
String s3 = "lng";
String s4 = "121.5082287";
RequestBody requestBody = new FormBody.Builder()
.add(s1, s2)
.add(s3, s4)
.build();
Request request = new Request.Builder()
.url(address)
.post(requestBody) //post
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
if (listener != null) {
// onFinish() method
listener.onFinish(responseData);
}
} catch (Exception e) {
if (listener != null) {
// onError() method
listener.onError(e);
}
}
}
}).start();
}
}
Is the map shoiwing up? What is inside your
getLocation();
function, if there is not something like the following, then add it
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Also remember to zoom in and out and pan the map around, may be the marker is plotted where you did not expect it to be.
if it still does not work, follow this tutorial, it must work.
google maps with marker
Are you sure you're getting the right value from the json? It may be returning a string. You might want to try converting it to the valueOf to get the desired type.
For a double it would be something like:
double lat = Double.valueOf(jsonBean.getResult().get(0).getDlat());

Unable to plot marker on the map using json

The marker is not showing on the map, json data is totally fine and i can see that while debugging.but marker is not showing on the map
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
public GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
public void onMapSearch (View view) throws IOException {
//hide button when button is pressed
InputMethodManager inputManager = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//preview the entered address as an Tost in bar
EditText locationSearch = (EditText) findViewById(R.id.editText);
String location = locationSearch.getText().toString();
//this will animate camera and zoom 12.0f
mMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
//further address search codes
List<Address> addressList = null;
//if nothing will be entered in the edit-text will not show a toast rather than crashing of thekha app
if (locationSearch.getText().toString().equals("")){
Toast.makeText(this,"Bitch please enter A Value",Toast.LENGTH_LONG).show();
}
else {
//process of exception handling and finding location
if (location != null || !location.equals("")) {
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location, 1);
} catch (IOException e) {
e.printStackTrace();
}
//if address is greater than one then these processes will happen
if(addressList.size()>0) {
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions()
.position(latLng)
.title(location + " is Here- ")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
Toast.makeText(this, location+" is here, Zoom In or Zoom Out to make your Thekha Visible ", Toast.LENGTH_LONG)
.show(); //popup type to show entered data
}
else {
//process where entered entry will not gonna find , this will gonna a toast to show popup
Toast.makeText(this,"Entered Address Not Found", Toast.LENGTH_LONG).show();
}
}
}
}
private class RetriveMarkerTask extends AsyncTask<StringBuilder,Void,StringBuilder> {
private Context context;
private String jsonData;
public RetriveMarkerTask(Context context) {
this.context = context;
}
#Override
protected StringBuilder doInBackground(StringBuilder... stringBuilders) {
android.os.Debug.waitForDebugger();
HttpURLConnection conn = null;
final StringBuilder json = new StringBuilder();
try {
//connect to the web service
URL url = new URL("http://www.loofre.com/api-for-webservice/?debug=true&action=getLocations");
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
//This will read the json data into string builder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
json.append(buff, 0, read);
}
this.jsonData = new String(buff);
} catch (IOException e) {
return null;
} catch (Exception ex) {
return null;
} finally {
if (conn != null) {
conn.disconnect();
}
return json;
}
}
#Override
protected void onPostExecute(StringBuilder stringBuilder) {
super.onPostExecute(stringBuilder);
try {
((MapsActivity)context).createMarkerFromJson(this.jsonData);
}catch (JSONException e){
e.printStackTrace();
}
}
}
void createMarkerFromJson (String json) throws JSONException {
// de-derialize the json string into an array of objects
JSONArray jsonArray = new JSONArray(json);
for (int i =0; i<jsonArray.length(); i++){
//create marker of each place in the json data
JSONObject jsonObject = jsonArray.getJSONObject(i);
String placeName = jsonObject.getString("name");
String placeAddress = jsonObject.getString("address");
double latitude = jsonObject.getJSONArray("latlang").getDouble(0);
double longitude = jsonObject.getJSONArray("latlang").getDouble(1);
LatLng loc = new LatLng(latitude, longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(loc, 13));
mMap.addMarker(new MarkerOptions()
.title(placeName)
.snippet(placeAddress)
.position(loc)
);
}
}
//OnReady map starts here when we can enter or add Marker to the map
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
try {
RetriveMarkerTask markerTask = new RetriveMarkerTask(this);
markerTask.execute();
}catch (Exception e){
Toast.makeText(this,"Can not fetch data",Toast.LENGTH_LONG).show();
}
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
//tool bar and other tool related on map uiSettings
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setMapToolbarEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
}
}
Instead of passing the context to your task and then casting the context back to call a function, why not just pass the mMap in your constructor and then move your createMarkerFromJson function inside of your AsyncTask class. If the Json data coming back is correct, this will help us verify that your marker is being added to the correct thing. Does your call to moveCamera occur?

Android Studio unable to plot marker using json

I am trying to plot marker using json in which marker is not showing.here is my code of map activity.
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
public GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
public void onMapSearch (View view) throws IOException {
//hide button when button is pressed
InputMethodManager inputManager = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//preview the entered address as an Tost in bar
EditText locationSearch = (EditText) findViewById(R.id.editText);
String location = locationSearch.getText().toString();
//this will animate camera and zoom 12.0f
mMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
//further address search codes
List<Address> addressList = null;
//if nothing will be entered in the edit-text will not show a toast rather than crashing of thekha app
if (locationSearch.getText().toString().equals("")){
Toast.makeText(this,"Bitch please enter A Value",Toast.LENGTH_LONG).show();
}
else {
//process of exception handling and finding location
if (location != null || !location.equals("")) {
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location, 1);
} catch (IOException e) {
e.printStackTrace();
}
//if address is greater than one then these processes will happen
if(addressList.size()>0) {
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions()
.position(latLng)
.title(location + " is Here- ")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
Toast.makeText(this, location+" is here, Zoom In or Zoom Out to make your Thekha Visible ", Toast.LENGTH_LONG)
.show(); //popup type to show entered data
}
else {
//process where entered entry will not gonna find , this will gonna a toast to show popup
Toast.makeText(this,"Entered Address Not Found", Toast.LENGTH_LONG).show();
}
}
}
}
private void setUpMap (){
final MapsActivity that = this;
new Thread(new Runnable() {
#Override
public void run() {
try {
retriveAndAddMarker();
}catch (IOException e){
Toast.makeText(that,"Can not fetch data",Toast.LENGTH_LONG).show();
}
}
});
}
protected void retriveAndAddMarker () throws IOException {
final MapsActivity that = this;
HttpURLConnection conn = null;
final StringBuilder json = new StringBuilder();
try {
//connect to the web service
URL url = new URL("http://www.loofre.com/api-for-webservice/?debug=true&action=getLocations");
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
//This will read the json data into string builder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
json.append(buff, 0, read);
}
} catch (IOException e) {
Toast.makeText(this, "Error connecting to Service", Toast.LENGTH_LONG).show();
throw new IOException("Error Connecting to service ", e);
} finally {
if (conn != null)
conn.disconnect();
Toast.makeText(this,"Disconnected",Toast.LENGTH_LONG).show();
}
//create marker for the onMapReady over main thekha app
// Must run this on this on the UI thread since its the UI operation.
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Toast.makeText(that, "Connection SuccessFull", Toast.LENGTH_LONG).show();
createMarkerFromJson(json.toString());
}catch (JSONException e){
Toast.makeText(that,"",Toast.LENGTH_LONG).show();
}
}
});
}
void createMarkerFromJson (String json) throws JSONException {
// de-derialize the json string into an array of objects
JSONArray jsonArray = new JSONArray(json);
for (int i =0; i<jsonArray.length(); i++){
//create marker of each place in the json data
JSONObject jsonObject = jsonArray.getJSONObject(i);
mMap.addMarker(new MarkerOptions()
.title(jsonObject.getString("name"))
.snippet(Integer.toString((jsonObject.getInt("address"))))
.position(new LatLng(
jsonObject.getJSONArray("latlang").getDouble(0),
jsonObject.getJSONArray("latlang").getDouble(0)
)
)
);
}
}
//OnReady map starts here when we can enter or add Marker to the map
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
// no 1 marker
LatLng dwarka = new LatLng(28.570317,77.32182);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(dwarka, 13));
mMap.addMarker(new MarkerOptions()
.title("Wine Beer Liquor Shop, Sector 18, Noida")
.snippet("Sector 18, Near Centre Stage Mall, Noida")
.position( dwarka ));
//no 2 marker
LatLng OPG_world_School = new LatLng(28.581074,77.314349);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(OPG_world_School,13));
mMap.addMarker(new MarkerOptions()
.title("Wine Beer Liquor Shop, Sector 15, Noida")
.snippet("Basoya Complex, Sector 15, Near Wipro, Noida")
.position(OPG_world_School));
//no 3 marker
LatLng sector27 = new LatLng(28.581074,77.314349);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sector27,13));
mMap.addMarker(new MarkerOptions()
.title("Wine Beer Liquor Shop, sector 27, Noida")
.snippet("Dharam Pali Palace, Sector 27, Near Vinayak Hospital, Noida")
.position(sector27));
//no 4 marker
LatLng gurgramamb = new LatLng(28.504865,77.094588); // tobe edited
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(gurgramamb,13));
mMap.addMarker(new MarkerOptions()
.title("Discovery Wines")
.snippet("Discovery Wines, Ambience Mall, Gurgaon")
.position(gurgramamb));
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
//tool bar and other tool related on map uiSettings
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setMapToolbarEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
}
}
Your issue is on retriveAndAddMarker. You're making a call using network thread that supposed to be run using AsyncTask.
Network operations can involve unpredictable delays. To prevent this from causing a poor user experience, always perform network operations on a separate thread from the UI. The AsyncTask class provides one of the simplest ways to fire off a new task from the UI thread - Android Developers [Perform Network Operations on a Separate Thread]
You can try adding this snippet:
private class RetrieveMarkerTask extends AsyncTask<StringBuilder, Void, StringBuilder> {
private Context context;
public RetrieveMarkerTask(Context context){
this.context = context;
}
#Override
protected StringBuilder doInBackground(StringBuilder... stringBuilders) {
HttpURLConnection conn = null;
final StringBuilder json = new StringBuilder();
try {
//connect to the web service
URL url = new URL("http://www.loofre.com/api-for-webservice/?debug=true&action=getLocations");
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
//This will read the json data into string builder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
json.append(buff, 0, read);
}
} catch (IOException e) {
return null;
} finally {
if (conn != null)
conn.disconnect();
}
return json;
}
#Override
protected void onPostExecute(StringBuilder stringBuilder) {
super.onPostExecute(stringBuilder);
if(null != stringBuilder){
try {
((MapsActivity)context).createMarkerFromJson(stringBuilder.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
And in your retriveAndAddMarker(), remove all those lines inside this method and replace with line below.
protected void retriveAndAddMarker (){
//remove all the previous code
new RetrieveMarkerTask(this).execute();
}
Note:
I simply created the AsyncTask based on your code, so I am not sure if it is working or not. You need to debug it on your own.

Every 1 Minute Gps LatLong Getting From Server Showing In Map as Marker. But Marker Geting Duplicating

1.In My app Gps LatLong is Getting from Server Every OneMinute. Saved in Shared Pref ,then getting the LatLong From shared pref Showing the Marker on the Map.
2.Every One Minute I want to Move the Marker based on the LatLong.
3.But While Changing the Marker Location. Getting Duplicates.
Please Help me to Solve this Issue.
Inside Oncreate method i Called below Snippet in Every 60 Secs for Calling a Method.
try
{
Thread t = new Thread()
{
#Override
public void run()
{
try
{
while (!isInterrupted())
{
Thread.sleep(60*1000);
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
display_Location();
Log.i("Every 60 Second","Current Called..");
}
});
}
} catch (Exception e)
{
e.printStackTrace();
}
}
};
t.start();
}
catch (Exception e)
{
e.printStackTrace();
}
Method Iam USing:
private void display_Location()
{
try
{
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null)
{
/*For Current Location ping Starts Here*/
// get user data from session
HashMap<String, String> user = session.getGPSPING();
// UserLat
String LatLongUser = "";
LatLongUser = user.get(SessionManagerFor_Register.KEY_LATLONG);
if (!LatLongUser.equals("") || LatLongUser != null)
{
Log.i(" PING on MAP LatLong", LatLongUser);
String[] LanlongArr = LatLongUser.split("//");
List<String> Lanlonglist1 = Arrays.asList(LanlongArr);
int length = Lanlonglist1.size();
/*ArrayList For adding All ArrayList items in Single(Concating)*/
arraylist_DetailLineWalker = new ArrayList<String>(length);
for (int i = 0; i < length; i++) {
arraylist_DetailLineWalker.add(Lanlonglist1.get(i)
);
}
if (arraylist_DetailLineWalker != null)
{
// Initializing
LineWalkermMarkers_arr = new ArrayList<Marker>();
// just Remove Older Line Wlaker
if (LineWalkermMarkers_arr != null) {
// LineWalker_marker1.remove();
RemoveLineWalkerMarkers();
Log.i(TAG, "LineWalker REMOVED.............................");
}
for (int i = 0; i < arraylist_DetailLineWalker.size(); i++)
{
try
{
String Val = arraylist_DetailLineWalker.get(i).toString();
//Log.i(" Validation Id",Val);
VALUE_ARRAY_STRING = Val.toString().split("::");
LatLong_DataSaveTable = VALUE_ARRAY_STRING[0].toString();
System.out.println("checking STarted LatLong::" + LatLong_DataSaveTable);
String[] latlong = LatLong_DataSaveTable.split(",");
double latitude1 = Double.parseDouble(latlong[0]);
double longitude2 = Double.parseDouble(latlong[1]);
//To hold location
LatLng latLng1 = new LatLng(latitude1, longitude2);
//To create marker in map
MarkerOptions markerOptionsLineWalker = new MarkerOptions();
markerOptionsLineWalker.position(latLng1); //setting position
markerOptionsLineWalker.draggable(true); //Making the marker draggable
markerOptionsLineWalker.title("USER LOCAITON");
markerOptionsLineWalker.icon(BitmapDescriptorFactory.fromResource(R.drawable.walker_outof_fence_icon_red));
//adding marker to the map
// googleMap.addMarker(markerOptionsLineWalker);
LineWalker_marker1 = googleMap.addMarker(markerOptionsLineWalker);
LineWalkermMarkers_arr.add(LineWalker_marker1);
// LineWalker_marker1.setPosition(latLng1);
Log.i(TAG, " NEW Line Walkers PING Added.............................");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
} else {
Log.i("MAP NEwLatLong", "TOTAL ARRY LIST NULLL");
}
}
else
{
Log.i("MAP NEwLatLong", "Null Not LatLong");
Toast.makeText(getActivity(), "Lat Long Not Available..!", Toast.LENGTH_SHORT).show();
}
}
else
{
Log.i("Location EXception", "Couldn't get the location. Make sure location is enabled on the device");
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/*Remove the Linewalker*/
private void RemoveLineWalkerMarkers()
{
for (Marker marker: LineWalkermMarkers_arr)
{
marker.remove();
}
LineWalkermMarkers_arr.clear();
}
if(arraylist_DetailLineWalker != null && arraylist_DetailLineWalker.size()>0){
arraylist_DetailLineWalker.clear()
mMap.clear();
showMarker();
}
You are calling RemoveLineWalkerMarkers() after initializing LineWalkermMarkers_arr doing LineWalkermMarkers_arr = new ArrayList<Marker>();, so you are never removing your markers.
Just initialize your LineWalkermMarkers_arr after removing the markers:
if (LineWalkermMarkers_arr != null) {
RemoveLineWalkerMarkers();
Log.i(TAG, "LineWalker REMOVED.............................");
}
LineWalkermMarkers_arr = new ArrayList<Marker>();
As a side note, you should follow the Java code conventions (variables and method names should start with lowercase). You can find good guides here and here
Solution is just a logic change
Initialize Marker only once , either onCreate or some other method according to your logic
If the markers are multiple, then re-initialization should be done once data is received.
Created markers can be cleared with below logic
if(mGoogleMap != null) {
mGoogleMap.clear();
}
Either reuse this marker to move from last location to new location. Or recreate all the markers, once data is received
//With your logic , this check should be done
if(arraylist_DetailLineWalker.size()>0){
RemoveLineWalkerMarkers();
}
LineWalkermMarkers_arr = new ArrayList<Marker>();
for (int i = 0; i < arraylist_DetailLineWalker.size(); i++)
{
}
Alternative easy method to move single marker , to show live driving direction kind of feature
private Marker mCurrentMarker;
private float ZOOMLEVEL=18.0f;
private LatLng previousLatLon;
private Handler mLocalHandler;
private GoogleMap mGoogleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocalHandler = new Handler();
previousLatLon=new LatLng(45.320372, 2.460161);
//Initialize Marker once Google Map object is created
mMarkerOptions = new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.custom_marker_icon));
mMarkerOptions.position(previousLatLon);
mCurrentMarker = mGoogleMap.addMarker(mMarkerOptions);
}
/**
* Call this method to move marker in map to new location in map with updated location
* #param marker
* #param toPosition
* #param fromPosition
*/
public void animateMarker(final Marker marker, final LatLng toPosition,final LatLng fromPosition) {
final long duration = 500;
final Interpolator interpolator = new LinearInterpolator();
mLocalHandler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - mStartTime;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
marker.setPosition(toPosition);
marker.setAnchor(Constants.MAPANCHOR, Constants.MAPANCHOR);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(toPosition, ZOOMLEVEL));
if (t < 1.0) {
// Post again 16ms later.
mLocalHandler.postDelayed(this, 16);
} else {
marker.setVisible(true);
}
}
}
});
previousLatLon=toPosition;// reassign the previous location to current location
}

Categories

Resources