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

发布于 2024-10-18 10:21:22 字数 2259 浏览 5 评论 0原文

嘿大家, 我正在编写一个应用程序,当用户从 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);
}

每当获得新的修复时,该应用程序当前都会显示经度和纬度。但是,只有当 Activity 显示在屏幕上时,跟踪才会起作用,并且一旦用户退出应用程序,跟踪就会停止。我希望我的应用程序做的是在后台继续跟踪用户,即使他退出应用程序也是如此。例如,每当他在几分钟后重新打开应用程序时,在后台捕获的所有坐标都应显示在屏幕上。

根据我到目前为止的研究,有两种方法可以实现这一点:要么使用后台服务进行跟踪,要么

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

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

提前非常感谢。

Hey everybody,
I am writing an app that uses geolocation to track a user while he is walking from point A to point B. Here is my code so far:

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

The app currently displays longitude and latitude whenever new fix is obtained. However, the tracking only works when the Activity is displayed on the screen and as soon as the user quits the app the tracking stops. What I want my app to do is keep tracking the user in the background even if he quits the app. Whenever he re-opens an app few minutes later, for example, all the coordinates captured in the background should be displayed on the screen.

From what I researched so far, there are two ways one can go about it: either use a background service to do the tracking or use

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

in combination with BroadcastReceiver to continue getting location updates even if the user quits the app. If I am understanding correct, the second method would continue running in the background. Can someone please show to me in code how to implement BroadcastReceiver with the alternate version of requestLocationUpdates

Many thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日 2024-10-25 10:21:22

使用下面的代码,您可以很好地获得定期位置更新,如果担心连续运行的服务,您可以自定义获取位置更新的时间间隔,您还需要在应用程序中集成 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 {

    }
}

有关集成 Google Play 服务的信息,请参阅此处

Using the below code you can get the periodic location updates well if are concerned for the continuously running service you can customise the interval for getting the location updates also you would need to integrate the google play services in you app in order the following code to work

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文