我正在开发一款用于学习和练习的Android应用。它是一个用于体育活动的GPS跟踪器。
我有Service
实现LocationListener
获取位置(纬度和经度),海拔高度等,并通过Activity
将此信息发送到sendBroadcast
。 Activity
可以在其布局中显示当前位置,因为它会从Service
到BroadcastReceiver
接收信息。
现在,我需要Activity
通知Service
已点击暂停按钮,因此Service
不会通过sendBroadcast
发送任何位置。这样做的最佳选择是什么?另一个BroadcastReceiver
? Messenger
?
我的Serivce
就是这样:
public class GpsTrackerService extends Service {
private static final String TAG = GpsTrackerService.class.getSimpleName();
// Action for location change and its extra data.
public static final String LOCATION_CHANGE_ACTION = "gpstrackerservice.LOCATION_CHANGE";
public static final String EXTRA_LOCATION_LATITUDE = "extra_location_latitude";
public static final String EXTRA_LOCATION_LONGITUDE = "extra_location_longitude";
public static final String EXTRA_LOCATION_ACCURACY = "extra_location_accuracy";
public static final String EXTRA_LOCATION_ALTITUDE = "extra_location_altitude";
public static final String EXTRA_LOCATION_TIME = "extra_location_time";
// Action for gps provider disabled and enabled.
public static final String LOCATION_GPS_PROVIDER_DISABLED_ACTION =
"gpstrackerservice.GPS_DISABLED";
public static final String LOCATION_GPS_PROVIDER_ENABLED_ACTION =
"gpstrackerservice.GPS_ENABLED";
// Contains if this service ir running or not.
private static boolean sIsRunning = false;
// Location manager and configuration.
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
// The location listener.
private android.location.LocationListener mLocationListener =
new LocationListener(LocationManager.GPS_PROVIDER);
/**
* An inner class for location listener.
*/
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
/**
* When loation is change it send via broadcast the information to the all registered
* receivers.
*
* @param location
*/
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
// Creates the intent, the location entity addint id to the extra and send de broadcast.
Intent intent = new Intent();
/*Bundle bundle = new Bundle();
es.rgmf.etroped.data.entity.Location locationEntity =
new es.rgmf.etroped.data.entity.Location();
locationEntity.setLatitude(mLastLocation.getLatitude());
locationEntity.setLongitude(mLastLocation.getLongitude());
locationEntity.setAccuracy(mLastLocation.getAccuracy());
locationEntity.setGpsAltitude(mLastLocation.getAltitude());
locationEntity.setBearing(mLastLocation.getBearing());
locationEntity.setSpeed(mLastLocation.getSpeed());
locationEntity.setTime(mLastLocation.getTime());
bundle.putSerializable(EXTRA_LOCATION, locationEntity);*/
intent.setAction(LOCATION_CHANGE_ACTION);
intent.putExtra(EXTRA_LOCATION_LATITUDE, mLastLocation.getLatitude());
intent.putExtra(EXTRA_LOCATION_LONGITUDE, mLastLocation.getLongitude());
intent.putExtra(EXTRA_LOCATION_ACCURACY, mLastLocation.getAccuracy());
intent.putExtra(EXTRA_LOCATION_ALTITUDE, mLastLocation.getAltitude());
intent.putExtra(EXTRA_LOCATION_TIME, mLastLocation.getTime());
//intent.putExtras(bundle);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
/**
* When provider is disabled then it sends via broadcast the information to all registered
* receivers.
*
* @param provider The provider has been disabled (gps, for example).
*/
@Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
if (provider.equals("gps")) {
Intent intent = new Intent();
intent.setAction(LOCATION_GPS_PROVIDER_DISABLED_ACTION);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
@Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
if (provider.equals("gps")) {
Intent intent = new Intent();
intent.setAction(LOCATION_GPS_PROVIDER_ENABLED_ACTION);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + provider);
}
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
// Initialize location manager.
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
}
// Prepares the location manager for updates and sets the flag sIsRunning to true. From this
// moment it can says that service is running.
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
LOCATION_INTERVAL,
LOCATION_DISTANCE,
mLocationListener
);
sIsRunning = true;
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
// Stop service in foreground.
stopForeground(true);
// It is not running.
sIsRunning = false;
// Remove listener.
mLocationManager.removeUpdates(mLocationListener);
}
public static boolean isRunning() {
return sIsRunning;
}
}