What is the best way to track the latitude / longitude of the device in Android. I've tried many methods, non of which are working at all.
My device is running Android 4.1.2.
In my current code, sometimes GPS will work perfectly fine but sometimes it won't work (giving me latitude 0 and longitude 0).
Here is my current code:
locationManager = mLocationManager;
locationListener = new LocationListener() {
/**
* Fired when the location from the sensor changes.
*
* #param location Location object.
*/
#Override
public void onLocationChanged(Location location) {
sLatitude = String.valueOf(location.getLatitude());
sLongitude = String.valueOf(location.getLongitude());
sLatLon = sLatitude.concat(",").concat(sLongitude);
Log.d("TOMTOM LOCATION", location.toString());
}
/**
* Fired when the provider's status changes.
*
* #param provider The provider that has changed status.
* #param status The new status of the provider.
* #param extras Any extra data.
*/
public void onStatusChanged(String provider, int status, Bundle extras) {
// Do nothing.
}
/**
* Fired when the provider has been enabled.
*
* #param provider Provider that has been enabled.
*/
#Override
public void onProviderEnabled(String provider) {
// Do nothing.
}
/**
* Fired when the provider has been disabled.
*
* #param provider Provider that has been disabled.
*/
#Override
public void onProviderDisabled(String provider) {
// Do nothing.
}
};
Log.d("TOMTOM", locationManager.getProviders(true).toString());
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Log.d("TOMTOM", "GPS enabled");
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.d("TOMTOM", "Request GPS updates");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else {
Log.d("TOMTOM", "Request network updates");
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
} else {
Log.d("TOMTOM", "Fail");
}
}
} else {
Log.d("TOMTOM", "GPS disabled");
Log.d("TOMTOM", "Request network updates");
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
} else {
Log.d("TOMTOM", "Fail");
}
}
Any ideas why sometimes I get GPS updates (Logged as Request GPS updates) and sometimes it will fail completely (Logged as Fail)?
It's been a year or so since I did GPS stuff on Android, so bear with me if I am not entirely right. Maybe someone can correct me.
The GPS system is not instant. You can not start your application and expect to have a location instantly. I believe the reason you get to the log telling you it's a Fail simply is because Android does not always have a last known location. So you can get in situations where GPS is neither available (In buildings for example) where you also don't have a meaningful last known location. In this case it will simply be null.
Related
I am getting longitude=0.0 and latitude=0.0 on tablet while this is working perfectly on the phone.
I am using LocationManager.NETWORK_PROVIDER and not the GPS_PROVIDER so what could be the cause please?
Logcat output??
that's my code:
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
longitude=location.getLongitude();
latitude=location.getLatitude();
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
//Or use LocationManager.GPS_PROVIDER
String locationProvider = LocationManager.NETWORK_PROVIDER;
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
if(lastKnownLocation!=null){
longitude=lastKnownLocation.getLongitude();
latitude=lastKnownLocation.getLatitude();
}
Check out Location settings inside your device settings. This seems not a problem with your code, but your device settings. In my Ginger bread, it's as:
Settings -> Location&security -> Use wireless networks
I have tried to do my research about GPS issues before posting here. When I tested my code It repeats the same output over and over. The method gpsStart() is called on a timer. Fine and Coarse location permissions have been added to the manifest. The method appendLog() stores the output in a file.
public void gpsStart() {
// 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) {
// Toast.makeText(getApplicationContext(), "location changed",
// Toast.LENGTH_SHORT).show();
// Called when a new location is found by the network location
// provider.
appendLog("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude()+"\n");
text3.setText("Lat: " + location.getLatitude() + "\nLng: "
+ 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
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
You must not call gpsStart() method in the timer. I am going to say how Location Listener works
What is Location Listener?
Location Listener is the class which notify you when your current location will be change. For receive the location updates you will have to register LocationListener class using LocationManager class.
When to register Location Listener?
It depends on the requirement of your application. For example if you want location listener for display current location on map then you should register Location Listener in onCreate() or onResume() method of the activity and unregister receiver in onPause() or onStop() method. If you want to receive the location even if your application is not running then you can use a service to receive location.
How to Register/Unregister Location Listener?
To register the LocationListener you first need the instance of the LocationManager class which you can get using the context like
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
After then you will have to set the location provider. There are 2 types of providers which are often used.
GPS provider
Network Provider
Now to register the location receiver with this location provider there is a method requestLocationUpdates of LocationManager. In this method first argument is the provider name second argument is the minimum time for request location update. Third argument is the minimum distance to request for the location change.Last argument is for locationListener.
Here how you can use the method
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, minTime, minDistance, locationListener);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, minTime, minDistance, locationListener);
To unRegister location updates you can use the below method
locationManager.removeUpdates(locationListener)
Note: You are calling a method gpsStart in the timer as you have mentioned in your question so it is adding location listener each time when this method calls.So all the listeners are triggering you the new location so probably you are getting same location multiple times. Instead of it, you should call this method once when your activity starts and unRegister this locationListener when your activity finish.
Hopes you are getting. :D
Enjoy!!!
Better you create a 2 listeners.1 for Gps and other for network.
the following are code samples
public class MyLocationListener extends LocationListener
{
public void onLocationChanged(Location location)
{
// Toast.makeText(getApplicationContext(), "location changed",
// Toast.LENGTH_SHORT).show();
// Called when a new location is found by the network location
// provider.
appendLog("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude()+"\n");
text3.setText("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude());
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
}
MyLocationListener gpsListener=new MyLocationListener();
MyLocationListener networkListener=new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpslocationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networklocationListener);
Thank you very much for your answers. Dharmendra you are correct, I did need to close the LocationListeners, however the answer to my question was much simpler. I needed to change the minimum time (the time the listener waits to get an answer) to a value above zero. The value I needed to change is shown in bold below (MINTIME).
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINTIME, 0, gpslocationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MINTIME, 0, networklocationListener);
I have tried both GPS and Network Provider but they give null location for getLastKnownLocation. I do not get any onLocationChanged either. I am trying from my apartment where the cell signal is strong. I can even browse internet well and download and install apps fine from market.
I have read few threads on same topic but their suggestion seems I already have tried.
Here is my code snippet.
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if(null == locationManager) {
Log.d(TAG, "location manager NULL");
}
geocoder = new Geocoder(this);
// Initialize with the last known location
Location lastLocation = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (lastLocation != null)
onLocationChanged(lastLocation);
else
Log.i(TAG, "null LastKnownLocation");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
super.onStartCommand(intent, flags, startId);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0,0, this);
Log.d(TAG, "requested location updates");
return START_STICKY;
}
As per log:
mitenm#pinkydebian:/media/sf_E_DRIVE/tmp$ adb logcat LocationNotifierService:* *:S
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
I/LocationNotifierService(30866): null LastKnownLocation
D/LocationNotifierService(30866): gps provider enabled:true
D/LocationNotifierService(30866): network provider enabled:true
D/LocationNotifierService(30866): onCreate
D/LocationNotifierService(30866): requested location updates
D/LocationNotifierService(30866): requested location updates
D/LocationNotifierService(30866): requested location updates
I have "unlock receiver" so when I unlock my screen I request location updates which is working as expected from logs. But the onLocationChanged method is not getting invoked.
I have permission added to manifest both for fine and coarse.
Regards,
Miten.
android getLaskKnownLocation null
As Per Google Doc
getLaskKnownLocation Returns a Location indicating the data from the last known location fix obtained from the given provider otherwise it returns null.
It means it shows the cached data.If you are running your application on device which has never queried for location data before will have empty cache thats why you are getting null.
do not get any onLocationChanged either.
Make sure you have enabled Network Provider for location.
Use below Snippet.
if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected() || connectivityManager.getNetworkInfo(
ConnectivityManager.TYPE_WIFI).isConnected()) {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Constants.CONNECTED = true;
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 5000, 1, this);
} else {
Constants.CONNECTED = false;
Toast.makeText(
context, "Please enable Wireless networks in Location Setting!!", 10000).show();
}
}
I got a weird problem. I uses wifi to retrieve user location. I have tested on several phones; on some of them, I could never get a location update. it seemed that the method onLocationChanged is never called. My code is attached below.. Any suggestions appreciated!!!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager locationManager;
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.NETWORK_PROVIDER;
Location l = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(l);
locationManager.requestLocationUpdates(provider, 0, 0,
locationListener);
}
private void updateWithNewLocation(Location location) {
TextView myLocationText;
myLocationText = (TextView)findViewById(R.id.myLocationText);
String latLongString = "No location found";
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
Log.i("onLocationChanged", "onLocationChanged");
Toast.makeText(getApplicationContext(), "location changed",
Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status,
Bundle extras) {}
};
Manifest
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
My guess is that the phones on which you don't get location updates from do not have proper data connection. Network Provider needs GSM/3G or WiFi data connection to retrieve a location fix from Google servers using phones's cell/wifi data. You can use the method below to check this.
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
Please check that your onProviderDisabled method is not being called immediately.
If you find it is being called as soon as your provider registers, it means that the phone you're on has location services disabled.
It's my suspicion now that Google Location Services were down in select areas. My app started working again with no changes to the code (the apk from the Play Store).
I too faced the same issue with NetworkProvider while testing in ICS(4.0) but working fine in older versions(2.2 and 2.3.3 i tested). Here is the solution i found and working fine in ICS as well. Please use the Criteria for getting the location updates as below:
LocationManager locationManager= (LocationManager) <YourAct>
.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); //ACCURACY_COARSE or ACCURACY_FINE based on usage
String provider = locationManager.getBestProvider(criteria, true);
// Register the listener with the Location Manager to receive location
// updates
locationManager.requestLocationUpdates(provider, 0, 0, locationListener);
Replace the code as above. This will help u in getting the location updates.
I had the very same problem and in turns out that onLocationChanged is not called if there is getLastKnownLocation which is the same as "current". That means that you will not get new location because there is nothing new to report...
Solution is to use the last known location even it is very old (and continue to listen for updates if you need more precise/new location (if such occurres)).
Hai i develop a application for getting the Gps value its woking fine.But i faced some problem
problem
1.when mobile is screen locked
2.when mobile is swtched off into switch on
3.when mobile display light is off
MyRequirements
Anytime i want to get the gps value ,except the mobile is switched of
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
networkLoc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (networkLoc != null) {
double l = (double) (networkLoc.getLatitude());
double lng11 = (double) (networkLoc.getLongitude());
latituteField1.setText(Double.toString(l));
longitudeField1.setText(Double.toString(lng11));
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
this
);
}
#Override
protected void onPause() {
super.onPause();
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
this
);
}
#Override
public void onLocationChanged(Location location) {
lat1 = (double) (networkLoc.getLatitude());
lng1 = (double) (networkLoc.getLongitude());
latituteField1.setText(Double.toString(lat1));
longitudeField1.setText(Double.toString(lng1));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disenabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
Usually the device powers down the screen after some time and than also the CPU. If this happens you will not get any more updates from the GPS. To prevent this behavior you need to aquire a WakeLock.
Wakelocks are described here: http://developer.android.com/reference/android/os/PowerManager.html
And here is another article on WakeLocks: How to get an Android WakeLock to work?
You can use TimerTask Class and Android's Alarm Class. In the TimerTask's Run method keep fetching gps data on particular interval ( suppose on every minute ). And use Alarm Class for closing LocationListener Class & Opening on every hour. This way your application will work very efficiently. I used same for my application. For Auto start on Switch on Mobile, you can use Android Services.
TimerTask's Example is here.
AlarmManager's Example is here.