使用PendingIntent进行后台位置更新的FusedLocationApi。无法接收更新。

8
从谷歌获取的示例源代码很容易在前端实现持续位置更新,但是我仍然无法清楚地理解和获取使用FusedLocationApi和PendingIntent进行后台位置更新的工作原理。
public class LocationService extends IntentService {
private static final String TAG = LocationService.class.getSimpleName();

private static final String ACTION_LOCATION_UPDATED = "location_updated";
private static final String ACTION_REQUEST_LOCATION = "request_location";

public static IntentFilter getLocationUpdatedIntentFilter() {
    return new IntentFilter(LocationService.ACTION_LOCATION_UPDATED);
}

public static void requestLocation(Context context) {
    Intent intent = new Intent(context, LocationService.class);
    intent.setAction(LocationService.ACTION_REQUEST_LOCATION);
    context.startService(intent);
}

public LocationService() {
    super(TAG);
}

@Override
protected void onHandleIntent(Intent intent) {
    String action = intent != null ? intent.getAction() : null;
    if (ACTION_REQUEST_LOCATION.equals(action)) {
        onRequestLocation();
    }
    else if(ACTION_LOCATION_UPDATED.equals(action)) {
        onLocationUpdated(intent);
    }
}

/**
 * Called when a location update is requested. We block until we get a result back.
 * We are using Fused Location Api.
 */
private void onRequestLocation() {
    Log.v(TAG, ACTION_REQUEST_LOCATION);
    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .build();

    // we block here
    ConnectionResult connectionResult = googleApiClient.blockingConnect(10, TimeUnit.SECONDS);

    if (connectionResult.isSuccess() && googleApiClient.isConnected()) {

        Intent locationUpdatedIntent = new Intent(this, LocationService.class);
        locationUpdatedIntent.setAction(ACTION_LOCATION_UPDATED);

        // Send last known location out first if available
        Location location = FusedLocationApi.getLastLocation(googleApiClient);
        if (location != null) {
            Intent lastLocationIntent = new Intent(locationUpdatedIntent);
            lastLocationIntent.putExtra(
                    FusedLocationProviderApi.KEY_LOCATION_CHANGED, location);
            startService(lastLocationIntent);
        }

        // Request new location
        LocationRequest mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        FusedLocationApi.requestLocationUpdates(
                googleApiClient, mLocationRequest,
                PendingIntent.getService(this, 0, locationUpdatedIntent, 0));

        googleApiClient.disconnect();
    } else {
        Log.e(TAG, String.format("Failed to connect to GoogleApiClient (error code = %d)",
                connectionResult.getErrorCode()));
    }
}

/**
 * Called when the location has been updated & broadcast the new location
 */
private void onLocationUpdated(Intent intent) {
    Log.v(TAG, ACTION_LOCATION_UPDATED);

    // Extra new location
    Location location =
            intent.getParcelableExtra(FusedLocationProviderApi.KEY_LOCATION_CHANGED);

    if (location != null) {
        LatLng latLngLocation = new LatLng(location.getLatitude(), location.getLongitude());
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
 }
}

MainActivity

代码看起来有点乱,所以我会在一个Google Drive链接中分享代码:https://drive.google.com/open?id=0B7QMYFlbkUpOVjkxMUtfenRLXzA

然而,我已经遵循了https://gist.githubusercontent.com/allenchi/c9659369c306752c0047/raw/16d6cd8e311013379e55b496d2b6d13347f418d6/gistfile1.txt的例子。

以上例子中的部分是我无法理解如何在MainActivity中放置。我该如何使用Broadcast receiver接收位置更新?我还需要清楚地了解FusedLocation在后台运行的情况,以及如何利用它来实现即时GPS跟踪器。

@Override
protected void onResume() {
    super.onResume();
    if(checkPlayServices()) {
        LocationService.requestLocation(this);
        LocalBroadcastManager.getInstance(getActivity())
                   .registerReceiver(locationReceiver, LocationService.getLocationUpdatedIntentFilter());
    }
}

@Override
public void onResume() {
    super.onResume();
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
    locationReceiver, LocationService.getLocationUpdatedIntentFilter());
}

@Override
public void onPause() {
    super.onPause();
    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(locationReceiver);
}

private BroadcastReceiver locationReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Location location = intent.getParcelableExtra(FusedLocationProviderApi.KEY_LOCATION_CHANGED);
        if (location != null) {
          LatLng latestLocation = new LatLng(location.getLatitude(), location.getLongitude());
          // do something with the location
        }
    }
};
1个回答

5
在下面的示例中,您可以使用PRIORITY_HIGH_ACCURACY模式每5秒接收应用程序在后台运行时的位置更新。您将通过接收指示您位置坐标的通知来查看这些更新。
我还想测试一下,即使应用程序已被系统杀死,是否仍然可以接收到更新,如此处所述:
此方法适用于后台使用情况,更具体地说是用于接收位置更新,即使应用程序已被系统杀死。为此,请使用用于启动服务的PendingIntent。
这就是为什么我在Activity的onBackPressed()方法中调用System.exit(0)的原因,当然您可以省略这个调用。
服务:
public class LocationService extends IntentService{

private static final String INTENT_SERVICE_NAME = LocationService.class.getName();

public LocationService() {
    super(INTENT_SERVICE_NAME);
}

@Override
protected void onHandleIntent(Intent intent) {
    if (null == intent) {
        return;
    }

    Bundle bundle = intent.getExtras();

    if (null == bundle) {
        return;
    }

    Location location = bundle.getParcelable("com.google.android.location.LOCATION");

    if (null == location) {
        return;
    }

    if (null != location) {
        // TODO: Handle the incoming location

        Log.i(INTENT_SERVICE_NAME, "onHandleIntent " + location.getLatitude() + ", " + location.getLongitude());

        // Just show a notification with the location's coordinates
        NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder notification = new NotificationCompat.Builder(this);
        notification.setContentTitle("Location");
        notification.setContentText(location.getLatitude() + ", " + location.getLongitude());
        notification.setSmallIcon(R.drawable.ic_audiotrack);
        notificationManager.notify(1234, notification.build());
    }
}

活动:

该活动:

public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

private GoogleApiClient googleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

}

@Override
public void onStart() {
    super.onStart();
    googleApiClient.connect();
}

@Override
public void onStop() {
    super.onStop();
    if (googleApiClient.isConnected()) {
        googleApiClient.disconnect();
    }
}

@Override
public void onBackPressed() {
    // Check whether you receive location updates after the app has been killed by the system
    System.exit(0);
}

@Override
public void onConnected(Bundle bundle) {
    requestLocationUpdates();
}

@Override
public void onConnectionSuspended(int cause) {
    googleApiClient.connect();
}

@Override
public void onConnectionFailed(ConnectionResult result) {

}

public void requestLocationUpdates() {
    LocationRequest locationRequest = new LocationRequest()
            .setInterval(5 * 1000)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    Intent intent = new Intent(this, LocationService.class);
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, pendingIntent);
}

清单文件中的权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

1
意图服务也应在清单文件中声明:<service android:name=".Service.LocationService" android:exported="false" /> - Nabzi
这将从前台活动中检索位置。用户要求在后台中检索它。 - UserK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接