I have following code (I know that some of that may be redundant, if yes, please let me know). What I can't do is to stop the invoking updating the location again and again. I tried some different ways where to stop it (they are present in the code but commented). Sometimes i get
java.lang.RuntimeException: Unable to start activity ComponentInfo{jangcy.emergency/jangcy.emergency.ReportStartActivity}: java.lang.IllegalArgumentException: invalid listener: null
and sometimes
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)' on a null object reference
If I try to stop it with some int (like is done now), it doesn't really stop. If I remove the if, it stops before it sends location to DB.
Any help please?
package jangcy.emergency;
import android.*;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class ReportStartActivity extends AppCompatActivity {
private String user;
TextView textView;
private double latitude = 500;
private double longitude = 500;
double old_longitude = 499;
double old_latitude = 499;
LocationManager locationManager;
LocationListener locationListener;
SharedPreferences sharedPref;
private int idZgloszenia;
public int counter = 0;
private static final String url_start_report = "http://192.168.0.12:80/emergency/start_report.php";
private StringRequest request;
private RequestQueue requestQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_start);
requestQueue = Volley.newRequestQueue(this);
textView = (TextView) findViewById(R.id.testTextView);
textView.setText("jangcy");
sharedPref = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
user = sharedPref.getString("loginKey", null);
int ik = geoLocation();
if (ik == 5){
locationManager.removeUpdates(locationListener);
locationManager = null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
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) {
requestPermissions(new String[]{
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.INTERNET
}, 10);
return;
}
} else {
//configureButton();
}
}
public int geoLocation()
{
final int[] do_zwrotu = new int[1];
textView.setText(String.valueOf(counter));
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
textView.setText(String.valueOf(longitude) + " " + String.valueOf(latitude));
if (longitude >= -180 && longitude <= 180 && latitude >= -90 && latitude <= 90) {
do_zwrotu[0] = 5;
textView.setText(String.valueOf(longitude) + " " + String.valueOf(latitude) + user);
startReport(user, longitude, latitude);
/*locationManager.removeUpdates(locationListener);
locationManager = null;*/
/*locationManager.removeUpdates(this);
locationManager = null;*/
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent in = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(in);
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
return do_zwrotu[0];
}
private void startReport(final String user, final double longitude, final double latitude) {
request = new StringRequest(Request.Method.POST, url_start_report, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
System.out.println(response);
JSONObject jsonObject = new JSONObject(response);
int success = jsonObject.getInt("success");
if (success == 1) {
/*
locationManager.removeUpdates(locationListener);
locationManager = null;*/
Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
//idZgloszenia = jsonObject.getInt("id_zgloszenia");
//textView.setText(idZgloszenia);
} else {
Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("gps_x", Double.toString(longitude));
hashMap.put("gps_y", Double.toString(latitude));
hashMap.put("uzytkownik", user);
return hashMap;
}
};
requestQueue.add(request);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
//configureButton();
return;
}
}
private void configureButton() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
textView.setText("jangcy2");
}
}
Related
I'm using the location manager to find my location, but when I simulate with an api greater than 18, I can not find the location
package br.com.josileudorodrigues.myapplication;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.cocoahero.android.geojson.GeoJSON;
import org.osmdroid.bonuspack.kml.KmlDocument;
import org.osmdroid.bonuspack.location.NominatimPOIProvider;
import org.osmdroid.bonuspack.location.POI;
import org.osmdroid.config.Configuration;
import org.osmdroid.events.MapEventsReceiver;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.FolderOverlay;
import org.osmdroid.views.overlay.MapEventsOverlay;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.PathOverlay;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.infowindow.InfoWindow;
import org.osmdroid.views.overlay.infowindow.MarkerInfoWindow;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
import java.util.ArrayList;
import static android.os.Build.VERSION_CODES.M;
public class MainActivity extends AppCompatActivity implements MapEventsReceiver, LocationListener {
private static final int PERMISSAO_REQUERIDA =1 ;
private MapView osm;
private MapController mc;
private LocationManager locationManager;
private PathOverlay po;
private KmlDocument kmlDocument;
ArrayList<OverlayItem> overlayItemArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
osm = (MapView) findViewById(R.id.mapaId);
osm.setTileSource(TileSourceFactory.MAPNIK);
osm.setUseDataConnection(true);
osm.setMultiTouchControls(true);
osm.setClickable(true);
osm.setBuiltInZoomControls(true);
if (Build.VERSION.SDK_INT >= M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
String[] permissoes = {Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissoes, PERMISSAO_REQUERIDA);
}
}
osm.setMapListener(new MapListener() {
#Override
public boolean onScroll(ScrollEvent event) {
Log.i("Script()", "onScroll ()");
return true;
}
#Override
public boolean onZoom(ZoomEvent event) {
Log.i("Script()", "onZoom ()");
return false;
}
});
//onde mostra a imagem do mapa
Context ctx = getApplicationContext();
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
mc = (MapController) osm.getController();
mc.setZoom(15);
GeoPoint center = new GeoPoint(-5.1251, -38.3640);
mc.animateTo(center);
addMarker(center);
// here is where the permissions are
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// .
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
MapEventsOverlay mapEventsOverlay = new MapEventsOverlay(this, this);
osm.getOverlays().add(0, mapEventsOverlay);
// Aqui adiciona a escala do mapa
ScaleBarOverlay scaleBarOverlay = new ScaleBarOverlay(osm);
osm.getOverlays().add(scaleBarOverlay);
kmlDocument = new KmlDocument();
// kmlDocument.parseGeoJSON(geoJsonString);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSAO_REQUERIDA: {
// Se a solicitação de permissão foi cancelada o array vem vazio.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permissão cedida, recria a activity para carregar o mapa, só será executado uma vez
this.recreate();
}
}
}
}
public void addMarker(final GeoPoint center) {
final Marker marker = new Marker(osm);
marker.setPosition(center);
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
marker.setIcon(getResources().getDrawable(R.drawable.ic_mapa));
marker.setDraggable(true);
marker.setTitle("DADOS");
marker.setSnippet(center.getLatitude()+ "," + center.getLongitude());
marker.setSubDescription("subDescription Marker");
marker.setInfoWindow(new CustomMarkerInfoWindow(osm));
marker.setInfoWindowAnchor(marker.ANCHOR_CENTER, marker.ANCHOR_TOP);
marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker m, MapView mapView) {
Log.i("Script","onMarkerClick");
m.showInfoWindow();
return true;
}
});
marker.setOnMarkerDragListener(new Marker.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
Log.i("Script", "onMarkerDragStart()");
}
#Override
public void onMarkerDragEnd(Marker marker) {
Log.i("Script", "onMarkerDragEnd()");
}
#Override
public void onMarkerDrag(Marker marker) {
Log.i("Script", "onMarkerDrag()");
}
});
//osm.getOverlays().clear();
osm.getOverlays().add(new MapOverlay(this));
osm.getOverlays().add(marker);
osm.invalidate();
}
#Override
public void onLocationChanged(Location location) {
GeoPoint center = new GeoPoint(location.getLatitude(), location.getLongitude());
mc.animateTo(center);
addMarker(center);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates((LocationListener) this);
}
}
class MapOverlay extends Overlay {
public MapOverlay(Context ctx) {
super(ctx);
}
#Override
public void draw(Canvas c, MapView osmv, boolean shadow) {
}
#Override
public boolean onSingleTapConfirmed(MotionEvent me, MapView mv) {
Projection p = osm.getProjection();
GeoPoint gp = (GeoPoint) p.fromPixels((int) me.getX(), (int) me.getY());
addMarker(gp);
return (true);
}
}
// Aqui quando eu pressionar em uma determinada parte do mapa ele
// irá mostrar as minhas cordenadas
#Override
public boolean singleTapConfirmedHelper(GeoPoint p) {
Toast.makeText(this, "Coordenadas:\nLatitude: ("+p.getLatitude() +"\nLongitude: " +
""+p.getLongitude()+")" , Toast.LENGTH_SHORT).show();
InfoWindow.closeAllInfoWindowsOn(osm); //Clicando em qualquer canto da tela, fecha o infowindow
return (true);
}
#Override
public boolean longPressHelper(GeoPoint p) {
return false;
}
// InfoWindow
public class CustomMarkerInfoWindow extends MarkerInfoWindow {
public CustomMarkerInfoWindow(MapView mapView) {
super(R.layout.bonuspack_bubble,mapView);
}
#Override
public void onOpen(Object item){
Marker m = (Marker) item;
ImageView iv = (ImageView) mView.findViewById(R.id.bubble_image);
iv.setImageResource(R.drawable.btn_moreinfo);
TextView snippet = (TextView) mView.findViewById(R.id.bubble_title);
snippet.setText(m.getTitle());
TextView coordenada = (TextView) mView.findViewById(R.id. coordenadas);
coordenada.setText(m.getSnippet());
Button bt = (Button) mView.findViewById(R.id.bubble_buttom);
bt.setVisibility(View.VISIBLE);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Salvo",Toast.LENGTH_SHORT ).show();
}
});
}
}
}
Image
How would you fix this error?
You need to request GPS permissions from the user on APIs > 21 (i think)
On every gps update, roughly once a second, you are adding a new marker to the map. You'll eventually run out of memory. Consider just updating the marker's location.
See this https://github.com/osmdroid/osmdroid/wiki/How-to-use-the-osmdroid-library#how-to-add-the-my-location-overlay that overlay is a bit easier to use that rolling your own solution, but whatever. Here's a working example of using it https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/location/SampleMyLocationWithClick.java (code is below)
Not all emulators do GPS. Sometimes you have to poke around in the menus to stimulate it. Try to reproduce on hardware. Genymotion works pretty well
Code snippet
final MyLocationOverlayWithClick overlay = new MyLocationOverlayWithClick(mMapView);
overlay.enableFollowLocation();
overlay.enableMyLocation();
mMapView.getOverlayManager().add(overlay);
Finally you can run the sample app from here, https://play.google.com/store/apps/details?id=org.osmdroid or you can get the APK on github. If that doesn't work in your emulator, then the emulator is broken or doesn't support gps
Below is my code and when I am near to this
(distance is less than 100 meter from my current location)
9.443469,76.540650
gps location i need to vibrate my phone , but when i reach there it is not vibrating and it is showing wrong lan and lon. What is wrong in my code?
import android.Manifest;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import androidx.annotation.Nullable;
import io.nlopez.smartlocation.OnLocationUpdatedListener;
import io.nlopez.smartlocation.SmartLocation;
import io.nlopez.smartlocation.location.config.LocationAccuracy;
import io.nlopez.smartlocation.location.config.LocationParams;
public class OfferLocator extends Service {
SmartLocation mSmartLocation;
LocationParams locationParam = null;
double l2 = 9.443469, lo2 = 76.540650, lan = 0, lon = 0;
boolean running = false;
double prelan = 0, prelon = 0;
MyLocationListener locationListener;
int ct = 0;
LocationManager locationManager;
private void info() {
if (locationManager == null) {
locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
}
if (locationListener == null) {
locationListener = new MyLocationListener();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 5, locationListener);
Log.i("OfferLocator_info","info called "+ct+" times lan lon "+lan+","+lon);
ct++;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
info();
}
},10000);
try {
if(locationParam==null) locationParam = new LocationParams.Builder().setAccuracy(LocationAccuracy.HIGH).build();
} catch (Exception e){
Log.i("OfferLocatorv2","error2 :"+e.getMessage()+"");
}
}
#Override
public void onCreate() {
super.onCreate();
Log.d("myLog", "Service: onCreate");
try {
locationParam = new LocationParams.Builder().setAccuracy(LocationAccuracy.HIGH).build();
} catch (Exception e){
Log.i("OfferLocatorv2","error2 :"+e.getMessage()+"");
}
info();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("myLog", "Service: onStartCommand");
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.d("myLog", "Service: onTaskRemoved");
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
if (Build.VERSION.SDK_INT <= 19) {
Intent restart = new Intent(getApplicationContext(), this.getClass());
restart.setPackage(getPackageName());
startService(restart);
}
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
super.onDestroy();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(getApplicationContext(),OfferLocator.class));
} else {
startService(new Intent(getApplicationContext(),OfferLocator.class));
}
Log.d("myLog", "Service: onDestroy");
// unregisterReceiver(batteryReceiver);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class MyLocationListener implements LocationListener {
String TAG="newloc";
#Override
public void onLocationChanged(Location loc) {
// editLocation.setText("");
// pb.setVisibility(View.INVISIBLE);
double l2 = 9.443469, lo2 = 76.540650;
float[] results = new float[1];
Location.distanceBetween( loc.getLatitude(), loc.getLongitude(),l2,lo2, results);
if (results[0]<100) {
Toast.makeText(getApplicationContext(),"vibrate please "+results[0],Toast.LENGTH_SHORT).show();
try {
Vibrator v = (Vibrator) getSystemService(getApplicationContext().VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(1500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(1500);
}
} catch (Exception e){
Log.i("OfferLocatorv2","error4 :"+e.getMessage()+"");
}
} else {
if (results[0]>500) {
try {
Vibrator v = (Vibrator) getSystemService(getApplicationContext().VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(1500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(1500);
}
}catch (Exception e){
Log.i("OfferLocatorv2","error4 :"+e.getMessage()+"");
}
}
Toast.makeText(getApplicationContext(),"my current location is "+results[0],Toast.LENGTH_SHORT).show();
}
String longitude = "Longitude: " + loc.getLongitude();
Log.v(TAG, longitude);
String latitude = "Latitude: " + loc.getLatitude();
Log.v(TAG, latitude);
/*------- To get city name from coordinates -------- */
String cityName = null;
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
List<Address> addresses;
try {
addresses = gcd.getFromLocation(loc.getLatitude(),
loc.getLongitude(), 1);
if (addresses.size() > 0) {
System.out.println(addresses.get(0).getLocality());
cityName = addresses.get(0).getLocality();
}
} catch (IOException e) {
e.printStackTrace();
}
String s = longitude + "\n" + latitude + "\n\nMy Current City is: " + cityName;
// editLocation.setText(s);
}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
}
If you have taken the coordinates from google map they can be slightly different from those obtained from the same position through the MapsActivity. Try to take the coordinates of the point where you want the phone to vibrate through another application with a MapsActivity that simply give you with the coordinates of your position.
So basically I am making an app in which I would get an SMS which will contain a latitude and longitude from which I need to add a new marker on the map. But I am unable to do so as I cannot add marker outside the onMapReady function. Any suggestion on how to add marker outside the onMapReady function?
the maps activity is as follow
package com.example.rajen.railwaycrackk;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
boolean sms_Perm=true;
private GoogleMap mMap;
boolean mapstart=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (ContextCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, Manifest.permission.RECEIVE_SMS)) {
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.RECEIVE_SMS}, 1);
} else {
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.RECEIVE_SMS}, 1);
}
}
// 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);
if (mMap!=null) {
// GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
// .getMap();
Log.d("1", "entered into truee");
this.mMap.addMarker(new MarkerOptions()
.position(new LatLng(10, 10))
.title("Hello world"));
}
}
#Override
public void onRequestPermissionsResult(int requestcode, String[] permissions, int[] grantResults) {
switch (requestcode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
sms_Perm = true;
}
} else {
Toast.makeText(this, "No permission granted", Toast.LENGTH_SHORT).show();
sms_Perm = false;
}
}
}
}
public void onMapReady(GoogleMap googleMap) {
this.mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(20.5937, 78.9629);
this.mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
this.mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mapstart=true;
SmsReceiver myMapReceiver = new SmsReceiver(googleMap);
IntentFilter filter = new IntentFilter(SmsReceiver.ADD_MARKER);
filter.addCategory(Intent.CATEGORY_DEFAULT);
LocalBroadcastManager.getInstance(this).registerReceiver(myMapReceiver, filter);
}
public String LoadInt(String key){
String savedValue;
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
savedValue = sharedPreferences.getString(key,null);
return savedValue;
}
}
My SMS broadcast receiver is as follows
package com.example.rajen.railwaycrackk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
/**
* Created by rajen on 29-01-2018.
*/
public class SmsReceiver extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public static final String ADD_MARKER = "some.unique.string.ADD_MARKER";
private GoogleMap mMap;
public SmsReceiver (GoogleMap mMap) {
this.mMap = mMap;
}
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
if (intent.getAction().compareTo(ADD_MARKER) == 0) {
double lat = intent.getDoubleExtra("lat", 0);
double lng = intent.getDoubleExtra("lng", 0);
}
// do something with map using lat/lng
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context,
"senderNum: " + senderNum + ", message: " + message, duration);
toast.show();
// LatLng position = new LatLng(20.5937, 78.9629);
// MapsActivity.plotOnMap(position);
} // end for loop
} // bundle is null
Intent broadcastIntent = new Intent();
// get 'lat' and 'lng' from message
broadcastIntent.setAction(SmsReceiver.ADD_MARKER);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra("lat", 10);
broadcastIntent.putExtra("lng", 10);
LocalBroadcastManager.getInstance(context.getApplicationContext()).sendBroadcast(broadcastIntent);
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
}
}
}
Use a broadcast receiver attached to your map activity....
Create a BroadcastReceiver subclass as follows:
public class MapRequestReceiver extends BroadcastReceiver {
public static final String ADD_MARKER = "some.unique.string.ADD_MARKER";
private GoogleMap mMap;
public MapRequestReceiver (GoogleMap mMap) {
this.mMap = mMap;
}
public void onReceive(Context context, Intent intent) {
if (intent.getAction().compareTo(ADD_MARKER) == 0) {
double lat = intent.getDoubleExtra("lat", 0);
double lng = intent.getDoubleExtra("lng", 0);
// do something with map using lat/lng
}
}
}
In your map activity 'onMapReady' register the local broadcast receiver:
public void onMapReady(GoogleMap googleMap) {
// ... other stuff...
// check if it already exists in which case do nothing or
// unregister it first using LocalBroadcastManager.
MapRequestReceiver myMapReceiver = new MapRequestsReceiver(googleMap);
IntentFilter filter = new IntentFilter(MapRequestReceiver.ADD_MARKER);
filter.addCategory(Intent.CATEGORY_DEFAULT);
LocalBroadcastManager.getInstance(this).registerReceiver(myMapReceiver, filter);
}
... and where you receive the SMS:
Intent broadcastIntent = new Intent();
// get 'lat' and 'lng' from message
broadcastIntent.setAction(MapRequestsReceiver.ADD_MARKER);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra("lat", lat);
broadcastIntent.putExtra("lng", lng);
LocalBroadcastManager.getInstance( getApplicationContext() ).sendBroadcast(broadcastIntent);
You may find you'll want to do more things than ADD_MARKER so just update MapRequestReceiver with more actions (strings) and update 'onReceive'.
I'm in a process of writing a tracking map. In a method getDeviceLocation I want to assign:
prevLat=mLastKnownLocation.getLatitude();
prevLng=mLastKnownLocation.getLongitude();
but it crashes the app. I want to assign it for later us in distanceBetween() to get a distance after every location change. When closing the activity by killApp() it should sum up all the distances and give me a total. It also crashes the app so it's been commented.
Whole activity:
package com.example.micha.aplikacjatreningowa;
import android.Manifest;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.support.v4.app.DialogFragment;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import static android.location.Location.distanceBetween;
import static java.lang.Math.pow;
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback, com.google.android.gms.location.LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = MapActivity.class.getSimpleName();
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private CameraPosition mCameraPosition;
private static final int DEFAULT_ZOOM = 20;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted = false;
private Location mLastKnownLocation;
private static final String KEY_CAMERA_POSITION = "camera_position";
private static final String KEY_LOCATION = "location";
private static final int UPDATE_INTERVAL = 1000;
private static final int FASTEST_INTERVAL = 500;
private static final int DISPLACEMENT = 1;
public double prevLat;
public double prevLng;
float totalDistance;
float[] distance;
float[] cBurned;
Float totalCalories;
public Button End;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Ustalanie mapy
setContentView(R.layout.activity_map);
//Budowanie klienta API do użytku w wyznaczaniu położenia
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
createLocationRequest();
endButton();
}
//Zapisuje stan aplikacji
protected void onSaveInstanceState(Bundle outState) {
if (mMap != null) {
outState.putParcelable(KEY_CAMERA_POSITION, mMap.getCameraPosition());
outState.putParcelable(KEY_LOCATION, mLastKnownLocation);
super.onSaveInstanceState(outState);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
//Gdy połączenie się nie uda
public void onConnectionFailed(#NonNull ConnectionResult result) {
Log.d(TAG, "Połączenie nieudane: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
//Gdy połączenie zostanie wstrzymane
public void onConnectionSuspended() {
Log.d(TAG, "Połączenie wstrzymane");
}
//Pobieranie lokacji użytkownika
private void getDeviceLocation() {
//Prośba o pozwolenie na zczytanie lokacji urządzenia
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
//Pobranie lokacji urządzenia
if (mLocationPermissionGranted) {
mLastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastKnownLocation != null) {
prevLat=mLastKnownLocation.getLatitude();
prevLng=mLastKnownLocation.getLongitude();
}
}
moveCamera();
}
//Po otrzymaniu pozwolenia
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
//Gdy mapa jest już gotowa
#Override
public void onMapReady(GoogleMap map) {
mMap=map;
updateLocationUI();
getDeviceLocation();
startLocationUpdates();
}
private void updateLocationUI() {
if (mMap == null) {
return;
}
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
if (mLocationPermissionGranted) {
mMap.setMyLocationEnabled(true);
} else {
mMap.setMyLocationEnabled(false);
mLastKnownLocation = null;
}
}
protected void startLocationUpdates() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
moveCamera();
float velocity = location.getSpeed();
float caloriesBurned;
String extra = getIntent().getStringExtra("EXTRA_MODE_TYPE");
switch (extra) {
case"walk": {
distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
prevLat=location.getLatitude();
prevLng=location.getLongitude();
double dbcaloriesBurned =(0.0215*pow(velocity*3600/1000, 3)-0.1765*pow(velocity*3600/1000, 2)+0.8710* + 1.4577*velocity*3600/1000);
caloriesBurned = (float)dbcaloriesBurned;
int count = 0;
cBurned[count] = caloriesBurned;
count++;
if (velocity > 2) {
killApp();
}
break;
}
case "run": {
distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
prevLat = location.getLatitude();
prevLng = location.getLongitude();
double dbcaloriesBurned = (0.0215 * pow(velocity * 3600 / 1000, 3) - 0.1765 * pow(velocity * 3600 / 1000, 2) + 0.8710 * +1.4577 * velocity * 3600 / 1000);
caloriesBurned = (float) dbcaloriesBurned;
int count = 0;
cBurned[count] = caloriesBurned;
count++;
if (velocity > 3) {
killApp();
}
break;
}
case "ride": {
distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
prevLat = location.getLatitude();
prevLng = location.getLongitude();
double dbcaloriesBurned = (0.0215 * pow(velocity * 3600 / 1000, 3) - 0.1765 * pow(velocity * 3600 / 1000, 2) + 0.8710 * +1.4577 * velocity * 3600 / 1000);
caloriesBurned = (float) dbcaloriesBurned;
int count = 0;
cBurned[count] = caloriesBurned;
count++;
if (velocity > 5) {
killApp();
}
break;
}
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
public void endButton(){
End = (Button)findViewById(R.id.End);
End.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
killApp();
}
});
}
public void moveCamera() {
if (mCameraPosition != null) {
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
} else if (mLastKnownLocation != null) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
}
}
public void killApp() {
stopLocationUpdates();
/*for(int i=0; i<=distance.length; i++) {
totalDistance += distance[i];
}
for(int j=0; j<cBurned.length; j++) {
totalCalories += cBurned[j];
}*/
AlertDialog.Builder builder = new AlertDialog.Builder(MapActivity.this);
builder.setMessage("Koniec treningu!\nPrzebiegłeś: " + totalDistance +" metrów.\nSpaliłeś: " + totalCalories +" kalorii.")
.setCancelable(false)
.setPositiveButton("Zakończ", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.create().show();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
#Override
public void onConnectionSuspended(int i) {
}
}
Edit:
Crash log:
--------- beginning of crash
05-24 22:16:57.509 2930-2930/com.example.micha.aplikacjatreningowa E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.micha.aplikacjatreningowa, PID: 2930
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.google.android.gms.internal.zzase$zza$zza.zza(Unknown Source)
at com.google.android.gms.internal.zzasg.zza(Unknown Source)
at com.google.android.gms.internal.zzash.zza(Unknown Source)
at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
at com.google.android.gms.internal.zzaad$zza.zzb(Unknown Source)
at com.google.android.gms.internal.zzaaq.zze(Unknown Source)
at com.google.android.gms.internal.zzaaq.zzb(Unknown Source)
at com.google.android.gms.internal.zzaav.zzb(Unknown Source)
at com.google.android.gms.internal.zzaat.zzb(Unknown Source)
at com.google.android.gms.internal.zzary.requestLocationUpdates(Unknown Source)
at com.example.micha.aplikacjatreningowa.MapActivity.startLocationUpdates(MapActivity.java:187)
at com.example.micha.aplikacjatreningowa.MapActivity.onMapReady(MapActivity.java:156)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.maps.internal.bw.a(:com.google.android.gms.DynamiteModulesB:82)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.DynamiteModulesB:1805)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Edit 2: App crashes because of startLocationUpdates() method
You are not handling android runtime permissions correctly, because you are requesting permission when condition
Manifest.permission.ACCESS_FINE_LOCATION == PackageManager.PERMISSION_GRANTED is true. Check your code one more time.
You should do something like this:
String permission = Manifest.permission.ACCESS_FINE_LOCATION;
if (!isPermissionGranted(permission)) {
if (isRationaleExplanationNeeded(permission)) {
//show dialog to explain why you need permission
} else {
ActivityCompat.requestPermissions(this, new String[]{permission},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
} else {
//do what ever you need to do
}
I assume that you are getting security exception because of not allowed permission.
Functions called above:
private boolean isPermissionGranted(String permission) {
int hasRequestedPermission = ContextCompat.checkSelfPermission(this, permission);
return hasRequestedPermission == PackageManager.PERMISSION_GRANTED;
}
private boolean isRationaleExplanationNeeded(String permission) {
return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
}
The loop inside the retrofitResponse method does not loops which it was suppose to do. It was suppose to fetch json data from google map url.
package com.webstarts.byteglory.shomadhan;
import android.*;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.location.Location;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.webstarts.byteglory.shomadhan.POJO.Example;
import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
public class StartActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener, com.google.android.gms.location.LocationListener, OnMapReadyCallback {
protected GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
protected static final String TAG = "Location Services Test";
private Button search_location_button;
private Button search_area_button;
private Button toilet_status_button;
protected LatLng latlng;
protected LocationRequest mLocationRequest;
private GoogleMap mMap;
private int PROXIMITY_RADIUS = 10000;
Marker mCurrLocationMarker;
boolean mapReady = false;
private Marker mPerth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
search_location_button = (Button) findViewById(R.id.search_location_button);
search_area_button = (Button) findViewById(R.id.search_area_button);
toilet_status_button = (Button) findViewById(R.id.toilet_status_button);
locationApiClient();
// SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
// .findFragmentById(R.id.map);
// mapFragment.getMapAsync(this);
search_location_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Log.i(TAG, String.valueOf(latlng.latitude));
// Uri gmmIntentUri = Uri.parse("geo:"+String.valueOf(latlng.latitude)+","+String.valueOf(latlng.longitude)+"?z=15&q=public toilets");
// Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
// mapIntent.setPackage("com.google.android.apps.maps");
// startActivity(mapIntent);
retrofitResponse();
// Marker loc = mMap.addMarker(new MarkerOptions().position(latlng)
// .title("You are here now 23"));
// mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
//
// // Zoom in, animating the camera.
// mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
// Log.i(TAG, String.valueOf(latlng.latitude));
}
});
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
protected synchronized void locationApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
// Provides a simple way of getting a device's location and is well suited for
// applications that do not require a fine-grained location and that do not need location
// updates. Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000);
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null) {
latlng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
}
else {
Toast toast = Toast.makeText(this, "Turn on your location service", Toast.LENGTH_LONG);
toast.show();
finish();
}
}
public void onLocationChanged(Location location) {
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
/*
* Called by Google Play services if the connection to GoogleApiClient drops because of an
* error.
*/
public void onDisconnected() {
Log.i(TAG, "Disconnected");
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
private void retrofitResponse() {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getNearbyPlaces("restaurents", latlng.latitude + "," + latlng.longitude, PROXIMITY_RADIUS);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
mMap.clear();
// This loop will go through all the results and add marker on each location.
Log.i("ishan", String.valueOf(response.body().getResults().size()));
for (int i = 0; i < response.body().getResults().size(); i++) {
Double lat = response.body().getResults().get(i).getGeometry().getLocation().getLat();
Double lng = response.body().getResults().get(i).getGeometry().getLocation().getLng();
String placeName = response.body().getResults().get(i).getName();
String vicinity = response.body().getResults().get(i).getVicinity();
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(lat, lng);
// Position of Marker on Map
markerOptions.position(latLng);
// Adding Title to the Marker
markerOptions.title(placeName + " : " + vicinity);
// Adding Marker to the Camera.
Marker m = mMap.addMarker(markerOptions);
// Adding colour to the marker
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
// move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
Log.i("ishan", String.valueOf(i));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
#Override
public void onMapReady(GoogleMap map) {
mapReady=true;
mMap = map;
// //Initialize Google Play Services
// if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// if (ContextCompat.checkSelfPermission(this,
// android.Manifest.permission.ACCESS_FINE_LOCATION)
// == PackageManager.PERMISSION_GRANTED) {
// }
// }
}
}
This is the interface of the retrofit. It has just the GET as it just reads data from map url.
package com.webstarts.byteglory.shomadhan;
import com.webstarts.byteglory.shomadhan.POJO.Example;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
public interface RetrofitMaps {
/*
* Retrofit get annotation with our URL
* And our method that will return us details of student.
*/
#GET("api/place/nearbysearch/json?sensor=true&key=AIzaSyABCGHHSFDGSDsdfGADFnM")
Call<Example> getNearbyPlaces(#Query("type") String type, #Query("location") String location, #Query("radius") int radius);
}
I have just looped inside the onResponse retrofit function like this:
public void onResponse(Call call, Response response) {
/* implement the toast */
/* =new ArrayList<User>(); */
ArrayList<User> test;
test=response.body().getUsers();
String jax= test.get(0).getFarm_name();
//Toast.makeText(MarkerDemoActivity.this, "farm name is "+jax, Toast.LENGTH_LONG).show();
//LatLng m_cord,String farm_name,String desc
int i = 0;
while ( test.size()>i) {
String farm_name = test.get(i).getFarm_name();
String desc1 = test.get(i).getOwner_tel();
String desc2 = test.get(i).getFarm_type();
String cords = test.get(i).getM_cord();
//split the co-ords
String[] latlong = cords.split(",");
double latitude = Double.parseDouble(latlong[0]);
double longitude = Double.parseDouble(latlong[1]);
LatLng location = new LatLng(latitude, longitude);
//do the loop here
// Add lots of markers to the map. LatLng m_cord,String farm_name,String desc
addMarkersToMapJax(location, farm_name, desc1 + desc2);
i++;
}
}
I created a marker function to load the co-ordinates:
private void addMarkersToMapJax(LatLng m_cord,String farm_name,String desc) {
// Uses a colored icon.
mArc = mMap.addMarker(new MarkerOptions()
.position(m_cord)
.title(farm_name)
.snippet(desc)