Google API - NULL Pointer by getLastKnownLocation - java

Yesterdy my App worked perfectly but this morning it began to crash. I think the trigger was that I rebooted my Smartphone , so my APP loosed the GPS datas. I started the Debug mode and looked step by step for NULL values and I actuelly find it by this command :
myLocation = locationManager.getLastKnownLocation(provider);
This returns a NULL object which cause to an crash when I try to use these methods :
latitude = myLocation.getLatitude();
longtitude = myLocation.getLongitude();
How can I make that my Location is not NULL in this case ? I tried to use the NETWORK_PROVIDER but then I have to use the WLAN and this is not the best way I think.Can I still catch informations with the GPS_PROVIDER without to get into a other Application which save them ?
BTW here is my Code :
public class gmapps extends FragmentActivity {
private GoogleMap googleMap;
TextView txt_street , txt_city , txt_country ;
Geocoder geocoder;
List<Address> addresses;
ImageView btn_yes;
Location myLocation;
String address , city , country;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
txt_street = (TextView)findViewById(R.id.txt_coordinates);
txt_city = (TextView)findViewById(R.id.txt_city);
txt_country = (TextView)findViewById(R.id.txt_country);
btn_yes = (ImageView)findViewById(R.id.btn_yes);
setUpIfNeeded();
}
private void setUpIfNeeded() {
if (googleMap == null)
{
try{
googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
}catch(Exception e){}
if (googleMap != null)
{
setUpMap();
}
}
}
private void setUpMap() {
googleMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria , true);
myLocation = locationManager.getLastKnownLocation(provider); // Here I get the NULL
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
double latitude = myLocation.getLatitude();
double longtitude = myLocation.getLongitude();
LatLng latLng = new LatLng(latitude , longtitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(17));
try {
convert_adresses(latitude,longtitude);
} catch (IOException e) {
e.printStackTrace();
}
txt_street.setText(address);
txt_city.setText(city);
txt_country.setText(country);
}
public void convert_adresses (double lat , double lng) throws IOException
{
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(lat, lng, 1);
address = addresses.get(0).getAddressLine(0);
city = addresses.get(0).getAddressLine(1);
country = addresses.get(0).getAddressLine(2);
}
Thanks everyone !

First you should be using the "new" LocationClent class (which is already depreciated in favor of LocationServices).
https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html
Using this classes getLastLocation(), generally does a good job, but as the documentation says (see below), it can return null at times, so you must check for that.
What you should also do is make a request for location updates (see the doc referenced above), then when the device location becomes available it will call onLocationChanged(Location location) on your listener and you can then do whatever you need to do with the location that is provided.
public Location getLastLocation ()
Returns the best most recent location currently available.
If a location is not available, which should happen very rarely, null will be returned. The best accuracy available while respecting the location permissions will be returned.
This method provides a simplified way to get location. It is particularly well suited for applications that do not require an accurate location and that do not want to maintain extra logic for location updates.
Here is stripped down example of using the location client.
public class DeviceLocationClient implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
private Context context;
private LocationClient locationClient;
private boolean isConnected;
private LocationRequest request;
#Override
public void onLocationChanged(Location location) {
System.out.println("got a location update");
if (location != null ) {
// do something with the location
}
}
public DeviceLocationClient(Context context) {
this.context = context;
System.out.println("connecting to google play services");
locationClient = new LocationClient(context, this, this);
isConnected = false;
locationClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
System.out.println("connection to google play services FAILED!");
}
#Override
public void onConnected(Bundle connectionHint) {
System.out.println("google play servies connected");
isConnected = true;
// locationClient.requestLocationUpdates(request, this);
request = new LocationRequest();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setExpirationDuration(60 * 1000);
request.setFastestInterval(5 * 1000);
request.setInterval(10 * 1000);
isConnected = true;
requestLLocationUpdates();
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
System.out
.println("google play services got disconnected - reconnecting");
mBus.unregister(this);
locationClient.connect();
}
#Subscribe
public void onUpdateLocationRequest(UpdateLocationRequest event) {
System.out.println("got the location request");
request = new LocationRequest();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setExpirationDuration(60 * 1000);
request.setFastestInterval(5 * 1000);
request.setInterval(10 * 1000);
locationClient.removeLocationUpdates(this);
locationClient.requestLocationUpdates(request, this);
}
public void requestLLocationUpdates() {
System.out.println("requesting location updates updates");
if (isConnected) {
System.out.println("processing request");
System.out.println("sending latest location");
Location lastLocation = locationClient.getLastLocation();
if (lastLocation != null) {
// do something with the last location
}
request = new LocationRequest();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setExpirationDuration(60 * 1000);
request.setFastestInterval(5 * 1000);
request.setInterval(10 * 1000);
System.out.println("requesting updates");
locationClient.removeLocationUpdates(this);
locationClient.requestLocationUpdates(request, this);
} else {
if (locationClient.isConnecting()) {
System.out.println("google play services is connecting");
} else {
System.out
.println("attempting to connect to google play services");
locationClient.connect();
}
}
}
}

you can put a check for null pointer like this
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, false);
Log.d("FlagLocation", "true");
if (provider != null && !provider.equals("")) {
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 20000, 1, this);
if (location != null) {
double lng = location.getLongitude();
double lat = location.getLatitude();
double kmInLongitudeDegree = 111.320 * Math.cos(lat / 180.0
* Math.PI);
double deltaLat = RADIUS / 111.1;
double deltaLong = RADIUS / kmInLongitudeDegree;
double minLat = lat - deltaLat;
double maxLat = lat + deltaLat;
double minLong = lng - deltaLong;
double maxLong = lng + deltaLong;
}

Just retrieve the location from GPS provider when getLastLocation() == null.
Take a look at the android documentation that does exactly what you need.
http://developer.android.com/training/location/retrieve-current.html
Let me know if you need some example code and I'll edit my answer.
Hope this helps.

Related

location returns null when started the first time

For my app, I need to get the location of the user, to fetch corresponding data from a server. The problem is that the code I use doesn't properly return the location when it's opened the first time. After restarting the app once it works just fine. I searched the other questions and found out, that if you use getLastKnownLocation and there is no location since the last reboot, it returns null. But why does it work when the app is restarted? Does it fetch it when it's opened the first time, and how can I make it wait until the location is fetched properly at the first opening then?
The code of my MainActivity:
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 123);
} else {
progressBar.setVisibility(View.VISIBLE);
GPSClass gt = new GPSClass(getActivity().getApplicationContext());
Location location = gt.getLocation();
if (location == null) {
//Toast
} else {
lat = location.getLatitude();
lon = location.getLongitude();
}
new GetContacts().execute();
}
And the GPSClass:
public class GPSClass implements LocationListener {
Context context;
public GPSClass(Context context) {
super();
this.context = context;
}
public Location getLocation(){
if (ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
Log.e("fist","error");
return null;
}
try {
LocationManager lm = (LocationManager) context.getSystemService(LOCATION_SERVICE);
boolean isGPSEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled){
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000,10,this);
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return loc;
}else{
Log.e("sec","error");
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
Here is the full tutorial
I shared a tutorial link follow that link.
Call this below method. It will return value; when lat and long is found. Until object is null or doesn't return any value your app must be idle or show some progress value or tell the user to wait.
InitGeoLocationUpdate.locationInit(SplashScreen.this,
object -> {
double latitude = object.latitude;
double longitude = object.longitude;
Lg.INSTANCE.d(TAG, "Current Location Latitude: " + latitude + " Longitude: " +
longitude);
});
Try this this will not give you null current location
class GetLastLocation extends TimerTask {
LocationManager mlocManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListenerTmp = new CustomLocationListener();
private final Handler mLocHandler;
public GetLastLocation(Handler mLocHandler) {
this.mLocHandler = mLocHandler;
}
#Override
public void run() {
timer.cancel();
mlocManager.removeUpdates(mlocListenerTmp);
Location location = mlocManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
{
if (mlocListenerTmp != null) {
mlocManager.removeUpdates(mlocListenerTmp);
}
currentLocation = location;
}
if (location != null) {
String message = String.format(
"Location \n Longitude: %1$s \n Latitude: %2$s",
location.getLongitude(), location.getLatitude());
Log.d("loc", " :" + message);
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", true);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
} else {
Log.d(
"loc",
":No GPS or network signal please fill the location manually!");
location = mlocManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
currentLocation = location;
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", true);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
} else {
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", false);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
}
}
}
}
call it like this in your MainActivity
timer.schedule(new GetLastLocation(mLocHandler), 3000);
and the customLocationclass is as follows:
public class CustomLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
loc.getLatitude();
loc.getLongitude();
currentLocation = loc;
String Text = "My current location is: " + "Latitud = "
+ loc.getLatitude() + "Longitud = " + loc.getLongitude();
Log.d("loc", "onLocationChanged" + Text);
}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}

Android GPS sensor don't enter onLocationChanged method

I am developing an android application for gathering data about the user location from the location sensor. Here is my code.
public class GPSService extends IntentService implements LocationListener {
public GPSService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public GPSService() {
super("GPSService");
// TODO Auto-generated constructor stub
}
private VSensorConfig config = null;
private static final String TAG = "AccelometerService";
public AndroidControllerListVSNew VSNewController;
public AbstractWrapper w;
private final Context mContext = null;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public Location getLocation() {
try {
Log.i("getLocation", "getLocation");
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
//TODO enja mishe parameter haro paas dad
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSService.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.i("onLocationChanged","onLocationChangedddddddddddddddddddddddddddddddddd");
StreamElement streamElement = new StreamElement(w.getFieldList(),
w.getFieldType(), new Serializable[] {location.getLatitude(),location.getLongitude()});
((AndroidAccelerometerWrapper) w).setTheLastStreamElement(streamElement);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle b = intent.getExtras();
config = (VSensorConfig) b.get("config");
Log.i("Service", config.getInputStreams().toString());
for (InputStream inputStream : config.getInputStreams()) {
for (StreamSource streamSource : inputStream.getSources()) {
w = streamSource.getWrapper();
Log.v(TAG, w.toString());
// Activity activity = config.getController().getActivity();
// mSensorManager = (SensorManager) activity
// .getSystemService(Context.SENSOR_SERVICE);
// mSensor = mSensorManager.getDefaultSensor(Sensor.Typ);
// mSensorManager.registerListener(this, mSensor,
// SensorManager.SENSOR_DELAY_NORMAL);
// while (w.isActive()) {
while(true)
{
Log.i("accelometer ", "accelometer");
try {
Thread.sleep(w.getSamplingRate());
((AndroidGPSWrapper) w).getLastKnownLocation();
Log.i("accelometer ", "accelometer");
}
catch (InterruptedException e) {
Log.e(e.getMessage(), e.toString());
}
}
}
}
}
}
I have to build it as an intent service.
The problem is that this code never enters the OnLocationChanged method. Can anyone help me with it?
I didn't move far from my first location yet. But it should at least print one location for me.
Thanks alot.
First off, you probably aren't getting a GPS lock. If you're inside at your computer testing, GPS generally doesn't work. Is the GPS sign on your notification bar flashing? If so, you're not locked and you aren't being called because GPS isn't working yet.
Secondly, an IntentService is a bad match for GPS. You need a continual lock to the satellites to make GPS work. An IntentService works briefly and then ends. This would end the GPS connection. It should be a normal service, not an intent service.
Third- your code is terrible. I've written a blog article here about why that GPSTracker class is badly broken and should never be used. I've posted better code here on SO before, but you can also find it at that link. It won't solve the problem of not getting satellite lock, but it will fix other problems in that code.

Pause code execution while acquiring informations

Have a working application which collects GPS coordinates over GPS.
The application will use the those coordinates after the collection.
But because the acquiring of the coordinates can take 10-15 or more sec.
The app starts acquiring, moves forward in code takes the cords ( usually lastknowlocation ) and uses the coordinates which are not last.
So often I get GPS cords as 0,0 0,0 or lastknowlocation
I need somehow to pause execution of code until the new cords are acquired.
For any ideas or help I would be thankful
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
Location location_1; // location
Location zadnja; // location
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 10 * 1; // 10 seconds
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
location = null ;
locationManager = null;
this.canGetLocation= false ;
canGetLocation = false ;
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener Calling this function will stop using GPS in your
* app
* */
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
*
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog On pressing Settings button will
* lauch Settings Options
* */
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog
.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
You need to delegate the GPS collection to a separate thread, and let the main code monitor it. That way the management of what is happening is in one thread, and the slow stuff is in another. The two threads need to communicate using classical state-machine techniques (synchronized code sections, semaphores etc).
Why don't you acquire the location in an AsyncTask and set a variable of the class foundLocation=true in PostExecute of the AsycTask, and pause your main thread with a
while(!foundLocation){
// do something like a loading bar or something
}

Google Maps API V2 marker not showing on correct position

I've been following a series of tutorials to make a basic restaurant locator app for android using Google places with maps API v2. The problem I am having, is that my gps location is correct, but the marker drawn on the map to show the users location is approximately 60-65 miles south east of the users actual location.
Here is the code for my Location class:
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location = null;
double latitude;
double longitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
}
else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
and finally here is the code for my map activity:
public class PlacesMapActivity extends FragmentActivity {
double latitude;
double longitude;
LatLng USER=null;
LatLng LOCATION=null;
PlacesList nearPlaces;
private GoogleMap map;
private int userIcon, locationIcon;
String address;
String name;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_places);
userIcon = R.drawable.mark_red;
locationIcon = R.drawable.mark_blue;
Intent i = getIntent();
String user_latitude = i.getStringExtra("user_latitude");
String user_longitude = i.getStringExtra("user_longitude");
String user_location = (user_latitude + ", " + user_longitude);
SupportMapFragment fm = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.mapView);
map = fm.getMap();
USER = new LatLng((int) (Double.parseDouble(user_latitude)),
(int) (Double.parseDouble(user_longitude)));
Marker user = map.addMarker(new MarkerOptions().position(USER)
.title("This is you.")
.snippet(user_location)
.icon(BitmapDescriptorFactory
.fromResource(userIcon)));
nearPlaces = (PlacesList) i.getSerializableExtra("near_places");
if(nearPlaces != null) {
for(Place place : nearPlaces.results) {
latitude = place.geometry.location.lat;
longitude = place.geometry.location.lng;
name = place.name;
address= place.vicinity;
}
final LatLngBounds.Builder builder = new LatLngBounds.Builder();
for(int c = 0; c < nearPlaces.results.size(); c++){
final LatLng pos = new LatLng(nearPlaces.results.get(c).geometry.location.lat,
nearPlaces.results.get(c).geometry.location.lng);
builder.include(pos);
map.addMarker(new MarkerOptions().position(pos)
.title(nearPlaces.results.get(c).name)
.snippet(nearPlaces.results.get(c).vicinity)
.icon(BitmapDescriptorFactory
.fromResource(locationIcon)));
}
}
map.moveCamera(CameraUpdateFactory.newLatLngZoom(USER, 14));
map.animateCamera(CameraUpdateFactory.zoomTo(9), 2000, null);
}
I tried to attach a screenshot, apparently I can't yet. I set the marker snippet to show the users latitude and longitude when clicked. When I click the users marker it shows the correct longitude and latitude (checked them on the internet, its within a block of my actual location), but as I stated the marker for the user always shows 60-65 miles south east. Also, the locations of the Places results are all correct and the markers in the correct locations.
any help is greatly appreciated. Cheers.
In your code below
USER = new LatLng((int) (Double.parseDouble(user_latitude)),
(int) (Double.parseDouble(user_longitude)));
Don't convert latitude-longitude to int, instead keep them as double.
Cheers !

How to get Latitude and Longitude of the mobile device in android?

How do I get the current Latitude and Longitude of the mobile device in android using location tools?
Use the LocationManager.
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
The call to getLastKnownLocation() doesn't block - which means it will return null if no position is currently available - so you probably want to have a look at passing a LocationListener to the requestLocationUpdates() method instead, which will give you asynchronous updates of your location.
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
}
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
You'll need to give your application the ACCESS_FINE_LOCATION permission if you want to use GPS.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
You may also want to add the ACCESS_COARSE_LOCATION permission for when GPS isn't available and select your location provider with the getBestProvider() method.
Here is the class LocationFinder to find the GPS location. This class will call MyLocation, which will do the business.
LocationFinder
public class LocationFinder extends Activity {
int increment = 4;
MyLocation myLocation = new MyLocation();
// private ProgressDialog dialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intermediat);
myLocation.getLocation(getApplicationContext(), locationResult);
boolean r = myLocation.getLocation(getApplicationContext(),
locationResult);
startActivity(new Intent(LocationFinder.this,
// Nearbyhotelfinder.class));
GPSMyListView.class));
finish();
}
public LocationResult locationResult = new LocationResult() {
#Override
public void gotLocation(Location location) {
// TODO Auto-generated method stub
double Longitude = location.getLongitude();
double Latitude = location.getLatitude();
Toast.makeText(getApplicationContext(), "Got Location",
Toast.LENGTH_LONG).show();
try {
SharedPreferences locationpref = getApplication()
.getSharedPreferences("location", MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = locationpref.edit();
prefsEditor.putString("Longitude", Longitude + "");
prefsEditor.putString("Latitude", Latitude + "");
prefsEditor.commit();
System.out.println("SHARE PREFERENCE ME PUT KAR DIYA.");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
// handler for the background updating
}
MyLocation
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//Toast.makeText(context, gps_enabled+" "+network_enabled, Toast.LENGTH_LONG).show();
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 10000);
// Toast.makeText(context, " Yaha Tak AAya", Toast.LENGTH_LONG).show();
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
//Context context = getClass().getgetApplicationContext();
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
With google things changes very often: non of the previous answers worked for me.
based on this google training here is how you do it using
fused location provider
this requires Set Up Google Play Services
Activity class
public class GPSTrackerActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
try {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Intent intent = new Intent();
intent.putExtra("Longitude", mLastLocation.getLongitude());
intent.putExtra("Latitude", mLastLocation.getLatitude());
setResult(1,intent);
finish();
}
} catch (SecurityException e) {
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
usage
in you activity
Intent intent = new Intent(context, GPSTrackerActivity.class);
startActivityForResult(intent,1);
And this method
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){
Bundle extras = data.getExtras();
Double longitude = extras.getDouble("Longitude");
Double latitude = extras.getDouble("Latitude");
}
}
you can got Current latlng using this
`
public class MainActivity extends ActionBarActivity {
private LocationManager locationManager;
private String provider;
private MyLocationListener mylistener;
private Criteria criteria;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); //default
// user defines the criteria
criteria.setCostAllowed(false);
// get the best provider depending on the criteria
provider = locationManager.getBestProvider(criteria, false);
// the last known location of this provider
Location location = locationManager.getLastKnownLocation(provider);
mylistener = new MyLocationListener();
if (location != null) {
mylistener.onLocationChanged(location);
} else {
// leads to the settings because there is no last known location
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// location updates: at least 1 meter and 200millsecs change
locationManager.requestLocationUpdates(provider, 200, 1, mylistener);
String a=""+location.getLatitude();
Toast.makeText(getApplicationContext(), a, 222).show();
}
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
// Initialize the location fields
Toast.makeText(MainActivity.this, ""+location.getLatitude()+location.getLongitude(),
Toast.LENGTH_SHORT).show()
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Toast.makeText(MainActivity.this, provider + "'s status changed to "+status +"!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " enabled!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " disabled!",
Toast.LENGTH_SHORT).show();
}
}
`
Above solutions is also correct, but some time if location is null then it crash the app or not working properly. The best way to get Latitude and Longitude of android is:
Geocoder geocoder;
String bestProvider;
List<Address> user = null;
double lat;
double lng;
LocationManager lm = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
bestProvider = lm.getBestProvider(criteria, false);
Location location = lm.getLastKnownLocation(bestProvider);
if (location == null){
Toast.makeText(activity,"Location Not found",Toast.LENGTH_LONG).show();
}else{
geocoder = new Geocoder(activity);
try {
user = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
lat=(double)user.get(0).getLatitude();
lng=(double)user.get(0).getLongitude();
System.out.println(" DDD lat: " +lat+", longitude: "+lng);
}catch (Exception e) {
e.printStackTrace();
}
}
Best way is
Add permission manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Then you can get GPS location or if GPS location is not available then this function return NETWORK location
public static Location getLocationWithCheckNetworkAndGPS(Context mContext) {
LocationManager lm = (LocationManager)
mContext.getSystemService(Context.LOCATION_SERVICE);
assert lm != null;
isGpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkLocationEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Location networkLoacation = null, gpsLocation = null, finalLoc = null;
if (isGpsEnabled)
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return null;
}gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (isNetworkLocationEnabled)
networkLoacation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (gpsLocation != null && networkLoacation != null) {
//smaller the number more accurate result will
if (gpsLocation.getAccuracy() > networkLoacation.getAccuracy())
return finalLoc = networkLoacation;
else
return finalLoc = gpsLocation;
} else {
if (gpsLocation != null) {
return finalLoc = gpsLocation;
} else if (networkLoacation != null) {
return finalLoc = networkLoacation;
}
}
return finalLoc;
}
You can use FusedLocationProvider
For using Fused Location Provider in your project you will have to add the google play services location dependency in our app level build.gradle file
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
...
...
implementation 'com.google.android.gms:play-services-location:17.0.0'
}
Permissions in Manifest
Apps that use location services must request location permissions. Android offers two location permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
As you may know that from Android 6.0 (Marshmallow) you must request permissions for important access in the runtime. Cause it’s a security issue where while installing an application, user may not clearly understand about an important permission of their device.
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_ID
)
Then you can use the FusedLocationProvider Client to get the updated location in your desired place.
mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
var location: Location? = task.result
if (location == null) {
requestNewLocationData()
} else {
findViewById<TextView>(R.id.latTextView).text = location.latitude.toString()
findViewById<TextView>(R.id.lonTextView).text = location.longitude.toString()
}
}
You can also check certain configuration like if the device has location settings on or not. You can also check the article on Detect Current Latitude & Longitude using Kotlin in Android for more functionality.
If there is no cache location then it will catch the current location using:
private fun requestNewLocationData() {
var mLocationRequest = LocationRequest()
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationRequest.interval = 0
mLocationRequest.fastestInterval = 0
mLocationRequest.numUpdates = 1
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
)
}
Plug and play location-manager that can be used both in XML-based projects and Jetpack Compose projects (personally using it in JetpackCompose)
class LocationManager(context: Context): LocationCallback() {
val context = context
var publicCompletion: ((Double, Double) -> Unit)? = null
var fusedLocationProviderClient = FusedLocationProviderClient(
context
)
fun requestLocationPermission() {
val activity = context as Activity?
ActivityCompat.requestPermissions(
activity!!,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION
),
101
)
}
fun checkIfLocationPermissionIsGranted(): Boolean {
return (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
)
}
fun getLatitudeLongitude(completion: (Double, Double) -> Unit) {
publicCompletion = { latitude, longitude ->
completion(latitude, longitude)
}
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
val activity = context as Activity?
fusedLocationProviderClient.lastLocation.addOnCompleteListener(activity!!) { task ->
var location: Location? = task.result
if (location != null) {
publicCompletion?.let { it(location!!.latitude, location!!.longitude) }
} else {
requestLocationUpdates()
}
}
}
}
fun requestLocationUpdates() {
var request = LocationRequest()
request.priority = com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCURACY
request.fastestInterval = 0
request.numUpdates = 1
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProviderClient.requestLocationUpdates(
request, this, Looper.myLooper()
)
}
}
override fun onLocationResult(p0: LocationResult?) {
super.onLocationResult(p0)
publicCompletion?.let { it(p0!!.lastLocation!!.latitude, p0!!.lastLocation!!.longitude) }
}
override fun onLocationAvailability(p0: LocationAvailability?) {
super.onLocationAvailability(p0)
}
}
Just follow Google recommendation and prepared codes in kotlin: (Supports also Android 11 and 12):
https://github.com/googlecodelabs/while-in-use-location
and its step by step explanation:
https://codelabs.developers.google.com/codelabs/while-in-use-location

Categories