I want to implement whenever I launch my android
application,that time I want to start gps,
Whenever I close
application, I want to stop gps in device. How to implement
this concept in my application ?
The most important thing is to remove the LocationListener in all onPause methods of your Activities. You then can restart the listening in your onResume methods.
If you don't remove the listener in the onPause method the GPS will be active even if your app is the paused in the background. See the activity lifecycle for more information.
John, you need to use the LocationManager class. Here is a tutorial on how to get the users location.
First add bellow Class and interface to your application.
public class GPSManager
{
private static final int gpsMinTime = 500;
private static final int gpsMinDistance = 0;
private LocationManager locationManager = null;
private LocationListener locationListener = null;
private GPSCallback gpsCallback = null;
public GPSManager()
{
locationListener = new LocationListener()
{
public void onProviderDisabled(final String provider)
{
}
public void onProviderEnabled(final String provider)
{
}
public void onStatusChanged(final String provider, final int status, final Bundle extras)
{
}
public void onLocationChanged(final Location location)
{
if (location != null && gpsCallback != null)
{
Log.e("if location "+location,"if gpscallback"+gpsCallback);
gpsCallback.onGPSUpdate(location);
}
else{
Log.e("else location "+location,"else gpscallback"+gpsCallback);
}
}
};
}
public void startListening(final Activity activity)
{
if (locationManager == null)
{
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
final String bestProvider = locationManager.getBestProvider(criteria, true);
if (bestProvider != null && bestProvider.length() > 0)
{
locationManager.requestLocationUpdates(bestProvider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
else
{
final List<String> providers = locationManager.getProviders(true);
for (final String provider : providers)
{
locationManager.requestLocationUpdates(provider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
}
}
public void stopListening()
{
try
{
if (locationManager != null && locationListener != null)
{
locationManager.removeUpdates(locationListener);
}
locationManager = null;
}
catch (final Exception ex)
{
}
}
public void setGPSCallback(final GPSCallback gpsCallback)
{
this.gpsCallback = gpsCallback;
}
public GPSCallback getGPSCallback()
{
return gpsCallback;
}
}
Interface:
public interface GPSCallback
{
public abstract void onGPSUpdate(Location location);
}
then implement this interface in your activity and also add below code in your activity
gpsmanager=new GPSManager();
gpsmanager.startListening(YourActicvityname.this);
gpsmanager.setGPSCallback(this);
To stop GPS call gpsmanager.stopListening() at where you want to close the application
Related
Here is my code. Actually, I want to use this service to get user's fresh coordinates. In my test it didn't work well. I didn't get a good location. And it seem never call mobile's GPS to update the coordinates. Is my code has bug or my phone has problem? Thanks
public class LocationService extends Service implements LocationListener {
Boolean isWifiEnable;
Boolean isGPSEnable;
Context context;
Location location;
private static final long MIN_DISTANCE = 10;
private static final long MIN_TIME = 1000 * 60;
public LocationService(Context context) {
this.context = context;
bestLastKnownLocation();
}
public Location getLocation() {
return location;
}
public Location bestLastKnownLocation() {
location = null;
String provider = null;
// Acquire a reference to the system Location Manager
LocationManager lm = (LocationManager) context.getSystemService(LOCATION_SERVICE);
// location = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
isGPSEnable = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
isWifiEnable = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
// Define a listener that responds to location updates
if (isGPSEnable == false && isWifiEnable == false) {
// no network provider is enabled
//showToastInAsync("No provider");
} else {
if (isWifiEnable) {
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME, MIN_DISTANCE, this);
provider = LocationManager.NETWORK_PROVIDER;
Log.d("Network", "Network");
}
if (isGPSEnable) {
if (lm == null) {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, this);
provider = LocationManager.GPS_PROVIDER;
Log.d("GPS", "GPS");
}
}
if (lm != null) {
location = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
// At here other PROVIDER doesn't work. Only passive work it is strange.
}
}
return location;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
I am not getting GPS location in my code, while Google maps is showing current location and even its updating, I am starting a service, inside service registering locationListener to the locationManager, handling onLocationChanged callback method, doing entry in the AndroidManifest.xml even. The logs onCreate methods is showing.
below is my code, could you guys please let me know where i am doing wrong...
public class LocationService extends Service implements LocationListener {
private static final long MIN_TIME_INTERVAL_FOR_GPS_LOCATION = 100;
private static final float MIN_DISTANCE_INTERVAL_FOR_GPS_LOCATION = 1.0f;
private static String TAG = LocationService.class.getSimpleName();
private LocationManager locationManager;
private static Location mCurrentLocation;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate...");
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_INTERVAL_FOR_GPS_LOCATION, MIN_DISTANCE_INTERVAL_FOR_GPS_LOCATION, this);
mCurrentLocation = getBestLocation();
}
private Location getBestLocation() {
Log.i(TAG, "getBestLocation...");
Location location_gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location location_network = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// If both are available, get the most recent
if (location_gps != null && location_network != null) {
return (location_gps.getTime() > location_network.getTime()) ? location_gps : location_network;
} else if (location_gps == null && location_network == null) {
return null;
} else {
return (location_gps == null) ? location_network : location_gps;
}
}
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, "onLocationChanged...");
Toast.makeText(LocationService.this, "Location Found", Toast.LENGTH_SHORT).show();
mCurrentLocation = location;
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public static Location getmCurrentLocation() {
return mCurrentLocation;
}
public static void setmCurrentLocation(Location mCurrentLocation) {
LocationService.mCurrentLocation = mCurrentLocation;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy...");
locationManager.removeUpdates(this);
}
}
Your locationManager called requestLocationUpdates using GPS provider only.
I think your device could not catch GPS satellite signal, in-door sate.
So, you should call requestLocationUpdates using Network provider too.
Next two links are may helpful to you.
http://developer.android.com/guide/topics/location/strategies.html
http://developer.android.com/training/location/receive-location-updates.html
I read the tutorial about Obtaining User Location in Android Dev Guid and,
I try to adapt this to the following code.. but i don't know which location value I should put into isBetterLocation(Location location, Location currentBestLocation)
Example.class
private LocationManager locman;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String context = Context.LOCATION_SERVICE;
locman = (LocationManager)getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locman.getBestProvider(criteria, true);
locman.requestLocationUpdates(
provider,MIN_TIME, MIN_DISTANCE, locationListener);
}
private LocationListener locationListener = new LocationListener(){
#Override
public void onLocationChanged(Location location) {
// What should i pass as first and second parameter in this method
if(isBetterLocation(location1,location2)){
// isBetterLocation = true > do updateLocation
updateLocation(location);
}
}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
//Brief ... See code in Android Dev Guid "Obtaining User Location"
}
Its not that hard really. What the code does is it receives continuous updates on locations found; you can have multiple listeners listening to different providers and as such those updates can be more or less accurate depending on the provider (GPS for example could be more accurate than network). isBetterLocation(...) evaluates if a location found by the listener is actually better than the one you already know about (and should have a reference to in your code). The isBetterLocation(...) code is well documented, so it shouldn't be hard to understand, but the first parameter location is the new location found by a provider, and currentBestLocation is the location you already know about.
The code I use is about the same as yours, except I don't just take best provider.
The handler stuff is because I don't want continued updates, just find the best possible location that is accurate enough for me within a maximum timeframe of two minutes (GPS can take a bit).
private Location currentBestLocation = null;
private ServiceLocationListener gpsLocationListener;
private ServiceLocationListener networkLocationListener;
private ServiceLocationListener passiveLocationListener;
private LocationManager locationManager;
private Handler handler = new Handler();
public void fetchLocation() {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
try {
LocationProvider gpsProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
LocationProvider networkProvider = locationManager.getProvider(LocationManager.NETWORK_PROVIDER);
LocationProvider passiveProvider = locationManager.getProvider(LocationManager.PASSIVE_PROVIDER);
//Figure out if we have a location somewhere that we can use as a current best location
if( gpsProvider != null ) {
Location lastKnownGPSLocation = locationManager.getLastKnownLocation(gpsProvider.getName());
if( isBetterLocation(lastKnownGPSLocation, currentBestLocation) )
currentBestLocation = lastKnownGPSLocation;
}
if( networkProvider != null ) {
Location lastKnownNetworkLocation = locationManager.getLastKnownLocation(networkProvider.getName());
if( isBetterLocation(lastKnownNetworkLocation, currentBestLocation) )
currentBestLocation = lastKnownNetworkLocation;
}
if( passiveProvider != null) {
Location lastKnownPassiveLocation = locationManager.getLastKnownLocation(passiveProvider.getName());
if( isBetterLocation(lastKnownPassiveLocation, currentBestLocation)) {
currentBestLocation = lastKnownPassiveLocation;
}
}
gpsLocationListener = new ServiceLocationListener();
networkLocationListener = new ServiceLocationListener();
passiveLocationListener = new ServiceLocationListener();
if(gpsProvider != null) {
locationManager.requestLocationUpdates(gpsProvider.getName(), 0l, 0.0f, gpsLocationListener);
}
if(networkProvider != null) {
locationManager.requestLocationUpdates(networkProvider.getName(), 0l, 0.0f, networkLocationListener);
}
if(passiveProvider != null) {
locationManager.requestLocationUpdates(passiveProvider.getName(), 0l, 0.0f, passiveLocationListener);
}
if(gpsProvider != null || networkProvider != null || passiveProvider != null) {
handler.postDelayed(timerRunnable, 2 * 60 * 1000);
} else {
handler.post(timerRunnable);
}
} catch (SecurityException se) {
finish();
}
}
private class ServiceLocationListener implements android.location.LocationListener {
#Override
public void onLocationChanged(Location newLocation) {
synchronized ( this ) {
if(isBetterLocation(newLocation, currentBestLocation)) {
currentBestLocation = newLocation;
if(currentBestLocation.hasAccuracy() && currentBestLocation.getAccuracy() <= 100) {
finish();
}
}
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {}
#Override
public void onProviderEnabled(String s) {}
#Override
public void onProviderDisabled(String s) {}
}
private synchronized void finish() {
handler.removeCallbacks(timerRunnable);
handler.post(timerRunnable);
}
/** Determines whether one Location reading is better than the current Location fix
* #param location The new Location that you want to evaluate
* #param currentBestLocation The current Location fix, to which you want to compare the new one
*/
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
//etc
}
private Runnable timerRunnable = new Runnable() {
#Override
public void run() {
Intent intent = new Intent(LocationService.this.getPackageName() + ".action.LOCATION_FOUND");
if(currentBestLocation != null) {
intent.putExtra(LocationManager.KEY_LOCATION_CHANGED, currentBestLocation);
locationManager.removeUpdates(gpsLocationListener);
locationManager.removeUpdates(networkLocationListener);
locationManager.removeUpdates(passiveLocationListener);
}
}
};
I'm trying to get the location updates running in a background service. The service is running a workerthread of its own doing a lot of other stuff already, like socket communication. I'd like it to also handle location updates but this seems to only work on an activity. As far as I can read this is due to the message loop missing on a workerthread. I think I need to use Looper.prepare() somewhere, but maybe I need another thread just to handle locations requests? I can't seem to get the emulator to respond to any geo fix events, so I must be doing something wrong.
Below is the service code, stripped for all the non-relevant parts.
public class MyService extends Service implements LocationListener {
private Thread runner;
private volatile boolean keepRunning;
private LocationManager locationManager = null;
#Override
public void onCreate() {
keepRunning = true;
runner = new Thread(null, new Runnable() {
public void run() { workerLoop(); }
});
runner.start();
startGps();
}
#Override
public void onDestroy() {
keepRunning = false;
runner.interrupt();
}
private void workerLoop() {
//Looper.myLooper(); How does this work??
//Looper.prepare();
// Main worker loop for the service
while (keepRunning) {
try {
if (commandQueue.notEmpty()) {
executeJob();
} else {
Thread.sleep(1000);
}
} catch (Exception e) {
}
}
stopGps();
}
public void onLocationChanged(Location location) {
// Doing something with the position...
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
private void startGps() {
if (locationManager == null)
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(true);
criteria.setCostAllowed(false);
criteria.setSpeedRequired(true);
String provider = locationManager.getBestProvider(criteria, true);
if (provider != null)
locationManager.requestLocationUpdates(provider, 10, 5, (LocationListener) this);
}
}
private void stopGps() {
if (locationManager != null)
locationManager.removeUpdates((LocationListener) this);
locationManager = null;
}
}
The LocationListener doesn't care whether it is in the context of an activity or a service.
You want to use the location uodates in your workerLoop(), right? The location updates (the call to the LocationListener) and the workerLoop() are both acting independently from each other. To get the location update to the workerLoop() you need to join the two threads. One method to do this is to use the blackboard pattern: The LocationListener writes the new location to a field of your class (this is easy since both are in the context of the same class):
private Location blackboard = null;
public void onLocationChanged(final Location location) {
if( location != null )
this.blackboard = location;
}
private void workerLoop() {
...
if( this.blackboard != null ) {
final Location locationUpdate = this.blackboard;
this.blackboard = null;
// .. do something with the location
}
...
}
With the above code you may get race conditions when the LocationListener writes to the blackboard while the workerLoop() is reading or erasing the location. This can be solved by surrounding the access to the blackboard by a synchronized block like this:
synchronized(this) {
this.blackboard = location
}
and likewise in the workerLoop(), and we must declare the blackboard volatile:
private volatile Location blackboard = null;
Alternatively you may use a Lock, confer to the docs for more details: http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
Hai all i want to find current GPS location, i have used the following code.
public class GPSManager
{
private static final int gpsMinTime = 500;
private static final int gpsMinDistance = 0;
private LocationManager locationManager = null;
private LocationListener locationListener = null;
private GPSCallback gpsCallback = null;
public GPSManager()
{
locationListener = new LocationListener()
{
public void onProviderDisabled(final String provider)
{
}
public void onProviderEnabled(final String provider)
{
}
public void onStatusChanged(final String provider, final int status, final Bundle extras)
{
}
public void onLocationChanged(final Location location)
{
location.getLatitude();
location.getLongitude();
if (location != null && gpsCallback != null)
{
Log.e("if location "+location,"if gpscallback"+gpsCallback);
gpsCallback.onGPSUpdate(location);
location.getLatitude();
location.getLongitude();
}
else{
Log.e("else location "+location,"else gpscallback"+gpsCallback);
}
}
};
}
public void startListening(final Activity activity)
{
if (locationManager == null)
{
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
final String bestProvider = locationManager.getBestProvider(criteria, true);
if (bestProvider != null && bestProvider.length() > 0)
{
locationManager.requestLocationUpdates(bestProvider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
else
{
final List<String> providers = locationManager.getProviders(true);
for (final String provider : providers)
{
locationManager.requestLocationUpdates(provider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
}
}
public void stopListening()
{
try
{
if (locationManager != null && locationListener != null)
{
locationManager.removeUpdates(locationListener);
}
locationManager = null;
}
catch (final Exception ex)
{
}
}
public void setGPSCallback(final GPSCallback gpsCallback)
{
this.gpsCallback = gpsCallback;
}
public GPSCallback getGPSCallback()
{
return gpsCallback;
}
But strange issue is it is working only when GPS in mobile is off mode. If GPS in device is in on Mode it is not working.
Can anybody please tell me what is the issue with my code?
Please help me... thanks in advance.
The problem should be the power requirement. You're requesting for everything that matchs the gps provider ( Location fine .... ) but gps is power consuming so try to remove that line or setting the criteria to POWER_HIGH