可以停止位置更新,Android 服务
Can able to stop location update, Android service
我正在尝试创建一个路线跟踪应用程序。即使应用程序在后台,它也需要跟踪位置。所以我创建了一个服务并向该服务添加了代码。以下是我的代码。但有一个问题。我从主 activity.
启动服务
public void startTracking(View view) {
startService(new Intent(MainActivity.this, LocationIntentService.class));
}
public void stopTracking(View view) {
stopService(new Intent(MainActivity.this, LocationIntentService.class));
}
它启动服务并将位置插入到本地数据库。但我不能停止这些服务。当我使用上面的代码停止服务时,它仍然会跟踪位置。我怎样才能停止位置更新。
public class LocationIntentService extends IntentService implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = LocationIntentService.class.getSimpleName();
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private static int DISPLACEMENT = 10;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
DBAdapter dbAdapter;
public LocationIntentService() {
super("LocationIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, " ***** Service on handled");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
@Override
public void onConnected(Bundle bundle) {
Log.e(TAG, " ***** Service on connected");
startLocationUpdates();
openDB();
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, " ***** Service on suspended");
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Location changed");
mLastLocation = location;
String latitude = String.valueOf(mLastLocation.getLatitude());
String longitude = String.valueOf(mLastLocation.getLongitude());
Log.e(TAG, " ##### Got new location"+ latitude+ longitude);
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
String timestamp = today.format("%Y-%m-%d %H:%M:%S");
dbAdapter.insertRow(latitude, longitude, timestamp);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
}
@Override
public void onDestroy() {
Log.e(TAG, "Service is Destroying...");
super.onDestroy();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
mGoogleApiClient.disconnect();
}
closeDB();
}
protected void stopLocationUpdates() {
Log.d(TAG, "Location update stoping...");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
protected void startLocationUpdates() {
Log.d(TAG, "Location update starting...");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
private void openDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.open();
}
private void closeDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.close();
}
protected void createLocationRequest() {
Log.e(TAG, " ***** Creating location request");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
Log.e(TAG, " ***** Update google play service ");
return false;
}
}
}
在 stopService() 中调用 stopLocationUpdates() 方法
当您停止服务时。然后在LocationIntentService.class.
中调用这一行
locationManager.removeUpdates(this);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
它对你不起作用的原因是你正在使用 IntentService
,所以调用 stopService()
不会导致调用 onDestroy()
,大概是因为它已经被调用了onHandleIntent()
完成后。没有必要在 IntentService
上调用 stopService()
见 here.
看来您应该只使用 Service
而不是 IntentService
。这样,当您调用 stopService()
时,它会调用 onDestroy()
并取消注册位置更新,如您所料。
您唯一需要做的其他更改是覆盖 onStartCommand()
而不是 onHandleIntent()
。
您可以让您的 class 扩展 Service
而不是 IntentService
,然后将您的代码移动到 onStartCommand
:
以注册位置更新
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, " ***** Service on start command");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
return Service.START_STICKY;
}
这样你仍然可以调用 startService()
和 stopService()
,它应该会如你所料的那样工作。
我正在尝试创建一个路线跟踪应用程序。即使应用程序在后台,它也需要跟踪位置。所以我创建了一个服务并向该服务添加了代码。以下是我的代码。但有一个问题。我从主 activity.
启动服务public void startTracking(View view) {
startService(new Intent(MainActivity.this, LocationIntentService.class));
}
public void stopTracking(View view) {
stopService(new Intent(MainActivity.this, LocationIntentService.class));
}
它启动服务并将位置插入到本地数据库。但我不能停止这些服务。当我使用上面的代码停止服务时,它仍然会跟踪位置。我怎样才能停止位置更新。
public class LocationIntentService extends IntentService implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = LocationIntentService.class.getSimpleName();
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private static int DISPLACEMENT = 10;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
DBAdapter dbAdapter;
public LocationIntentService() {
super("LocationIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, " ***** Service on handled");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
@Override
public void onConnected(Bundle bundle) {
Log.e(TAG, " ***** Service on connected");
startLocationUpdates();
openDB();
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, " ***** Service on suspended");
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Location changed");
mLastLocation = location;
String latitude = String.valueOf(mLastLocation.getLatitude());
String longitude = String.valueOf(mLastLocation.getLongitude());
Log.e(TAG, " ##### Got new location"+ latitude+ longitude);
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
String timestamp = today.format("%Y-%m-%d %H:%M:%S");
dbAdapter.insertRow(latitude, longitude, timestamp);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
}
@Override
public void onDestroy() {
Log.e(TAG, "Service is Destroying...");
super.onDestroy();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
mGoogleApiClient.disconnect();
}
closeDB();
}
protected void stopLocationUpdates() {
Log.d(TAG, "Location update stoping...");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
protected void startLocationUpdates() {
Log.d(TAG, "Location update starting...");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
private void openDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.open();
}
private void closeDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.close();
}
protected void createLocationRequest() {
Log.e(TAG, " ***** Creating location request");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
Log.e(TAG, " ***** Update google play service ");
return false;
}
}
}
在 stopService() 中调用 stopLocationUpdates() 方法
当您停止服务时。然后在LocationIntentService.class.
中调用这一行locationManager.removeUpdates(this);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
它对你不起作用的原因是你正在使用 IntentService
,所以调用 stopService()
不会导致调用 onDestroy()
,大概是因为它已经被调用了onHandleIntent()
完成后。没有必要在 IntentService
上调用 stopService()
见 here.
看来您应该只使用 Service
而不是 IntentService
。这样,当您调用 stopService()
时,它会调用 onDestroy()
并取消注册位置更新,如您所料。
您唯一需要做的其他更改是覆盖 onStartCommand()
而不是 onHandleIntent()
。
您可以让您的 class 扩展 Service
而不是 IntentService
,然后将您的代码移动到 onStartCommand
:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, " ***** Service on start command");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
return Service.START_STICKY;
}
这样你仍然可以调用 startService()
和 stopService()
,它应该会如你所料的那样工作。