2015-11-16 22 views
5

Il codice sorgente di esempio da google è stato facile implementare aggiornamenti di posizione continui su frontend, ma non riesco ancora a ottenere o capire chiaramente come funzionano gli aggiornamenti delle posizioni in background utilizzando FusedLocationApi e PendingIntent.FusedLocationApi con PendingIntent per gli aggiornamenti delle posizioni in background. Impossibile ricevere gli aggiornamenti

classe 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 Il codice è disordinato quindi voglio condividere il codice in un collegamento drive: https://drive.google.com/open?id=0B7QMYFlbkUpOVjkxMUtfenRLXzA

Tuttavia, ho seguito l'esempio da https://gist.githubusercontent.com/allenchi/c9659369c306752c0047/raw/16d6cd8e311013379e55b496d2b6d13347f418d6/gistfile1.txt

La seguente parte dell'esempio è ciò che non riesco a capire il posizionamento in MainActivity. Come posso ricevere gli aggiornamenti sulla posizione utilizzando il ricevitore Broadcast? Avrei anche bisogno di una chiara comprensione di FusedLocation in esecuzione in background e di come posso utilizzare per implementare un tracker gps "al volo".

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

risposta

4

Nell'esempio qui sotto riceverai gli aggiornamenti sulla posizione quando l'app viene eseguito in background ogni 5 secondi utilizzando la modalità PRIORITY_HIGH_ACCURACY. Vedrai questi aggiornamenti ricevendo notifiche che indicano le coordinate della tua posizione.

ho anche voluto verificare se gli aggiornamenti possono essere ricevuti dopo l'applicazione è stato ucciso dal sistema come si afferma here:

pubblici requestLocationUpdates PendingResult astratte (client GoogleApiClient, richiesta LocationRequest, PendingIntent callbackIntent)

Questo metodo è adatto per i casi di utilizzo in background, in particolare per ricevere gli aggiornamenti di posizione, anche se l'applicazione è stata uccisa dal sistema. Per fare ciò, usa un PendingIntent per un servizio iniziato.

è per questo che ho chiamato System.exit (0) nel metodo onBackPressed() dell'attività, che ovviamente puoi omettere.

Il Servizio:

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

}

L'Attività:

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

}

Il permesso nel manifesto:

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