在 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);
        }
    }
}
}