Configuring frequency of notifications for requesting location updates
I'm trying to resolve a small problem:
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 120000, 0, mLocationListener);
So I assumed that mLocationListener should wait for 2 mainutes before calling it's onLocationChanged method. However, the method is called right after I send geo fix updates to emulator, every time I d开发者_JAVA百科o it. Did I misunderstand the android developers guide, and do I have to to use timers or anything similar for organizing update rate I need?
I think you're confused as to how the updates work. You can't tell the GPS hardware to send you an update at a specific time in the future. You can only give it guidelines on when you'd like to be updated. With the minTime you're saying you don't want updates more frequently than every 2 minutes, but then you're using a min distance of zero when you setup your listener. That tells the underlying GPS driver to send you an update whenever the location changes distance by any amount. That's why you're getting updates immediately when you send in a new point.
Well after some research and meditation :) I've come up with something like this: a service that can run in two modes (depending on the listenPeriod variable): 1) simply process coordinates once and shut self down afterwards (listenPeriod=0); 2) and process coordinates with specified rate (listenPeriod>0) until the service will be shut down.
GPSTracer.listenPeriod = 120000;
comp = new ComponentName(context.getPackageName(), GPSTracer.class.getName());
GPSTracer.iGPSTracer = new Intent(context, GPSTracer.class.getClass());
GPSTracer.iGPSTracer.setComponent(comp);
service=context.startService(GPSTracer.iGPSTracer);
So I have to initialize the listenPeriod variable before I start my service. And the service part looks like this:
public class GPSTracer extends Service {
public static Intent iGPSTracer;
public static volatile Location mLocation = null;
public static volatile LocationListener mLocationListener = null;
public static LocationManager mLocationManager = null;
public static long listenPeriod = 0;
Timer mTimer = null;
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.arg1 == 1)
{
if(GPSTracer.mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
GPSTracer.mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 120000, 100, GPSTracer.mLocationListener);
}
else if(GPSTracer.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
GPSTracer.mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 120000, 100, GPSTracer.mLocationListener);
}
else
{
List<NameValuePair> gpsData = new ArrayList<NameValuePair>();
gpsData.add(new BasicNameValuePair("Error", "No location provider"));
stopSelf();
}
}
else if(msg.arg1 == 0)
{
GPSTracer.mLocationManager.removeUpdates(GPSTracer.mLocationListener);
}
};
};
TimerTask selfStopTask = new TimerTask() {
@Override
public void run() {
stopSelf();
}
};
TimerTask mTimerTask = new TimerTask() {
@Override
public void run() {
//Message mMessage = new Message();
//mHandler.sendMessage(mMessage);
if(mLocation == null)
{
mLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(mLocation == null)
{
mLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
}
if(mLocation != null)
{
List<NameValuePair> gpsData = new ArrayList<NameValuePair>();
gpsData.add(new BasicNameValuePair("Latitude", (new Double(mLocation.getLatitude())).toString()));
gpsData.add(new BasicNameValuePair("Longitude", (new Double(mLocation.getLongitude())).toString()));
gpsData.add(new BasicNameValuePair("Provider", mLocation.getProvider()));
}
else
{
List<NameValuePair> gpsData = new ArrayList<NameValuePair>();
gpsData.add(new BasicNameValuePair("Error", "Location is unknown"));
}
}
};
@Override
public void onCreate() {
mLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
mLocationListener = new GPSListener(getApplicationContext());
};
@Override
public void onStart(Intent intent, int startId) {
Message mMessage = new Message();
mMessage.arg1 = 1;
mHandler.sendMessage(mMessage);
if(listenPeriod == 0)
{
mTimer = new Timer("GPSTask");
mTimer.schedule(mTimerTask, 0);
mTimer.schedule(selfStopTask, 60000);
}
else if(listenPeriod>0)
{
mTimer = new Timer("GPSTask");
mTimer.schedule(mTimerTask, 0, listenPeriod);
}
};
@Override
public void onDestroy() {
Message mMessage = new Message();
mMessage.arg1 = 0;
mHandler.sendMessage(mMessage);
//GPSTracer.mLocationManager.removeUpdates(GPSTracer.mLocationListener);
iGPSTracer = null;
mTimer.cancel();
mTimerTask.cancel();
mTimer = null;
mTimerTask = null;
mLocationListener = null;
mLocationManager = null;
};
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
and implementation of LocationListener:
public class GPSListener implements LocationListener{
Context context;
public GPSListener(Context appContext) {
context = appContext;
}
@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
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
//GPSTracer.mLocationManager.removeUpdates(GPSTracer.mLocationListener);
GPSTracer.mLocation = location;
}
}
I hope it will help someone...) P.S. thanks to Dave MacLean and EboMike!; and feel free to ask questions;)
精彩评论