Hello I have implemented a service that broadcasts the current location. the thing is the first time it updates it gives me 0.0 lat and 0.0 lon, which ruins the UI.how can I fix this?
Here is the code, thank you
public class LocationService extends Service {
protected LocationManager locationManager;
final static String MY_ACTION = "MY_ACTION";
MyLocListener myloc = new MyLocListener();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override public void onDestroy() {
};
#Override
public int onStartCommand(Intent intent, int flags, int startId){
final Criteria criteria = new Criteria();
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(true);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(true);
LocationListener ll = new MyLocListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 0, ll);
Location location = new Location("abc");
ll.onLocationChanged(location);
Log.d("Last", ""+location.getLatitude());
return START_STICKY;
}
private class MyLocListener implements LocationListener {
public void onLocationChanged(Location location) {
Log.d("1provider",location.toString());
Log.d("1Provider LOCATION CHANGED", location.getLatitude() + "");
Log.d("1Provider LOCATION CHANGED", location.getLongitude() + "");
Intent intent = new Intent();
intent.putExtra("location", location);
intent.setAction(MY_ACTION);
sendBroadcast(intent);
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
Log.d("1Provider DIsabled", "Provider Disabled");
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
Log.d("1Provider Enabled", "Provider Enabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
Log.d("1Provider Changed", "Service Status Changed");
}
}
}
The onLocationChanged() method usually returns 0 on the first occasion - just check for this value and don't update the UI. As to it taking too long, it can take a while so run your service as an AsyncTask when getting the location, so that your UI thread is waiting around, and then update the UI when you get a return from the AsyncTask.
Related
I have an android device that is mounted inside a car.
I need to receive gps location updates every second.
my problem is that I get all the necessary data (number of satellites , coordinates , time etc .. )
but for some reason "GpsStatus.GPS_EVENT_FIRST_FIX" is not called or if is called it takes a long time (like 30 minutes .. )
why is that ? here is my code :
public class ExtProtocolService extends Service implements GpsStatus.Listener {
private GpsStatus gpsStatus;
private GpsData gpsData;
private LocationManager locationManager;
private LocationListener locationListener;
#Override
public void onCreate() {
locationManager = (LocationManager)
getSystemService(this.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = locationManager.getBestProvider(criteria, true);
if(provider.equals("gps"))
{
locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
// not used
}
#Override
// not used
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
// update location parameters when location is changed
#Override
public void onLocationChanged(Location location) {
gpsData.setLatitude(location.getLatitude());
L.m("LATLONG", "latitude " + location.getLatitude());
gpsData.setLongitude(location.getLongitude());
L.m("LATLONG", "longitude " + location.getLongitude());
gpsData.setSpeed(location.getSpeed());
gpsData.setHeading(location.getBearing());
gpsData.setAltitude(location.getAltitude());
gpsData.setHdop(location.getAccuracy());
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
1000, 0, locationListener); // update location every 1000 ms
locationManager.addGpsStatusListener(this);
}
}
#Override
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_FIRST_FIX:
gpsData.setLocked(true); // gps is locked
break;
case GpsStatus.GPS_EVENT_STOPPED:
gpsData.setLocked(false); // gps unreachable
break;
}
gpsStatus = locationManager.getGpsStatus(null);
// calc number of satelites fixed
Iterable<GpsSatellite> sats = gpsStatus.getSatellites();
int satellites = 0;
int satellitesInFix = 0;
int timetofix = gpsStatus.getTimeToFirstFix();
for (GpsSatellite sat : sats) {
if (sat.usedInFix()) {
satellitesInFix++;
}
satellites++;
}
gpsData.setNumSatellites(satellitesInFix);
L.m("GPS", gpsData.toString());
}
}
edit : also I can not use the google location API's ..
I'm writing an app that requests for location updates like this:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, interval, 0, locationListener);
onLocationChanged gets invoked when device is on but when put into sleep it stops receiving further updates. I followed this thread but as I said - it doesn't work.
The listener is registered inside foreground service that needs to work all the time. I want to conserve battery by waking it from sleep only when I receive new location.
EDIT: of course everything works when I acquire wakelock in onCreate() method and release it in onDestroy() method for service but I don't want to do this.
If you want to use background task then use this service
public class LocationFinder extends Service {
public static double lat, lng;
LocationManager locationManager;
public void onDestroy() {
super.onDestroy();
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
}
}
#Override
public void onCreate() {
Log.v("location", "===>location ed onCreate " + lat);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.v("location", "===>location ed onStartCommand " + lat + "==>" + lng);
new Handler().post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
getLocation();
}
});
return START_STICKY;
}
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
private void getLocation() {
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
if (locationManager != null) {
String provider = locationManager.getBestProvider(criteria, true);
if (provider != null) {
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
locationManager.requestLocationUpdates(provider, 500, 50, locationListener);
} else {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 500, 50, locationListener);
}
}
}
}
private void updateWithNewLocation(Location location) {
if (location != null) {
Log.v("location", "===>location ed " + lat);
lat = location.getLatitude();
lng = location.getLongitude();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
I'm trying to program an application which is using the current location from the user and calculating the distance and writes it into my listview.
The location doesn't have to be very accurate and i only want to fetch a new location when the list is refreshed or on app start, not continously.
My problem is that the locationlistener with gps takes too long to find a location and i have to update my list a lot before it is showing the right distance.
I was thinking about implementing a background task which gets the location and updates the list automatically when it found the position. Would that be a solution?
Is there any option to get a location faster, even if it is not as accurate as gps?
what i have so far on my location listener:
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
myLoc.setLatitude(lat);
myLoc.setLongitude(lng);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
in this method i'm calling the locationmanager and listener and creating the listview with the distance
public void getList(){
locationManager = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
//... creating the list with distance and so on
}
i hope you can give me some hints how i can implement this that i will work as described above or tell me what i should use instead.
thanks :)
1). You can use LocationManager.NETWORK_PROVIDER
This provider determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup. Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION.
eg:- locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 50, locationListener);
2). If you want to use background task then use this service
public class LocationFinder extends Service {
public static double lat, lng;
LocationManager locationManager;
public void onDestroy() {
super.onDestroy();
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
}
}
#Override
public void onCreate() {
Log.v("location", "===>location ed onCreate " + lat);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.v("location", "===>location ed onStartCommand " + lat + "==>" + lng);
new Handler().post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
getLocation();
}
});
return START_STICKY;
}
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
private void getLocation() {
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
if (locationManager != null) {
String provider = locationManager.getBestProvider(criteria, true);
if (provider != null) {
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
locationManager.requestLocationUpdates(provider, 500, 50, locationListener);
} else {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 500, 50, locationListener);
}
}
}
}
private void updateWithNewLocation(Location location) {
if (location != null) {
Log.v("location", "===>location ed " + lat);
lat = location.getLatitude();
lng = location.getLongitude();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
I try to retrieve Location updates in Service by network provider, but the updates doesn,t perform. My code looks like this:
public class TimeService extends Service{
LocationManager lm;
LocationListener ll = new LocationListener()
{
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longtitude = location.getLongitude();
Intent inte =new Intent( TimeService.this, myAppWidgetProvider.class);
inte.setAction("action_location");
inte.putExtra("lat", latitude);
inte.putExtra("long", longtitude);
PendingIntent pinte = PendingIntent.getBroadcast(TimeService.this, 0, inte, 0);
try {
pinte.send();
} catch (CanceledException e) {
// TODO Auto-generated catch block
Log.d("sendPIException", ":-(");
}
Log.d("locReceived", "onLochanged");
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
};
Log "locReceived" in onLocationChanged doesn't appear i logcat
Following code responsible for Location in my Service, too:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.registerReceiver(br, new IntentFilter(Intent.ACTION_TIME_TICK));
lm =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll);
return super.onStartCommand(intent, flags, startId);
}
What's wrong in my code?
Criteria criteria = new Criteria();
String provider = lm.getBestProvider(criteria, false);
Location location = lm.getLastKnownLocation(provider);
lm.requestLocationUpdates(provider, 0, 0, ll);
if (location == null) {
Log.e("Impl", "Location not available");
}
I am using location listener in my app.
I have the code like:
public void startlistning()
{
locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
Toast.makeText( getApplicationContext(),"Gps Enabled", Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
Toast.makeText( getApplicationContext(),"Gps Disabled", Toast.LENGTH_SHORT ).show();
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
location.getLatitude();
location.getLongitude();
}
};
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
But don't know why the method onLocationChanged did not call when I restart device 1st time (without cellular data (no simcard) available). however, I am using best provider in my app.
Please look into matter. Thanks
Location listener method call when you change the location of device . Its not start when you restart device . If you want to invoke onLocationChanged method you have to change the location of device .
Please try this to get last known location.
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Criteria locationCritera = new Criteria();
locationCritera.setAccuracy(Criteria.ACCURACY_FINE);
locationCritera.setAltitudeRequired(false);
locationCritera.setBearingRequired(false);
locationCritera.setCostAllowed(true);
locationCritera.setPowerRequirement(Criteria.NO_REQUIREMENT);
String providerName = locationManager.getBestProvider(locationCritera, true);
Location location = locationManager.getLastKnownLocation(providerName);
Log.i("--- Latitude",""+location.getLatitude());
Log.i("--- Latitude",""+location.getLongitude());