在 Android 上实施后台服务
Implementing background services on Android
我正在为 Android 构建一个应用程序以在乘车过程中跟踪用户 GPS 定位(通过将带有定位信息的事件发送到服务器),但到目前为止我遇到了两个问题。由于用户可以暂停应用程序以便在骑行期间使用其他应用程序,因此应用程序将停止发送事件。为了解决这个问题,我实现了一个后台服务,即使当用户切换到另一个应用程序时,它也会保持 运行,并因此不断向服务器发送事件。然而,似乎每当 phone 关闭其屏幕(进入睡眠模式?)时,该服务就会以某种方式暂停。第二个问题是关于从 phone 获取 GPS 定位数据。我已经为应用程序设置了从 GPS 接收器获取数据的必要权限,实际上,有时会正确检索 positiong(同时还有其他应用程序也在使用 GPS)。当没有其他应用程序使用 GPS 时,检索到的定位是经度和纬度的元组 (0.0, 0.0)。我不清楚为什么会出现这两个问题。为什么屏幕关闭时后台服务会暂停,为什么 GPS returns 只有在有其他应用程序请求使用 GPS 时才能正确定位?
我遇到了同样的问题(第一期)。我通过在服务内部使用 looper 来解决它。对于第二期,我们必须查看您的一些代码来帮助您。另外,我将显示我的搜索位置代码,也许它会有所帮助。我为此使用了 GoogleApiClient https://developer.android.com/training/location/retrieve-current.html
public class LocationService extends Service implements com.google.android.gms.location.LocationListener {
private Thread mTriggerService;
private Handler mLooperHandler;
...
private void addLocationListener(){
// Start thread which listen location
mTriggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();//Initialise the current thread as a looper.
mLooperHandler = new Handler();
initLocationManager();
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
mTriggerService.start();
}
/**
* Strart listening location
*/
public void initLocationManager(Context context) {
...
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(mInterval);
//This controls the fastest rate at which your application will receive location
//updates, which might be faster than setInterval(long) in some situations
//(for example, if other applications are triggering location updates).(from doc)
mLocationRequest.setFastestInterval(mFastestInterval);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended");
}
})
.addOnConnectionFailedListener(mOnConnectionFailedListener)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
//stop listening location
private void stopLocationListener() {
if(mLocationHelper != null){
mLooperHandler.getLooper().quit();
if(mGoogleApiClient != null && mLocationListener != null
&& mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
}
}
我正在为 Android 构建一个应用程序以在乘车过程中跟踪用户 GPS 定位(通过将带有定位信息的事件发送到服务器),但到目前为止我遇到了两个问题。由于用户可以暂停应用程序以便在骑行期间使用其他应用程序,因此应用程序将停止发送事件。为了解决这个问题,我实现了一个后台服务,即使当用户切换到另一个应用程序时,它也会保持 运行,并因此不断向服务器发送事件。然而,似乎每当 phone 关闭其屏幕(进入睡眠模式?)时,该服务就会以某种方式暂停。第二个问题是关于从 phone 获取 GPS 定位数据。我已经为应用程序设置了从 GPS 接收器获取数据的必要权限,实际上,有时会正确检索 positiong(同时还有其他应用程序也在使用 GPS)。当没有其他应用程序使用 GPS 时,检索到的定位是经度和纬度的元组 (0.0, 0.0)。我不清楚为什么会出现这两个问题。为什么屏幕关闭时后台服务会暂停,为什么 GPS returns 只有在有其他应用程序请求使用 GPS 时才能正确定位?
我遇到了同样的问题(第一期)。我通过在服务内部使用 looper 来解决它。对于第二期,我们必须查看您的一些代码来帮助您。另外,我将显示我的搜索位置代码,也许它会有所帮助。我为此使用了 GoogleApiClient https://developer.android.com/training/location/retrieve-current.html
public class LocationService extends Service implements com.google.android.gms.location.LocationListener {
private Thread mTriggerService;
private Handler mLooperHandler;
...
private void addLocationListener(){
// Start thread which listen location
mTriggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();//Initialise the current thread as a looper.
mLooperHandler = new Handler();
initLocationManager();
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
mTriggerService.start();
}
/**
* Strart listening location
*/
public void initLocationManager(Context context) {
...
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(mInterval);
//This controls the fastest rate at which your application will receive location
//updates, which might be faster than setInterval(long) in some situations
//(for example, if other applications are triggering location updates).(from doc)
mLocationRequest.setFastestInterval(mFastestInterval);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended");
}
})
.addOnConnectionFailedListener(mOnConnectionFailedListener)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
//stop listening location
private void stopLocationListener() {
if(mLocationHelper != null){
mLooperHandler.getLooper().quit();
if(mGoogleApiClient != null && mLocationListener != null
&& mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
}
}