谷歌的示例源代码是为了在前端轻松实现连续的位置更新,但我仍然可以使用FusedLocationApi和PendingIntent清楚地了解背景位置更新的工作原理。
LocationService类:
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 代码看起来很乱,所以我将在驱动器链接中共享代码:https://drive.google.com/open?id=0B7QMYFlbkUpOVjkxMUtfenRLXzA
中的示例进行操作示例中的以下部分是我无法理解MainActivity中的位置。如何使用广播接收器接收位置更新?我还需要清楚地了解在后台运行的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
}
}
};
答案 0 :(得分:5)
在下面的示例中,当应用程序使用PRIORITY_HIGH_ACCURACY模式每5秒在后台运行时,您可以收到位置更新。您将通过接收指示您的位置坐标的通知来查看这些更新。
我还想测试是否可以在应用程序被系统杀死后收到更新,如here所述:
公共摘要PendingResult requestLocationUpdates(GoogleApiClient客户端,LocationRequest请求,PendingIntent callbackIntent)
此方法适用于后台使用案例,更适用于接收位置更新,即使应用程序已被系统杀死。为此,请对已启动的服务使用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"/>