Android onLocationUpdate not called with GPS_PROVIDER - android

Hi
I have an Android service using the location manager :
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Log.i("service","start with GPS"); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,locationListener);
}
Then the location listener :
private LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location aLocation) {
Log.i("location listener", "location updated");
}
... other methods ....
}
In the manifest, the authorization for ACCESS_FINE_LOCATION is set.
Everything works ok both in simulator and phone ( Xperia Android 1.6 to 2.2 ) for NETWORK_PROVIDER. It works fine in simulator for GPS_PROVIDER. But when I try to use the GPS in the devices, the location listener is never called. I can see in the DDMS that the GPS is actually working and retrieve locations, but it never calls the listener methods.
There is a strange message though :
WARN/libloc_api(1173): loc_eng_report_position: ignore position report when session status = 1
I can not see what I am missing. Any idea ? Thanks.

It takes a while to get a location fix. The time to first fix de(TTFF) depends on a lot of factors, like number of visible GPS satellites, signal to noise ratio, the GPS chipset etc ...
Here is a nice article that will help you get the best out of GPS on android phones.

Related

android :how to localise only with wifi or mobile network by code without using popup security menu

j know that since 4.0 it s impossible to trigger programmatically gps
but besides that there are three possibilities to localise
1) gps and wifi and mobile network (all together)
2) only wifi and mobile network
3) only gps
is there some possible code to get through the second one
so let's be clear j don't want to trigger wifi. that i know
j want to trigger localisation by whatever wifi (and)or mobile network without using gps
j tried to implement some object like skyhook' WPSPeriodicLocationCallback or WPSLocationCallback but
it doesn 't work without triggering the official android security menu
so what j want is getting through the positionning system only with wifi or internet connection and that by code
avast antitheft does that giving back some information with more or less accuracy .
i would like to reproduce the same
thanks in advance
You can get locating the position using the LocationManager.NETWORK_PROVIDER instead of LocationManager.GPS_PROVIDER. The NETWORK_PROVIDER will resolve on the GSM or wifi, which ever available. Obviously with wifi off, GSM will be used. Keep in mind that using the cell network is accurate to basically 500m.
http://developer.android.com/guide/topics/location/obtaining-user-location.html has some really great information and sample code.
After you get done with most of the code in OnCreate(), add this:
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
You could also have your activity implement the LocationListener class and thus implement onLocationChanged() in your activity or you can use this tutorial to get lat and lang.
Copypasted from this answer.

LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) always returns NULL on Galaxy S7 (ONLY)

Just received a Galaxy S7 (Edge) running Marshmallow (6.0.1) and find that it has an issue with my app that uses android.permission.ACCESS_COARSE_LOCATION and targets Sdk Version 22 (Lollipop). When I call locationManager.getLastKnownLocation() it always returns NULL. Here's what I'm running:
public Location getLastKnownLocationObject(Context context) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// Location is always null on S7 (only)
Log.i(TAG, ">>> getLastKnownLocationObject() getLastKnownLocation: " + location);
return location;
}
} catch (Exception e) {
Log.e(TAG, ">>> getLastKnownLocationObject() exception", e);
}
return null;
}
This same code works fine on every other device I've tried: Galaxy S5 (5.0.1), Nexus 7 (5.0.1), Nexus 9 (6.0.1), and Samsung Tab3 (4.4.2)
Note that if I change the manifest to use ACCESS_FINE_LOCATION, the above code works fine on every device. Unfortunately, management won't allow me to change permissions at this time.
In a few answers I've seen here on SO, it's suggested to call the following prior to doing the getLastKnownLocation(), but that didn't have any effect.
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
#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 onLocationChanged(final Location location) {
// NEVER CALLED on Samsung S7 for LocationManager.NETWORK_PROVIDER
}
});
So at the moment, I feel this is an issue exclusive to the new Samsung Galaxy S7.
From my experience with Samsung devices. If you reboot the phone and you DON'T enable GPS you will not get a location. If you enable GPS as some point - maybe by running Google Maps, then you will get a location. Samsung does not return a location for GPS, Network or Passive providers unless it has gotten a location during the devices power on cycle.
None of the calls I have made in code ever get it to kick in and activate and get a location. They work fine on other devices. Samsung does not seem to cache this information for very long either.
Well, you are calling isProviderEnabled() so at least that is covered and using the network location should be enabled. However the exact wording of the documentation is:
"If the user has enabled this provider in the Settings menu, true is
returned otherwise false is returned"
So it's just about the provider being "enabled" as in not being turned off by the user.
Does the problematic phone (the S7) have a SIM card inside? It's possible that on that specific device the network based positioning requires a SIM card or internet connection.
Referring to the the documentation you could check what these return:
locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresCell();
locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresNetwork();
And of course just calling getLastKnownLocation() will return null if the location is unknown. And it's unknown if no application (yours or some other) has specifically requested the device to determine its location. So the suggestion to call requestLocationUpdates() is the correct advice. But it may take a while to determine the location so calling getLastKnownLocation() right after probably still returns null.
And even if it returns something, it might be very old data that's not even valid anymore. So why not just subscribe to receive location updates? That's the way it's intended. You are using network based positioning so it won't (at all/significantly) affect power consumption and the updates won't come too often if you specify time interval and distance limits that suit your needs.

Android LocationManager requestLocationUpdates changed?

My app is working in Ice Cream Sandwich perfectly well, but now I tried it on KitKat and faced some problems.
The app is kind of server I'm running in my old phone and it provides location when requested. In ICS when the location is requested the GPS icon starts blinking and soon the app receives location update and sends it forward. But now with KitKat the GPS icon does not start blinking when location is requested. The app gives 60s time for finding the GPS location, but usually the GPS isn't even activated during this time. Still now and then the GPS suddenly activates itself (during the 60s) and the location is provided to my app.
Why the GPS doesn't get activated even my app requests location? As said, my app works with ICS without problems. And I do have required permissions set in my manifest.
public variables:
public static LocationManager mlocManager = null;
public static LocationListener mlocListener_fast = null;
onCreate:
mlocListener_fast = new MyLocationListener();
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Handling user requested command (location request)
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener_fast);
What should I do differently to get the GPS location instantly without waiting for sudden location updates/GPS activation, probably triggered by Android or some other app?? Unfortunately I don't have any other Android device I could try this.
EDIT:
It seems that if the app does not request location at startup, then the location request works every time when requested time after time. But if the location was requested (and received) on startup, then the location request does not work anymore. What can cause that? I use exactly the same line (the same location mgr and the same location listener) for location request on startup and later if requested.
Even if the location listener used in startup is different than the one used later, the location request does not work anymore. Tried even initialize the location mngr again just before requesting the location again and it did not help. What's with this??
EDIT2:
It just seems that with KitKat it's not possible to request multiple location requests. I used to have several location listeners for different purposes. For example one for updating location once per hour and another for getting location instantly (user requested update). Now it seems that if I have the 1/60min location listener running as normal, then KitKat location manager fails to handle the instant location requests. Have anyone faced this issue? Would be good to know which Android versions have this issue.
Workaround for this issue is to use only one LocationManager and one LocationListener. If your app has needs for different kind of simultaneous location requests (with different parameters), then you need to implement a "location request handler" which decides which parameters should be used for the location request i.e. which parameters have the tightest requirements for location.
Here is a simple example code that explains the idea of "location request handler":
class LR {
long lock_min_time; // defined in set_lock_lr before using
float lock_min_dist;
boolean lock_active = false;
long idle_min_time = 3600000; // 1 per hour
float idle_min_dist = 200;
boolean idle_active = true;
long fast_min_time = 0;
float fast_min_dist = 0;
boolean fast_active = false;
//constructor
public LR()
{}
public void set_lock_lr(long min_time, float min_dist, boolean active)
{
lock_active = active;
lock_min_dist = min_dist;
lock_min_time = min_time;
System.out.println("LR lock set: "+min_time+", "+min_dist+", "+active);
update_location_request();
}
public void set_idle_lr(boolean active)
{
idle_active = active;
System.out.println("LR idle set: "+active);
update_location_request();
}
public void set_fast_lr(boolean active)
{
fast_active = active;
System.out.println("LR fast set: "+active);
update_location_request();
}
private void update_location_request()
{
// Remove current location request
mlocManager_basic.removeUpdates(mlocListener_basic);
if(fast_active)
{
mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, fast_min_time, fast_min_dist, mlocListener_basic);
System.out.println("LR: fast_active");
}
else if(lock_active)
{
mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, lock_min_time, lock_min_dist, mlocListener_basic);
System.out.println("LR: lock_active");
}
else if(idle_active) // only idle updates
{
mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, idle_min_time, idle_min_dist, mlocListener_basic);
System.out.println("LR: idle_active");
}
}
}

Android NETWORK_PROVIDER location

I'm having little problem with getting my current location using NETWORK_PROVIDDER.
My code looks like this:
LocationManager lMgr = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
boolean isNetworkProviderEnabled = lMgr
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Location location = lMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
// deal somehow with last (very likely outdated location)
}
if (isNetworkProviderEnabled) {
lMgr.requestLocationUpdates(provider, 0, 0, locationListener);
}
Of course I have MyLocationListener that deals with location changes and ALL REQUIRED PERMISSIONS ARE ADDED TO MANIFEST
And the problem is that on some phones this code works like charm, but one others, the "requestLocationUpdates" does totally nothing. Of course on those problematic phones, when I open Google Maps application, my current location appears immediately. So my question is (I believe that people from Google should answer this): how this is done that Google Maps retrieves current location immediately, and other apps don't? Is my code wrong? Of course I have seen code like this in many stackoverflow questions. If anyone wish to know, this kind of problem appears on some Samsung Galaxy Nexus S phones
In my application GPS is not used to save battery power, but location services are enabled.
I have recently faced the same issue, LocationManager is buggy and not implemented completely on Samsung phones. They also consume a lot of power. Use LocationClient to solve both these issues. LocationClient uses all means available to get you the last location, so its the super set of all your providers and sensors.
I faced issues with the Samsung Y model phones, I wonder which phones you are talking about. To fix the problem with Samsung phones, I kickstarted the GPS on the phone with
HomeScreen.getLocationManager().requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
#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 onLocationChanged(final Location location) {
}
});
And then called the LocationManager.getLastKnownLocation OR the new locationClient.getLastLocation api.
First, just add the above lines over your getLastKnownLocation. Things should magically start workings
Migrate to LocationClient when you have more time and test again. Use the magic above to get it working if it fails.
Sometimes device does not receive any location updates and GPS_PROVIDER and NETWORK_PROVIDER returns null.
Try restarting your device, this trick helped me. My code was perfectly fine but providers were returning null.

Send GPS coordinates to Android emulator using DDMS, telnet or any other means

DDMS is not able to send location to the emulator. I have tried sending just the location from DDMS but still the emulator is not able to receive location. Nothing appears on the DDMS log when I click the Send button.
I tried sending geo fix from telnet which returns OK but doesn't actually update the location, or if it does I can't read it via my application.
The application works properly in the device, is able to capture test location details but not able to capture location data sent to the emulator either via DDMS or telnet.
I am testing on Android 2.2 emulator. Can anyone let me know what is wrong?
My app (below) is written in C# using Mono for Android and may need fixing (I'm a newbie to all things Android so I could have missed something). OnLocationChanged(Location location) just doesn't seem to fire at all, as if the listener isn't properly defined. Any help appreciated.
Note: The first time I run this Activity the LocationManager.GetLastKnownLocation is null but the test provider stuff isn't accessed. When I run it again GetLastKnowLocation is still null but the test provider stuff is accessed and set. Weird.
[Activity(Label = "Location Demo")]
public class LocationActivity : Activity, ILocationListener
{
private TextView _locationText;
private LocationManager _locationManager;
private StringBuilder _builder;
private Geocoder _geocoder;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.LocationActivity);
_geocoder = new Geocoder(this);
_locationText = FindViewById<TextView>(Resource.Id.TextView1);
_locationManager = (LocationManager)GetSystemService(LocationService);
if (_locationManager.GetLastKnownLocation("gps") == null)
{
_locationManager.AddTestProvider("gps", false, false, false, false, false, false, false, 0, 5);
_locationManager.SetTestProviderEnabled("gps", true);
Location loc = new Location("gps");
loc.Latitude = 50;
loc.Longitude = 50;
_locationManager.SetTestProviderLocation("gps", loc);
}
Location lastKnownLocation = _locationManager.GetLastKnownLocation("gps");
if (lastKnownLocation != null)
{
_locationText.Text += string.Format("Last known location, lat: {0}, long: {1}", lastKnownLocation.Latitude, lastKnownLocation.Longitude);
}
else
{
_locationText.Text += string.Format("Last location unknown");
}
_locationManager.RequestLocationUpdates("gps", 5000, 2, this);
}
public void OnLocationChanged(Location location)
{
_locationText.Text += string.Format("Location updated, lat: {0}, long: {1}", location.Latitude, location.Longitude);
}
public void OnProviderDisabled(string provider){}
public void OnProviderEnabled(string provider){}
public void OnStatusChanged(string provider, Android.Locations.Availability availability, Bundle extras){}
}
Kudos to https://stackoverflow.com/users/170333/greg-shackles for getting me this far.
I think the problem may be with how you're calling RequestLocationUpdates(). That third parameter is the minimum distance the device needs to move before you get updates, so you're telling the system to only send updates after the device has moved 2 meters. If it works on a real device, it's probably because you moved more than 6 feet. :)
Try starting with RequestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this). That will start a stream of updates on a real device, but only one when you press 'Send' in DDMS. Once that works, I would work back from there on how often you get updates.
Also, GetLastKnownLocation() is always null when you start the emulator. It's better for devices since it can send you the network location as a starting estimate, or the GPS location if another program was using it recently.
EDIT
It could also be a permissions issue. Normally you need to alter AndroidManifest.xml to get GPS access. The line is
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
See the docs here.
Call
_locationManager.RequestLocationUpdates("gps", 5000, 2, this);
function before doing any location operations, like below:
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.LocationActivity);
_geocoder = new Geocoder(this);
_locationText = FindViewById<TextView>(Resource.Id.TextView1);
_locationManager = (LocationManager)GetSystemService(LocationService);
_locationManager.RequestLocationUpdates("gps", 5000, 2, this); //this will cause updated location to be retrieved from telnet
Note: Its normal that program works after the first run, so that after the first run your application could get the initial updated location from telnet and that will be enough to not throws an exception
Finally resolved this. When the emulator is launched by VS2010 (i.e. F5, start debugging) it does not behave as expected. Launch the emulator externally using AVD.exe, start a virtual device and deploy the app. to it (using F5, start debugging) and everything works fine.
Why starting the emulator from within or outside VS2010 should make any difference is a mystery I am able to live with. Thanks to everyone for their helpful suggestions.
Does your emulated android image have GPS hardware? The description in the emulator should have "hw.gps=yes".
I had the same symptoms before recreating a new image with the right (emulated) hardware. I found a simple web page that displays the current location was handy when debugging the emulation environment.

Categories

Resources