I am testing my app on a real device and getting a null location when the GPS is on. When I test on the emulator with dummy coordinates it works fine. What is wrong?
locationManager = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
listener = new MyLocationListener();
viaGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
viaNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!viaGps && !viaNetwork) {
tracking = false;
} else {
if (viaGps) {
Log.d("", "gps is on");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}else if (viaNetwork) {
Log.d("", "network is on");
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if (location == null) {
Log.d("", "location not fouond");
}
Try using this , it solved my problem
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Also check your permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
You need a Location listener:
Follow the documentation
Update:
You can also try that easy way: What is the simplest and most robust way to get the user's current location in Android?
Related
I want to get current GPS location when button is clicked. I have written this code (given below) but this gives NullPointerException for location object that is Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);. please tell what is problem with my code?
Code:
#Override
public void onClick(View v) {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
String cur_loc = "latitude = " + location.getLatitude() + "\n" + location.getLongitude(); //this is line 54 in my code
Toast.makeText(ctx, cur_loc, Toast.LENGTH_LONG).show();
}
AndroidManifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
getLastKnownLocation (String provider) may well return null. see Documentation :
Returns a Location indicating the data from the last known location
fix obtained from the given provider.
This can be done without starting the provider. Note that this
location could be out-of-date, for example if the device was turned
off and moved to another location.
If the provider is currently disabled, null is returned.
try this method:
private Location getLastKnownLocation() {
mLocationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
Now use it as:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location myLocation = getLastKnownLocation();
I have a simple location manager that normally works, however when the Android device has been turned off and then turned back on, the android location manager returns Null even when I have it requesting updates. I am aware that getLastKnownLocation can return null, however I believe I am handling that in my code. All suggestions Appreciated.
Apparently lon = location.getLongitude(); is crashing it.
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null)
{
// request location update!!
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
lon = location.getLongitude();
lat = location.getLatitude();
}
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//Get last known location
location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//Update if not null
if (location != null)
{
lat = location.getLatitude();
lon = location.getLongitude();
}
//Request update as location manager can return null otherwise
else
{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
lat = location.getLatitude();
lon = location.getLongitude();
}
}
the android location manager returns Null even when I have it requesting updates
Correct. Requesting updates requests that Android start trying to find out where the device is. That will take a while. In the meantime, getLastKnownLocation() can very well return null.
getLastKnownLocation() is generally only useful if you would like to know the location, but if that data is not ready, you can move on without it. If you need the location, and getLastKnownLocation() returns null, you will to wait to use the Location until onLocationChanged() is called. Note that onLocationChanged() may never be called, as there is no requirement that the user have any location providers enabled, and there is no requirement that the device be in a position to actually get location fixes.
I saw your reply on the airplane mode but you do however have bad practices in your code.
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null)
{
// request location update!!
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
lon = location.getLongitude();
lat = location.getLatitude();
}
you already saw here that location in null, that means that you can't access the inner properties such as latitude and longitude. In any case, location requests are asynchronous and it takes a short amount of time for them to start.
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//Get last known location
location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//Update if not null
if (location != null)
{
lat = location.getLatitude();
lon = location.getLongitude();
}
//Request update as location manager can return null otherwise
else
{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
lat = location.getLatitude();
lon = location.getLongitude();
}
}
Even here, in the "else" clouse, you can't access the location right away. that means that you can't immediately get the location (it will just hold the last value).
What you should do is implement the onLocationChanges method and hadle the location there in asynchronous way. like this:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null)
{
lat = location.getLatitude();
lon = location.getLongitude();
}
else
{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lon = location.getLongitude();
}
The only problem was that I had airplane mode enabled on the Android Phone. I'm a bit embarrassed now!
I wanted to get my GPS coordinates using Android App. I started developing, and I can get GPS coordinates, but they are not accurate. I wanted to use NETWORK_PROVIDER, but the Location by this provider is always null. More interesting, isProvicerEnabled returns true.
I used example from this thread (best answer)
enter link description here
private void _getLocation() {
// Get the location manager
try {
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
Location location = null;
double latitude = -1;
double longitude = -1;
// 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 {
if (isNetworkEnabled) {
showToast("network");
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
1000,
0, 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 GPS Enabled get lat/long using GPS Services
else if (isGPSEnabled) {
showToast("gps");
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000,
0, this);
Log.d("GPS", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
showToast("" + latitude + longitude);
} catch (Exception e) {
e.printStackTrace();
}
I have all the permissions in manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
I know the code is dirty, but for now it's only for testing. Do I miss something? I found similar examples in many places, and it seems pretty straight, so I am a little confused.
My phone works ok, GPS and network works fine. For example Google Maps application I have works well. Any suggestions?
Please do NOT use this code. It's bad. It has a lot of errors. Also, getLastKnownLocation will return null if it doesn't have a location yet. Which it always will if nobody on the phone is using requestUpdates.
Your code is taken from a class that was posted on a very old thread on here called GPSTracker. I've been trying to kill that code for months- it causes far more problems than it helps. If you want better example code, try http://gabesechansoftware.com/location-tracking/ which is a blog post I wrote about how bad that code is. It will show you the correct way to do it, and explains some of what's wrong with that code.
I've been working on an application that tracks a users GPS coordinates and intermittently sends updates to my server. This is done in a thread within a service. Most of the time the first reading will be accurate but when moving the GPS is not updating. I think this is because the LocationManager takes some time to warm up. The location setting on the device will also affect the outcome (Device only, high accuracy), sometimes resulting with 0.0 being returned. Is there a simple solution that will allow it enough time before the values are decided upon?
Service thread:
new Thread() {
public void run() {
// prepare looper
Looper.prepare();
// send text messages
String numbersList = helper.getNumbers();
if (numbersList != "") {
String numbersArray[] = numbersList.split(", ");
for (int i = 0; i < numbersArray.length; i++) {
sendSMS(numbersArray[i], incident_id);
}
}
// run until told otherwise
while (active == true) {
// check if GPS enabled
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longitude = gps.getLongitude();
accuracy = gps.getAccuracy();
} else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
GPS Tracker Class:
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
} else {
this.canGetLocation = true;
// 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();
}
}
}
}
else 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();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
Your first location always is the last known location (locationManager.getLastKnownLocation(...)). This location may be relativly old, for example the last fix of the GPS before it was turned off or before you entered a building. Its accurracy in relation to your current location is more or less random (unless you did not move or left the building using the same door).
If the GPS was turned off or the satellites were not visible for a while (e.g. inside a building) the hardware will need some time to get a fix on the current location. This is the delay you are seeing. Afterwards your location listener (not shown above) will get updates from the GPS.
I've got Google Maps v2 running on my app, using a service to get the users location. Problem is the location keeps changing. It shows my real location for a bit, then jumps to a random location that I've never been to before.
I'm check GPS/Network lat/lng via the service and calling them in my maps class, where I then animate the camera to move to my location. I don't really know what's wrong, or where to start with this one.
Does anyone know what sort of problem this is? It's baffling to me.
I don't really know what code to post. The accuracy of the location via network is 1121m where as the accuracy of the location via GPS is around 31. I'm using a LocationListener and in the onLocationChanged is says it's using my network location, suddenly the accuracy improves, to 29m, then it suddenly goes back up to 1121m. This happens about every minute or so. Very odd behaviour. With GPS enabled, shouldn't that be the preferred choice anyway? Is there a way to set it to my preferred choice once it gets a fix?
My service gets it's information like this:
public Location getLocation() {
Log.i("getLocation", "Get location called");
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 and GPS is off.
Log.d("NOT ENABLED", "PASSIVE PROVIDER");
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
loc = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
Log.i("PASSIVE_LOCATION", "Location: "+loc.toString());
}
}
else {
this.canGetLocation = true;
if (isNetworkEnabled) {
Log.d("Network", "Network");
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
Log.i("NETWORK_LOCATION", "Location: "+loc.toString());
}
}
if (isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
Log.i("GPS_LOCATION", "Location: "+loc.toString());
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
//check provider & accuracy
Log.d("PROVIDER", loc.getProvider());
Log.d("ACCURACY", Float.toString(loc.getAccuracy()));
return loc;
If anyone could help I would really appreciate it. Thank you in advance.
I think this solved itself. It was jumping between locations simply because of accuracy. Once GPS accuracy was better than network, it started updating via GPS.
I'm also stopping location updates once the accuracy is less than 30 in onLocationChanged so I have a bit more control and don't waste the users battery.