启动时的位置更新 - 在 activity 后打开和关闭

Location Updates on Boot - turn on and off in activity

我从 Google 的 LocationUpdatesPendingIntent 示例开始。 我已将位置内容从 Main Activity 移至 onBoot 广播接收器,因为我需要在设备启动时立即开始位置更新。这非常有效,并在状态栏中提供了通知。

但是我该如何打开和关闭 Activity 的位置更新?

这用于轮询车辆位置。

这是我的 BroadcastReceiver:

public class StartupComplete1 extends BroadcastReceiver {

private static final long UPDATE_INTERVAL = 10000; // Every 10 seconds.
private static final long FASTEST_UPDATE_INTERVAL = 5000; // Every 5 seconds
private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 2; // Every 20 seconds.
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;

@Override
public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
        createLocationRequest();

        try {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, getPendingIntent(context));
        } catch (SecurityException e) {
            Toast.makeText(context, "Error - Cant start location updates", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }
}

private PendingIntent getPendingIntent(Context context) {
    Intent intent = new Intent(context, LocationUpdatesBroadcastReceiver.class);
    intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

private void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME);
}

开始检查广播接收器中的位置更新不是一个好主意。基于 android documentation 用于广播接收器

As a general rule, broadcast receivers are allowed to run for up to 10 seconds before they system will consider them non-responsive and ANR the app. Since these usually execute on the app's main thread, they are already bound by the ~5 second time limit of various operations that can happen there (not to mention just avoiding UI jank), so the receive limit is generally not of concern. However, once you use goAsync, though able to be off the main thread, the broadcast execution limit still applies, and that includes the time spent between calling this method and ultimately PendingResult.finish().

当位置更新需要更长的响应时间时,这可能会导致 ANR,尤其是当您在室内时。

您应该在启动完成的广播接收器的 onReceive() 上启动粘性服务。然后 MainActivity 可以绑定到该服务以执行必要的操作。

如果您的目标是 Android O,此方法可能会出现问题。请检查 this post,其中解释了 Android O 的背景位置收集。