如何启用android后台位置更新?

时间:2011-02-20 18:41:05

标签: android geolocation broadcastreceiver

嘿大家, 我正在编写一个应用程序,使用地理位置来跟踪用户在从A点走到B点时。这是我的代码到目前为止:

public class LocationTest extends Activity {   
    private static final String[] S = { "out of service", "temporarily unavailable", "available" };
    ArrayList<Location> list = new ArrayList<Location>();
    private TextView output;
    private String best;
    LocationListener locationListener;
    LocationManager mgr;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
        output = (TextView) findViewById(R.id.output);

        mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        Criteria criteria = new Criteria(); 
        best = mgr.getBestProvider(criteria, true);
        log("\nBest provider is: " + best);

        locationListener = new LocationListener(){
        public void onLocationChanged(Location location){
            dumpLocation(location);
            list.add(location);
        }

        public void onStatusChanged(String provider, int status, Bundle extras){
            log("\nProvider status changed: " + provider + ", status=" + S[status]);
        }

        public void onProviderEnabled(String provider){
            log("\nProvider enabled: " + provider);
        }

        public void onProviderDisabled(String provider){
            log("\nProvider disabled: " + provider);
        }
    };
 }

 @Override
 protected void onResume(){
     super.onResume();
     mgr.requestLocationUpdates(best, 120000, 50, locationListener);
 }

 @Override
 protected void onPause(){
     super.onPause();
     mgr.removeUpdates(locationListener);
     log_gen(list);
}

每当获得新修补程序时,应用程序当前都会显示经度和纬度。但是,跟踪仅在屏幕上显示“活动”时才会生效,并且只要用户退出应用程序,跟踪就会停止。我希望我的应用程序做的是即使退出应用程序也会在后台跟踪用户。例如,每当他在几分钟后重新打开应用程序时,背景中捕获的所有坐标都应显示在屏幕上。

根据我目前的研究,有两种方法可以解决这个问题:使用后台服务进行跟踪或使用

requestLocationUpdates (String provider, long minTime, float minDistance, PendingIntent intent)

BroadcastReceiver结合使用即使用户退出应用也会继续获取位置更新。如果我理解正确,第二种方法将继续在后台运行。有人可以在代码中向我展示如何使用BroadcastReceiver

的替代版本实施requestLocationUpdates

非常感谢提前。

1 个答案:

答案 0 :(得分:0)

使用以下代码,您可以很好地获得定期位置更新,如果您担心持续运行的服务,您可以自定义获取位置更新的时间间隔,您还需要在您的应用中集成Google Play服务,以便以下顺序代码工作

public class BackgroundLocationService extends Service implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {

    IBinder mBinder = new LocalBinder();

private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
// Flag that indicates if a request is underway.
private boolean mInProgress;
private static final String TAG = BackgroundLocationService.class
        .getSimpleName();
private Boolean servicesAvailable = false;

public class LocalBinder extends Binder {
    public BackgroundLocationService getServerInstance() {
        return BackgroundLocationService.this;
    }
}

@Override
public void onCreate() {
    super.onCreate();

    mInProgress = false;
    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create();
    // Use high accuracy
    mLocationRequest
            .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    // Set the update interval to 5 seconds
    mLocationRequest.setInterval(Constants.UPDATE_INTERVAL);
    // Set the fastest update interval to 1 second
    mLocationRequest.setFastestInterval(Constants.FASTEST_INTERVAL);

    servicesAvailable = servicesConnected();

    /*
     * Create a new location client, using the enclosing class to handle
     * callbacks.
     */
    mLocationClient = new LocationClient(this, this, this);

}

private boolean servicesConnected() {

    // Check that Google Play services is available
    int resultCode = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(this);

    // If Google Play services is available
    if (ConnectionResult.SUCCESS == resultCode) {

        return true;
    } else {

        return false;
    }
}

public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);

    if (!servicesAvailable || mLocationClient.isConnected() || mInProgress)
        return START_STICKY;

    setUpLocationClientIfNeeded();
    if (!mLocationClient.isConnected() || !mLocationClient.isConnecting()
            && !mInProgress) {
        mInProgress = true;
        mLocationClient.connect();
    }

    return START_STICKY;
}

/*
 * Create a new location client, using the enclosing class to handle
 * callbacks.
 */
private void setUpLocationClientIfNeeded() {
    if (mLocationClient == null)
        mLocationClient = new LocationClient(this, this, this);
}

// Define the callback method that receives location updates
@Override
public void onLocationChanged(final Location location) {
    // Report to the UI that the location was updated
    String msg = Double.toString(location.getLatitude()) + ","
            + Double.toString(location.getLongitude());
    Log.d("debug", msg);

    if (location != null) {
        // location has the latitude and longitude
    }

    // Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();

}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

public String getTime() {
    SimpleDateFormat mDateFormat = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss", Locale.US);
    return mDateFormat.format(new Date());
}


@Override
public void onDestroy() {
    // Turn off the request flag
    mInProgress = false;
    if (servicesAvailable && mLocationClient != null) {
        mLocationClient.removeLocationUpdates(this);
        // Destroy the current location client
        mLocationClient = null;
    }
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new
    // Date()) + ": Disconnected. Please re-connect.",
    // Toast.LENGTH_SHORT).show();
    super.onDestroy();
}

/*
 * Called by Location Services when the request to connect the client
 * finishes successfully. At this point, you can request the current
 * location or start periodic updates
 */
@Override
public void onConnected(Bundle bundle) {

    // Request location updates using static settings
    mLocationClient.requestLocationUpdates(mLocationRequest, this);

}

/*
 * Called by Location Services if the connection to the location client
 * drops because of an error.
 */
@Override
public void onDisconnected() {
    // Turn off the request flag
    mInProgress = false;
    // Destroy the current location client
    mLocationClient = null;
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new
    // Date()) + ": Disconnected. Please re-connect.",
    // Toast.LENGTH_SHORT).show();

}

/*
 * Called by Location Services if the attempt to Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    mInProgress = false;

    /*
     * Google Play services can resolve some errors it detects. If the error
     * has a resolution, try sending an Intent to start a Google Play
     * services activity that can resolve error.
     */
    if (connectionResult.hasResolution()) {

        // If no resolution is available, display an error dialog
    } else {

    }
}

For integrating google play services please refer here