My app has two activities that need GPS, so I tried to offload it to a separate class that either activity could use. I found an answer here that looked easy enough
Android - Best way to implement LocationListener across multiple activities
But of course, it's not working for me. I was wondering if anyone can see the issue. I used pretty much exactly the same code, but I got rid of the gps settings dialog.
Here's my GPS class
package fieldlayout.skipmorrow.com.fieldlayout;
import android.app.Activity;
import android.content.Context;
import android.location.LocationManager;
import android.os.Bundle;
import android.location.LocationListener;
import android.location.Location;
import android.util.Log;
/**
* Created by skip on 4/20/2015.
*/
public class GPS {
private IGPSActivity main;
// Helper for GPS-Position
private LocationListener mlocListener;
private LocationManager mlocManager;
private boolean isRunning;
public GPS(IGPSActivity main) {
this.main = main;
// GPS Position
mlocManager = (LocationManager) ((Activity) this.main).getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
// GPS Position END
this.isRunning = true;
Log.i("FieldLayout_GPS", "GPS Object created");
}
public void stopGPS() {
if(isRunning) {
mlocManager.removeUpdates(mlocListener);
this.isRunning = false;
}
Log.i("FieldLayout_GPS", "stopGPS");
}
public void resumeGPS() {
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
this.isRunning = true;
Log.i("FieldLayout_GPS", "resumeGPS");
}
public boolean isRunning() {
return this.isRunning;
}
public class MyLocationListener implements LocationListener {
private final String TAG = MyLocationListener.class.getSimpleName();
#Override
public void onLocationChanged(Location loc) {
GPS.this.main.locationChanged(loc.getLongitude(), loc.getLatitude());
Log.i("FieldLayout_GPS", "onLocationChanged");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i("FieldLayout_GPS", "onStatusChanged");
}
#Override
public void onProviderEnabled(String provider) {
Log.i("FieldLayout_GPS", "onProviderEnabled");
}
#Override
public void onProviderDisabled(String provider) {
Log.i("FieldLayout_GPS", "onProviderDisabled");
}
}
}
The interface file
package fieldlayout.skipmorrow.com.fieldlayout;
/**
* Created by skip on 4/20/2015.
*/
public interface IGPSActivity {
public void locationChanged(double longitude, double latitude);
}
And my implementation from my activity
package fieldlayout.skipmorrow.com.fieldlayout;
import android.content.Context;
import android.content.Intent;
public class StartActivity extends ActionBarActivity implements IGPSActivity{
private Location currentLocation;
private GPS gps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
gps = new GPS(this);
}
#Override
protected void onResume() {
if (!gps.isRunning()) gps.resumeGPS();
super.onResume();
}
#Override
protected void onStop() {
// Disconnecting the client invalidates it.
Log.i("FieldLayout_StartAct", "onStop called. Disconnecting GPS client");
gps.stopGPS();
super.onStop();
}
#Override
public void locationChanged(double longitude, double latitude) {
Log.i("FieldLayout_StartAct", "locationChanged");
currentLocation.setLatitude(latitude);
currentLocation.setLongitude(longitude);
}
}
The only log I am seeing is the creation of the GPS object. None of the other methods in the listener are being executed.
GPS class constructor contains this row:
public GPS(IGPSActivity main) {
this.main = main;
// GPS Position
mlocManager = (LocationManager) ((Activity) this.main).getSystemService(Context.LOCATION_SERVICE);
...
}
And your interface looks like this:
public interface IGPSActivity {
public void locationChanged(double longitude, double latitude);
}
So, the GPS class get an interface, and you want to cast it into an Activity to get a system service from it. That is not going to work.
Change your GPS class a little bit. For example:
public GPS(IGPSActivity main, Activity activity){
mlocManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
...
}
Call this in your activity:
gps = new GPS(this, this);
Related
My Application crashes when gps is off and the back end code searches for the location of the user. I have tried the following code for finding the location of user when gps is off it searches using the internet.
Please suggest something in the following code or any other way
below is my code for the locationservice:
package com.example.myapp;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
public class LocationService extends Service implements LocationListener {
protected LocationManager locationManager;
Location location;
private static final long MIN_DISTANCE_FOR_UPDATE = 10;
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;
public LocationService(Context context) {
locationManager = (LocationManager) context
.getSystemService(LOCATION_SERVICE);
}
public Location getLocation(String provider) {
if (locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider,
MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(provider);
return location;
}
}
return null;
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
I'm trying to make a trivial application in which the user clicks a button and a few text views display various information about the phone(model,battery %,location,signal strength etc). I'm having trouble getting the current latitude and longitude, since when I press the button the textview displays the previous latitude/longitude(first time it shows 0,0 and the second the position I was when I first pressed it).
What I'm trying to achieve is when I press the button, activate the location manager and location listener, and make the onClick() method wait until the latitude is not equal to the old latitude. I've tried Threads, handler, and asynctask but I haven't managed anything. Any tips? This is how my onClick() method looks right now: (Infogatherer is a class where I collect all the info)
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()){
case R.id.bMeasurements:
oldLat=InfoGatherer.getLatitude();
oldLong=InfoGatherer.getLongitude();
//SOMEWHERE HERE START A THREAD OR SOMETHING IN ORDER TO RETRIEVE CURRENT LOCATION
//Retrieval and Assignment of information to the corresponding text fields
DeviceName.setText(infogatherer.getDeviceName());
NetworkOp.setText(infogatherer.getNetworkOp());
Date.setText(infogatherer.getDate());
BatteryStatus.setText(String.valueOf(infogatherer.getBatteryStatus()));
Generation.setText(String.valueOf(infogatherer.getGeneration()));
infogatherer.getLocation();
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
infogatherer.getSignalStrength();
SignalStrength.setText(String.valueOf(infogatherer.getDbm()));
oldLat = InfoGatherer.getLatitude();
oldLong = InfoGatherer.getLongitude();
break;
}
This is my InfoGatherer class:
package com.example.netmap;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.telephony.CellInfoGsm;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
public class InfoGatherer extends Application{
String address,city,country;
int cid,lac,generation=0,ipAddress=0,signalStrngth=0;
private GsmCellLocation location;
private WifiInfo wifiInfo;
private LocationManager lm;
private LocationListener ll;
Geocoder geoc;
static public double Longitude,Latitude=0;
List<Address> addresses;
Context context;
Intent batteryIntent;
TelephonyManager tm;
WifiManager wifimanager;
public InfoGatherer(){
}
public InfoGatherer(Context context){
this.context = context;
}
public String getDate(){
Calendar c = Calendar.getInstance();
return Integer.toString(c.get(Calendar.DAY_OF_MONTH))+"-"+Integer.toString(c.get(Calendar.MONTH))+"-"+Integer.toString(c.get(Calendar.YEAR))+" "+Integer.toString(c.get(Calendar.HOUR_OF_DAY))+":"+Integer.toString(c.get(Calendar.MINUTE))+":"+Integer.toString(c.get(Calendar.SECOND));
}
public String getDeviceName(){
return Build.MANUFACTURER +" "+Build.MODEL;
}
public String getNetworkOp(){
tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getNetworkOperatorName();
}
public float getBatteryStatus() {
batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
return ((float)batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) / (float)batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)) * 100.0f;
}
public int getGeneration(){
tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getNetworkType();
}
public int getCid(){
tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
location = (GsmCellLocation)tm.getCellLocation();
return location.getCid();
}
public int getLac(){
tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
location = (GsmCellLocation)tm.getCellLocation();
return location.getLac();
}
public String getIpAddress() {
// TODO Auto-generated method stub
wifimanager = (WifiManager) context.getSystemService(WIFI_SERVICE);
wifiInfo = wifimanager.getConnectionInfo();
ipAddress = wifiInfo.getIpAddress();
return String.format("%d.%d.%d.%d",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
}
public void getLocation(){
/*Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_FINE);
c.setPowerRequirement(Criteria.POWER_LOW);
String provider = lm.getBestProvider(c, true);*/
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
ll = new mylocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
}
public class mylocationlistener implements LocationListener{
#Override
public void onLocationChanged(android.location.Location location) {
// TODO Auto-generated method stub
if(location!=null){
Longitude = location.getLongitude();
Latitude = location.getLatitude();
lm.removeUpdates(ll);
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
//Pass views as parameters? DIscuss
//DeviceName.setText(String.valueOf(Latitude) +" "+String.valueOf(Longitude));
}
#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
}
}
public void getSignalStrength(){
tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener Listener = new phoneStateListener();
tm.listen(Listener ,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
public class phoneStateListener extends PhoneStateListener{
public void onSignalStrengthsChanged(SignalStrength signalStrength){
super.onSignalStrengthsChanged(signalStrength);
if (signalStrength.isGsm()) {
signalStrngth = -113 + 2 * signalStrength.getGsmSignalStrength();
}
else
signalStrngth = -113 + 2 * signalStrength.getCdmaDbm();
}
}
static public double getLatitude(){
return Latitude;
}
static public double getLongitude(){
return Longitude;
}
public String getAddress(){
return address;
}
public String getCity(){
return city;
}
public String getCountry(){
return country;
}
public int getDbm(){
return signalStrngth;
}
}
You donĀ“t provide enough time to Location service get the location.
You ask for latitude and longitude before the LocationManager have time to call onLocationChanged.
infogatherer.getLocation();
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
Call infogatherer.getLocation(); out of onClick event. Do that at Activity onResume() event.
Remove lm.removeUpdates(ll); from onLocationChanged. Call it at Activity onPause()event.
If you want see this example how to create a GPS Manager Class
EDIT
Try something like this: Note: Not tested!
private void updateLocationText(double oldLat, double oldLong) {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
boolean isPositionChanged = false;
double lat;
double long;
while (!isPositionChanged) {
lat = InfoGatherer.getLatitude();
long = InfoGatherer.getLongitude();
if(lat != oldLat || long != oldLong)isPositionChanged = true;
}
handler.post(new Runnable(){
public void run() {
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
});
}
}
};
new Thread(runnable).start();
}
Note that if you click on the button without having been no change of location, it will run forever.
EDIT AGAIN
Another approach more clean:
Replace
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
with this
Location.postDelayed(new Runnable() {
#Override
public void run() {
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
Location.postInvalidate();//Try without, may be not necessary
}
}, 3000);//Change if need
Create the LocationListener out of Aplication.
In the Ativity instantiate the class, override the onLocationChanged event and update Location TextView there.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.........
.........
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener(){
#Override
public void onLocationChanged(android.location.Location location) {
if(location!=null){
Location.setText(String.valueOf(location.getLatitude()+","+location.getLatitude()));
lm.removeUpdates(listener);
}
}
}
}
In onClick() event replace:
infogatherer.getLocation();
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude()));
with
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
In the end I used AsyncTask, which helped me in order to sleep the app while I looked for the location.
private class LocationThread extends AsyncTask<Context, Void, Void> {
protected void onPreExecute() {
infogatherer.startLocationListener();
}
#Override
protected Void doInBackground(Context... params) {
while (!infogatherer.getGo()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(final Void unused) {
//Do whatever you wanna do after you get location
}
}
getGo is a boolean which whenever becomes true gives the location back
public class mylocationlistener implements LocationListener {
#Override
public void onLocationChanged(android.location.Location location) {
if(location != null){
Longitude = location.getLongitude();
Latitude = location.getLatitude();
lm.removeUpdates(ll);
go = true;
}
}
hope you understand the procedure. Cheers.
So, I have an Android application that is asking for the GPS from the LocationManager class.
I have an Activity that wants to use that data, and a custom class that implements LocationListener.
I have written some custom methods to return the GPS values to my other class.
Currently, I am asking for and releasing the location updates from my Activity class, not my implementation of the LocationListener class... I think this is the right way to go about it, but I just wanted to get any feedback on the life cycle, etc. (the class that implements LocationListener is not an Activity, so I don't think I even could call onPause() etc, ?)
This is the Activity:
package com.jessescott.sonicity;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationListener;
public class PlayActivity extends Activity {
// GLOBALS
private static final String TAG = "SoniCity";
LocationManager locationManager;
MyLocationListener locationListener;
TextView latitude, longitude;
TextView ActualLatitude, ActualLongitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_layout);
// GPS
locationListener = new MyLocationListener(this);
// TextViews
latitude = (TextView) findViewById(R.id.Latitude);
longitude = (TextView) findViewById(R.id.Longitude);
ActualLatitude = (TextView) findViewById(R.id.ActualLat);
ActualLatitude.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "Asking For New Latitude");
ActualLatitude.setText(locationListener.getCurrentLatitude());
}
});
ActualLongitude = (TextView) findViewById(R.id.ActualLon);
ActualLongitude.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "Asking For New Latitude");
ActualLongitude.setText(locationListener.getCurrentLongitude());
}
});
}
#Override
protected void onPause() {
super.onPause();
// Stop GPS
locationManager.removeUpdates(locationListener);
locationManager = null;
}
#Override
protected void onResume() {
super.onResume();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 5, locationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
}
} /* */
... and this is the LocationListener implementation :
package com.jessescott.sonicity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.util.Log;
class MyLocationListener implements LocationListener {
private static final String TAG = "SoniCity";
float currentLatitude = 0;
float currentLongitude = 0;
public MyLocationListener(Context context) {
super();
}
// Define all LocationListener methods
public void onLocationChanged(Location location) {
currentLatitude = (float)location.getLatitude();
currentLongitude = (float)location.getLongitude();
}
public void onProviderDisabled (String provider) {
Log.v(TAG, "Provider is " + provider);
}
public void onProviderEnabled (String provider) {
Log.v(TAG, "Provider is " + provider);
}
public void onStatusChanged (String provider, int status, Bundle extras) {
Log.v(TAG, "Status is " + status);
}
// Custom Methods
public String getCurrentLatitude() {
String lat = Float.toString(currentLatitude);
return lat;
}
public String getCurrentLongitude() {
String lon = Float.toString(currentLongitude);
return lon;
}
} /* */
I guess since I've moved it to a separate class (they used to be the same one), I just want to make sure I'm calling th request/remove in the right place.
I haven't looked at your code in detail, but from what I've seen it looks fine to me. onResume() is the right place to register your listener, and onPause() is the right place to unregister it, so that e.g. battery life is optimised.
A couple of things to consider going forward:For a robust app, make sure you pay attention to the information that you get from onStatusChanged, onProviderEnabled and onProviderDisabled. I've seen various questions on stackoverflow.com to which the answer was to pay attention to status changes etc.Also for a better estimate of location, you might consider using the Location.accuracy value, because the accuracy of GPS location estimates can change. One minute they might be very accurate, but then the visible satellites change and the accuracy can suddenly be much lower. In my apps I use a simple Kalman filter for this, and I posted the code for it in my answer to the question Smooth GPS data.
Here is the code.
How can I be sure, that location is returned alwasys instead of null.
package com.test.location;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
public class NotifyOnBoot extends Service {
Location location;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
updateNotification();
Thread th = new Thread(null, task, "myService");
th.start();
}
private Runnable task = new Runnable() {
public void run() {
if(location == null)
{
Log.d("location","No location");
}
else
Log.d("location",location.toString());
NotifyOnBoot.this.stopSelf();
}
};
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand (Intent intent, int flags, int startId){
return START_STICKY;
}
protected void updateNotification()
{
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
private class MyLocationlistener implements LocationListener{
public void onLocationChanged(Location location){}
public void onProviderDisabled(String provider){}
public void onProviderEnabled(String provider){}
public void onStatusChanged(String provider, int status, Bundle extras){}
}
}
I recommend to create a call back interface and use onLocationChanged which notifies that call back on the moment the location initiate for the first time.
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or use LocationManager.GPS_PROVIDER
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
I wrote a GPSDataCollectService to collect location data every 10 seconds, but it did not report location in my HTC mobile phone, any wrong? could anyone help me?
package com.android.example;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class GPSDataCollectorService extends Service {
private static final String TAG = GPSDataCollectorService.class
.getSimpleName();
LocationManager locationManager;
LocationListener gpsLocationListener;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private Timer timer;
private TimerTask collectTask = new TimerTask() {
#Override
public void run() {
Log.i(TAG, "Timer task doing work: "
+ Calendar.getInstance().getTimeInMillis());
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 10 * 1000L, 0,
gpsLocationListener);
}
};
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service creating");
timer = new Timer("GPSDataCollectorTimer");
timer.schedule(collectTask, 1000L, 10 * 1000L);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
locationManager.removeUpdates(gpsLocationListener);
timer.cancel();
timer = null;
}
private class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged: " + location.toString());
locationManager.removeUpdates(gpsLocationListener);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
}
If your location is changed every 10 sec then only your LocationManager will track the new location. Otherwise it will use the same last known location.
Instead of using a LocationListener, you may want to use a Timer, within the TimerTask, maybe you can do something like this:
LocationManager lm = yourActivityReference.getSystemService(Context.LOCATION_SERVICE);
String provider = lm.getBestProvider(new Criteria(),true);
Location loc = lm.getLastKnownLocation (provider);
I haven't checked it, but if I do I will let know...
Regards.
EDIt: Let me try again with the "classic" approach.
public class GPSDataCollectorService extends Service {
private static final String TAG = GPSDataCollectorService.class
.getSimpleName();
LocationManager locationManager;
LocationListener gpsLocationListener;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000L, 0, gpsLocationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
locationManager.removeUpdates(gpsLocationListener);
}
private class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged: " + location.toString());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
}
I don't think you need any Timer, since the Location updates will call your listener asynchronally and you can set the timeout. I haven't played much with GPS in Android, but there must be plenty of examples out there.
The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation
Use
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 20 * 1000, 0, this);
more details refer Location Manager