LocationManager
CLLocationManager wrapper in Swift, performs location update, geocoding and reverse geocoding using Apple and Google service
Before I go into location based mode I check for existence of any location providers by calling
List<String> android.location.LocationManager.getProviders(boolean enabledOnly) //enabledOnly = true
and checking the size of the resulting list.
Now I tested my App on a HTC Desire with Android 2.2. The system settings don't allow any location tracking (GPS and mobile is turned off).
However, the list get returned has 1 entry, whose value is "passive". What is it? Can I work with it? The provider seems to be slow / not working.
Source: (StackOverflow)
One user of my app reported that app tells network for location is off even he did turn it on. He sent me few screen shots and they made me think;
LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
is not working properly. His phone is running Android 4.1.2 and first I thought this is the cause of this issue. But it was not the case. He sent me a screen shot of that setting too.
Then I googled and found this. The question seems to help me but unfortunately answer was not helpful for this case and questioner did not pursue farther.
My app is related to location and have been using LocationManager.isProviderEnabled to know GPS and Network for location is on or off. I have never been told my app is not properly knowing those settings until recently. He is the first user who reported the issue. I learned there are another method to know GPS and Network for location settings, by seeing Secure.LOCATION_PROVIDERS_ALLOWED. To see how this method work on his phone, I wrote simple app and asked him to run. This app does simple task and shows text on screen.
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
string = "GPS=on\n";
}
else
{
string = "GPS=off\n";
}
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
string += "Network=on\n";
}
else
{
string += "Network=off\n";
}
String status = android.provider.Settings.Secure.getString(getContentResolver(), Secure.LOCATION_PROVIDERS_ALLOWED);
if(status.contains("gps"))
{
string += "GPS=on\n";
}
else
{
string += "GPS=off\n";
}
if(status.contains("network"))
{
string += "Network=on\n";
}
else
{
string += "Network=off\n";
}
He sent back screen shot again. It looks;
GPS=on
Network=off
GPS=on
Network=on
This result did not make me happy. There could be some possibilities for this.
- As other person questioned before, this issue has been there on some phones.
- Google broke this with 4.1.2. isProviderEnabled does not work on this version.
- Although not documented, starting 4.1.2, isProviderEnabled won't work as it did before.
- No, Google changed anything. This is a bug for this particular phone.
Now my questions are;
- Is LocationManager.isProviderEnabled still valid for Android 4.1.2 and later?
- Does seeing Secure.LOCATION_PROVIDERS_ALLOWED have some drawbacks/pit holes (when I gave up using LocationManager.isProviderEnabled?
Thanks in advance.
EDIT1:
Here you can download test app from Google Play to try or ask someone to try.
EDIT6:
I removed test app since this question is answered.
EDIT2:
I released my app which checks network provider is usable by seeing Secure.LOCATION_PROVIDERS_ALLOWED and got exception on limited phones.
These are ACRA's report.
Some phone running OS 4.1.1.
java.lang.IllegalArgumentException: requested provider network doesn't exisit
at android.os.Parcel.readException(Parcel.java:1434)
at android.os.Parcel.readException(Parcel.java:1384)
at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:675)
at android.location.LocationManager._requestLocationUpdates(LocationManager.java:686)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:508)
Some phone running OS 4.1.2.
java.lang.IllegalArgumentException: provider=network
at android.os.Parcel.readException(Parcel.java:1439)
at android.os.Parcel.readException(Parcel.java:1389)
at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:659)
at android.location.LocationManager._requestLocationUpdates(LocationManager.java:690)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:512)
I have never seen those exceptions until I changed a method to check network provider for location is usable or not. So I think LocationManager.isProviderEnabled is safe and seeing Secure.LOCATION_PROVIDERS_ALLOWED is risky. But this will put me back to original issue. Why LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) returns false (and there is not really) when Secure.LOCATION_PROVIDERS_ALLOWED tells there IS. Is Android OS poorly designed? Or I have just seeing issues tied only to specific (but there are at least 2 of them) phones?
EDIT3:
I updated test app to show GPS/Network location provider seems really usable or not by accessing with requestLocationUpdates().
And I disclose 2 phones name.
1) SBM200SH, OS4.1.2, Softbank mobile, Sharp Corporation
2) HTX21 (INFOBAR A02), OS4.1.1, KDDI, HTC
EDIT4:
I found 3rd phone.
3) SBM203SH, OS4.1.2, Softbank mobile, Sharp Corporation
EDIT5:
Sharp Corporation is running discussion space for mobile developers. I posted topic by presenting this SO's question. I hope someone at Sharp Corporation takes action for this. I will keep this updated.
Source: (StackOverflow)
LocationManager locationManager = (LocationManager)getApp().getSystemService(Context.LOCATION_SERVICE); //getApp() returns my Application object
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER , 1, 1, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, this);
That's the code I'm using to listen. With GPS enabled, everything works fine. However, if I disable GPS and rely on network location, it gives me stale results -- in this case, from two days ago. I cannot get it to update. Calling getLastKnownLocation returns the same stale results.
Google Maps updates just fine, so I know it's not a hardware/system configuration problem.
I've Googled around, and found a few people with similar problems, but no answers. I've tried targeting my project to API level 8 (2.2) as well as 15 (4.0.3). Same results. My phone is running ICS.
I've also tried removing the request for GPS_PROVIDER, as well as including requests for everything in getAllProviders(). Same deal.
Any idea why NETWORK_PROVIDER is not updating? Any help would be greatly appreciated.
(P.S. No, I don't I normally use "1, 1" as my time/distance parameters; I just changed it while debugging this.)
EDIT: I forgot to mention that yes, isProviderEnabled() returns true.
Source: (StackOverflow)
I am developing an application that gets position of the cell phone all day long in 6 and 6 minutes in a service, it works fine but sometimes the method OnLocationChanged
of the Network provider listener stop to being called, and I don't know why.
It for some reason stop being called, but the Provider is enable and the Lister is working, when I Enable or disable the Provider manually, onProviderEnabled
and onProviderDisabled
is called.
It just happens with NETWORK_PROVIDER
, the GPS_PROVIDER
works well.
Listener:
LocationListener locationListenerGPS = new LocationListener() {
// @Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO locationListenerGPS onStatusChanged
Log.d(TAG, "Provedor trocado");
}
// @Override
public void onProviderEnabled(String provider) {
Log.w(TAG, "PROVEDOR " + provider + " HABILITADO!");
}
// @Override
public void onProviderDisabled(String provider) {
Log.w(TAG, "PROVEDOR " + provider + " DESABILITADO!");
}
// @Override
public void onLocationChanged(Location location) {
longitudeGPS = location.getLongitude();
latitudeGPS = location.getLatitude();
Log.d(TAG,"LocationChangedGPS LAT: "+latitudeGPS+" longi: "+longitudeGPS);
gpsComSinal = true;
}
};
LocationListener locationListenerNET = new LocationListener() {
// @Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO locationListenerNET onStatusChanged
Log.d("Contele", "Provedor foi mudado");
}
// @Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "PROVEDOR " + provider + " HABILITADO!");
}
// @Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "PROVEDOR " + provider + " DESABILITADO!");
}
@Override
public void onLocationChanged(Location location) {
longitudeNET = location.getLongitude();
latitudeNET = location.getLatitude();
Log.d(TAG,"LocationChangedNET LAT: "+latitudeNET+" longi: "+longitudeNET);
netComSinal = true;
}
};
Code:
public void initProviders() {
localizacao = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
localizacao.removeUpdates(locationListenerNET);
localizacao.removeUpdates(locationListenerGPS);
localizacao.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locationListenerGPS);
localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
0, locationListenerNET);
Log.d(TAG,"EsperaGPS");
Handler esperaGPS = new Handler() {
public void handleMessage(Message msg) {
requestGPS();
}
};
Message msgEsperaGPS = Message.obtain();
msgEsperaGPS.what = 0;
esperaGPS.sendMessageDelayed(msgEsperaGPS, 35000);
}
public void requestGPS() {
if (gpsComSinal) {
Log.d(TAG,"PEGO SINAL DE GPS");
rastreio = "GPS";
longitude = longitudeGPS;
latitude = latitudeGPS;
Log.d(TAG, "Utilizando provedor GPS.");
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
} else {
Log.d(TAG,"Sem GPS... pegar NEt");
// Setando os valores para usar network
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
localizacao
.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0, 0, locationListenerNET);
Log.d(TAG,"EsperaNET");
requestNET();
}
}
public void requestNET() {
if (netComSinal) {
Log.d(TAG,"PEGO SINAL DE NET");
rastreio = "NET";
longitude = longitudeNET;
latitude = latitudeNET;
Log.d(TAG, "Utilizando provedor NET.");
localizacao.removeUpdates(locationListenerNET);
} else {
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
Log.d(TAG,"Sem sinal");
}
}
Report in a Samsung Galaxy S3:
Still getting "Sem sinal" for 4 days in a row.
This issue have already happened with Galaxy Y and LG Optimus l5
I have made another test to see if other aplications got the NET positions, and I discovered that they are passing for the same problem, they can't get the NET position just the GetLastknowLocation; to test that I used a Galaxy S3 with this problem, and I disabled the GPS Provider. (Tested in Cerberus).
I couldn't find any explanation for why NETWORKSLOCATIONS listener stop giving positions, but it might be because it shouldn't work for 2 or 3 days without stop.
I have done some tests with other aplications to see if this issue is just happening with my aplication, and I discovered that they are passing for same problem, like in Cerberus for example :
I disable the GPS Provider in a cellphone (Galaxy S3) with the "Sem sinal" problem, take a look:
My report:
And Cerberus(print taken in 14/05/2013) report:
But When I opened the Google Maps it seems to work OK, I tried to move to a distance place to see if it going to show the GetLastknowLocation
, but no, google maps put me in the right place in the moment, so I realized that Google Maps was using motionevent to move me in the map;
And also print the Log of Google Maps to get NetWorkProvider:
Normal case:
Sem sinal case:
Source: (StackOverflow)
I am trying to get the users current location using the LocationManager
. I have done a lot of research and can't seem to find anyone with the same problem. The OnLocationChanged
callback never seems to be called. Below is my various code and the logcat.
protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;
My OnCreate()
method
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "IN ON CREATE");
this.context = getActivity();
registerLocationUpdates();
}
My registerLocationUpdates
method
void registerLocationUpdates() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_LOW);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);
provider = locationManager.getBestProvider(criteria, true);
// Cant get a hold of provider
if (provider == null) {
Log.v(TAG, "Provider is null");
showNoProvider();
return;
} else {
Log.v(TAG, "Provider: " + provider);
}
locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);
// connect to the GPS location service
Location oldLocation = locationManager.getLastKnownLocation(provider);
if (oldLocation != null) {
Log.v(TAG, "Got Old location");
latitude = Double.toString(oldLocation.getLatitude());
longitude = Double.toString(oldLocation.getLongitude());
waitingForLocationUpdate = false;
getNearbyStores();
} else {
Log.v(TAG, "NO Last Location found");
}
}
My LocationListener
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
latitude = Double.toString(location.getLatitude());
longitude = Double.toString(location.getLongitude());
Log.v(TAG, "IN ON LOCATION CHANGE");
if (waitingForLocationUpdate) {
getNearbyStores();
waitingForLocationUpdate = false;
}
locationManager.removeUpdates(this);
}
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.v(TAG, "Status changed: " + s);
}
public void onProviderEnabled(String s) {
Log.e(TAG, "PROVIDER DISABLED: " + s);
}
public void onProviderDisabled(String s) {
Log.e(TAG, "PROVIDER DISABLED: " + s);
}
}
My permissions in the AndroidManifest
<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" />
And finally the logcat after I run my app
01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3
And the android SDK location parts of the logcat keep repeating them selves. I have tried everything that i can think of and have seen on google and stackoverflow. Als just as a side note i have been able to get it to work on a 2.3 device using the requestSingleUpdate
which is available in API 9 and by following the guide A Deep Dive into Location but i need it to work on 2.1 or 2.2 and higher using the old SDK. SO if you have any hints or would like to know more please let me know. Thanks in advance.
Source: (StackOverflow)
I am trying to implement the suggestions given in this post.
Unfortunately the steps are not clear to me. I tried implementing those suggestions, but the backgroundTimeRemaining continues to decrease even after I start and stop locationServices. This is how I developed it:
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
self.timer = nil;
[self initTimer];
});
}
initTimer:
- (void)initTimer {
// Create the location manager if this object does not
// already have one.
if (nil == self.locationManager)
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startMonitoringSignificantLocationChanges];
if (self.timer == nil) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3
target:self
selector:@selector(checkUpdates:)
userInfo:nil
repeats:YES];
}
}
checkUpdates:
- (void)checkUpdates:(NSTimer *)timer{
UIApplication* app = [UIApplication sharedApplication];
double remaining = app.backgroundTimeRemaining;
if(remaining < 580.0) {
[self.locationManager startUpdatingLocation];
[self.locationManager stopUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
DbgLog(@"Reminaing %f", app.backgroundTimeRemaining);
}
Does anyone have a suggestion on what might be wrong in my code? Both initTimer and checkUpdates are being called, but only during for the background execution time (+- 10 Mins). I want the app to update the location every n minutes "forever".
My app's UIBackgroundModes is set to location.
UPDATE:
I am now resetting the timer on didUpdateToLocation and didFailWithError. But still the backgroundTimeRemaining keeps decreasing:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"Did Update Location = %f / %f", [newLocation coordinate].latitude, [newLocation coordinate].longitude);
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
[self initTimer];
});
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[self.locationManager stopUpdatingLocation];
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
[self initTimer];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
});
}
I am also invalidating the timer:
- (void)checkUpdates:(NSTimer *)timer{
UIApplication* app = [UIApplication sharedApplication];
double remaining = app.backgroundTimeRemaining;
if(remaining < 580.0 && remaining > 570.0) {
[self.timer invalidate];
self.timer = nil;
[self.locationManager startUpdatingLocation];
[self.locationManager stopUpdatingLocation];
}
DbgLog(@"*************************Checking for updates!!!!!!!!!!! Reminaing %f", app.backgroundTimeRemaining);
}
Source: (StackOverflow)
Don't know why, but sometimes LocationManager is still working also after closing application.
I call startGPS() in onCreate-Methode in one Activity (only one, let me call it StartActivity).
protected void startGPS()
{
try
{
lmanager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lmanager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
lmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
catch(Exception e)
{
e.printStackTrace();
}
}
And if this activity will be destroyed (so, when application will be closed), I call endGPS()
public void endGPS()
{
try
{
lmanager.removeUpdates(this);
lmanager=null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
Some ideas, some suggestions, what have I done wrong?!
Source: (StackOverflow)
I have a class that extends Fragment and implements LocationListener.
When I write
LocationManager myLocalManager =
(LocationManager)getSystemService(Context.LOCATION_SERVICE);
I get an compile time error because the method getSystemService
is not a method of Fragment.
What can I do in order to create the LocationManager
?
Source: (StackOverflow)
At first glance in the code below the mLocationManager
object should go out of scope after onCreate(...)
is finished, and the expected behaviour is that onLocationChanged
is never called or called a few times until the object is garbage collected. However the object returned by the getSystemService
seems to be singleton which lives outside the scope of MainActivity
(appropriately so since it is a system service :) )
After taking a heap dump and going through it with the Eclipse Memory Analyzer it seems that ContextImpl keeps a reference to a LocationManager instance. In the memory dump there were two references to a LocationManager object while in the code there is clearly only one, which means that another reference is created somewhere else.
My questions are:
Does someone have a complete description of what is exactly happening when calling the implementation of:
public abstract Object getSystemService(String name);
is the object returned a singleton lazily created and where exactly is the reference created/kept ?
package com.neusoft.bump.client.storage;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("TAG", "STARTED");
LocationManager mLocationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.v("TAG", "onLocationChanged");
Log.v("TAG", "Latitude: " + location.getLatitude()
+ "Longitude: " + location.getLongitude());
}
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
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
600, 0, locationListener);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Update1
The LocationManager
is created as singleton
private LocationManager getLocationManager() {
synchronized (sSync) {
if (sLocationManager == null) {
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
ILocationManager service = ILocationManager.Stub.asInterface(b);
sLocationManager = new LocationManager(service);
}
}
return sLocationManager;
}
but I have trouble understanding what happens when calling ServiceManager.getService(LOCATION_SERVICE);
even after reading the ServiceManager
code.
Source: (StackOverflow)
This question is directly related to the same prevailing stackoverflow question at "Android: get current location of user without using gps or internet" where the accepted answer is actually not answering the question.
I should be able to get the current location name (eg:city name, village name) of the device via network provider not with GPS or internet.
Following is the accepted answer in that question. (The following code parts should be included in the onCreate()
method)
// 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);
I changed the above code given in the linked answer as following but no success.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView txtView = (TextView) findViewById(R.id.tv1);
txtView.setText("ayyo samitha");
////
// Acquire a reference to the system Location Manager
LocationManager 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);
}
private void makeUseOfNewLocation(Location location) {
txtView.setText("sam came in");
txtView.append(location.toString());
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {
// makeUseOfNewLocation(location);
}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
}
How to accomplish what I want by correcting above code or any other method? Note that I want to get the location name, but not the longitudes and latitudes. Can somebody please help me.
Source: (StackOverflow)
Writing a GPS logging application~
I'm finding the values returned by the getSpeed()
method on Locations
reported by LocationManager
are massively unreliable. I'm using LocationManager.GPS_PROVIDER
, filtering the Locations provided through onLocationChanged
for best accuracy. Even at single digit accuracy levels the speed returned is generally ridiculously high. We're talking up to 200 mp/h (yes I know it's logged in metres/sec) when the phone is stationary.
I'm testing the same code base on two different model Android phones, running two different OS versions, and seeing the same issues so I expect this is a code issue.
What am I missing? I've tried averaging locations over a window of time, to no avail. Am I going to have to work out my own speed values based on distance travelled / time? This would be disappointing.
As you will see, I'm not doing anything special - a little filtering for accuracy, even after this both AverageSpeed
and _bestLocation.getSpeed()
are regularly unfeasibly high, even when accuracy of the location is good.
public void onLocationChanged(Location location) {
if (location.getAccuracy() < 25f) {
_recentLocations.add(location);
if (_bestLocation == null || location.getAccuracy() <= _bestLocation.getAccuracy())
_bestLocation = location;
}
if ((_bestLocation != null && _bestLocation.getAccuracy() < 10f && _recentLocations.size() >= 10)
|| _recentLocations.size() >= 25)
{
int Count = 0;
float TotalSpeed = 0f;
float AverageSpeed = 0f;
for (int i = 0; i<_recentLocations.size(); i++) {
if (_recentLocations.get(i).hasSpeed()) {
Count++;
TotalSpeed += _recentLocations.get(i).getSpeed();
}
}
if (Count > 0)
AverageSpeed = TotalSpeed / Count;
}
}
Source: (StackOverflow)
Plain and simple. I start an Activity and check if the phone has the GPS module enabled or not. If it isn't enabled, I prompt the user with a dialog and ask if he wants to manually enable it. On Yes I activate the Settings for Location. Now the user can enable it if he wants to, but I need to check what he has done.
try {
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {}
if (isGPSEnabled) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"Your GPS module is disabled. Would you like to enable it ?")
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
// Sent user to GPS settings screen
final ComponentName toLaunch = new ComponentName(
"com.android.settings",
"com.android.settings.SecuritySettings");
final Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(toLaunch);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, 1);
dialog.dismiss();
}
})
.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
I need to know what the user has chosen in Location settings, when he comes back in order to proceed with my logic in code. Basically I need to wait for the user to make a choice and return to my activity, and also to recheck the status of gps module again.
Source: (StackOverflow)
Is there a way to access the GPS once instead of having a looper that constantly checks for location updates?
In my scenario all I'm interested in is finding the current co-ordinates and not a continuous connection with the GPS satellite. Does anyone have any ideas how this can be done? Thanks in advance.
Source: (StackOverflow)
I am developing the Location Tracking application. But i am stopping getting the location update by doing 2 things...
- locationManager.removeUpdates(this); and
- setting locationManager reference to null.
This will stop getting location co-ordinates as i want...
But the problem is the gps icon is still blinking.. which will draining the device's battery.
So please help me in stopping this GPS fixes...
Source: (StackOverflow)
I am writing a code that brings current location but it is not giving me the location because it never calls onLocationChanged()
.Is there any way to find the location.
mobileLocation is coming 0 for this case, so the execution goes to the else block.
My code is
public class FindLocation {
private LocationManager locManager;
private LocationListener locListener;
private Location mobileLocation;
private String provider;
public FindLocation(Context ctx){
locManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
locListener = 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(Location location) {
System.out.println("mobile location is in listener="+location);
mobileLocation = location;
}
};
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locListener);
if (mobileLocation != null) {
locManager.removeUpdates(locListener);
String londitude = "Londitude: " + mobileLocation.getLongitude();
String latitude = "Latitude: " + mobileLocation.getLatitude();
String altitiude = "Altitiude: " + mobileLocation.getAltitude();
String accuracy = "Accuracy: " + mobileLocation.getAccuracy();
String time = "Time: " + mobileLocation.getTime();
Toast.makeText(ctx, "Latitude is = "+latitude +"Longitude is ="+londitude, Toast.LENGTH_LONG).show();
} else {
System.out.println("in find location 4");
Toast.makeText(ctx, "Sorry location is not determined", Toast.LENGTH_LONG).show();
}
}
}
Source: (StackOverflow)