2015-05-09 10 views
10

In che modo gli aggiornamenti di posizione possono essere inviati direttamente a Intent Service? Il seguente approccio non funziona. Funzione OnConnected viene chiamata, ma poi l'intento non è mai ricevuto nel servizio:Invia aggiornamenti posizione a IntentService

... 
    private PendingIntent getLocationPendingIntent(boolean shouldCreate) { 
     Intent broadcast = new Intent(m_context,LocationUpdateService.class); 
     int flags = shouldCreate ? 0 : PendingIntent.FLAG_NO_CREATE; 
     return PendingIntent.getService(m_context, 0, broadcast, flags); 
    } 



    @Override 
    public void onConnected(Bundle arg0) { 
     PendingIntent locationPendingIntent = getLocationPendingIntent(true);   
     LocationRequest locationRequest = new LocationRequest(); 
     locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     locationRequest.setInterval(LOCATION_UPDATE_INTERVAL); 
     locationRequest.setFastestInterval(LOCATION_FASTEST_UPDATE_INTERVAL); 
     LocationServices.FusedLocationApi.requestLocationUpdates(m_googleApiClient, locationRequest,locationPendingIntent); 
} 
... 

Servizio Intent:

import android.app.IntentService; 
import android.content.Intent; 
import android.util.Log; 

public class LocationUpdateService extends IntentService { 

    public LocationUpdateService() { 
     super(LocationUpdateService.class.getName()); 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startID) { 
     super.onStartCommand(intent, flags, startID); 
     Log.d("LocationUpdateService","Location received"); 
     return START_REDELIVER_INTENT; 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     Log.d("LocationUpdateService","Intent received"); 

    } 
} 

manifest: metodo

... 
<service android:name=".LocationUpdateService" /> 
... 
+0

quando si sono sull'emulatore è necessario impostare maually geolocalizzazione vedere questo link: http://stackoverflow.com/questions/2279647/how-to-emulate-gps-location-in-the-android-emulator hai chiamato m_googleApiClient.connect() ?? – kamokaze

risposta

20

Ecco il codice funzionante e testato che imposta con successo IntentService come ricevitore per l'Intento incluso nel PendingIntent utilizzato per gli aggiornamenti di posizione, in base al codice trovato here.

In primo luogo, il IntentService:

import android.app.IntentService; 
import android.content.Intent; 
import android.location.Location; 
import android.util.Log; 
import com.google.android.gms.location.FusedLocationProviderApi; 
import com.google.android.gms.location.LocationResult; 

public class LocationUpdateService extends IntentService { 

    private final String TAG = "LocationUpdateService"; 
    Location location; 

    public LocationUpdateService() { 

     super("LocationUpdateService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     if (LocationResult.hasResult(intent)) { 
      LocationResult locationResult = LocationResult.extractResult(intent); 
      Location location = locationResult.getLastLocation(); 
      if (location != null) { 
       Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude()); 
      } 
     } 
    } 
} 

Ed ecco il codice di attività che si registra per gli aggiornamenti di posizione con un PendingIntent che viene inviato al IntentService:

import android.app.PendingIntent; 
import android.os.Bundle; 
import android.content.Intent; 
import android.app.Activity; 
import android.widget.Toast; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

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

    LocationRequest mLocationRequest; 
    GoogleApiClient mGoogleApiClient; 
    PendingIntent mRequestLocationUpdatesPendingIntent; 

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

     buildGoogleApiClient(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    protected void onPause(){ 
     super.onPause(); 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mRequestLocationUpdatesPendingIntent); 
     } 
    } 

    protected synchronized void buildGoogleApiClient() { 
     Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show(); 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show(); 

     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(10); 
     mLocationRequest.setFastestInterval(10); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
     //mLocationRequest.setSmallestDisplacement(0.1F); 

     // create the Intent to use WebViewActivity to handle results 
     Intent mRequestLocationUpdatesIntent = new Intent(this, LocationUpdateService.class); 

     // create a PendingIntent 
     mRequestLocationUpdatesPendingIntent = PendingIntent.getService(getApplicationContext(), 0, 
       mRequestLocationUpdatesIntent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 

     // request location updates 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, 
       mLocationRequest, 
       mRequestLocationUpdatesPendingIntent); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show(); 
    } 
} 

logs risultante:

D/locationtesting﹕ accuracy: 10.0 lat: 37.779702 lon: -122.3931595 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797023 lon: -122.3931594 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797022 lon: -122.3931596 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797021 lon: -122.3931597 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797021 lon: -122.3931596 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797019 lon: -122.3931597 
D/locationtesting﹕ accuracy: 10.0 lat: 37.7797019 lon: -122.3931597 
+0

Non so perché questo non funziona per me. requestLocationUpdates viene chiamato ma onHandleIntent no. –

+1

Nevermind, ho dimenticato di aggiungere il servizio nel manifest –

-1

È possibile utilizzare getService() di pendingIntent e onStartCommand() del servizio è possibile ottenere l'intento corrispondente. getBroadcast() invia una trasmissione per cui è necessario registrare un ricevitore broadcast da ascoltare. Spero che questo ti aiuti.

+0

Ho aggiornato il mio codice in base al tuo post, tuttavia, non riesco ancora ad ottenere gli aggiornamenti di posizione nel mio Servizio di Intenti. Si prega di consultare il mio codice aggiornato nella domanda modificata. –

+0

Controlla se onConnected() viene chiamato o meno – Aks

+0

È ma dopo non succede nulla. Qualche idea come posso eseguire il debug di questo? –

0

I servizi di intenti per loro natura sono destinati alle attività del terminale, come ricevere l'intento di chiamare attività o frammenti, avviare alcune attività su un thread separato e terminare in silenzio, senza notificare alcuna entità della sua terminazione. C'è anche una documentazione di note che onStartCommand non deve essere sovrascritto per Intent Services ([IntentService] [1]). La mia ipotesi è che il tuo servizio finisca da solo quando ti aspetti che sia vivo e, quindi, l'intento non viene consegnato correttamente.

I servizi associati sono un'opzione più adatta in quanto consentono a diversi componenti di collegarsi a se stessi ed eseguire la comunicazione richiesta.

+0

La mia idea è di elaborare l'aggiornamento della posizione nel servizio Intent e quindi terminarlo fino al prossimo aggiornamento, per me sembra un uso totalmente inteso del servizio intent, correggimi se sbaglio.Inoltre non sono sicuro di cosa intendi con: "finisce se stesso", non dovrei vedere alcun registro dai miei metodi di servizio in questo caso? –

+0

Vedo, quindi sì, Intent Service sarebbe adatto per tale scopo. In questo caso, è sufficiente eseguire override suHandleIntent e gestire la logica di aggiornamento della posizione in tale posizione. Prova a eliminare onStartCommand, metti le istruzioni del tuo registro su onHandleIntent e controlla se onHandleIntent viene richiamato. – dkarmazi

+0

Non è ancora lo stesso, sono davvero confuso da questo problema. Qualche idea dove dovrei iniziare il debug? –

0

Non è possibile farlo direttamente - I significa requestLocationUpdates e ottenere quegli aggiornamenti in IntentService.

Quello che puoi fare è avere uno Service in background che richiede quegli aggiornamenti tramite requestLocationUpdates ed è in esecuzione tutto il tempo che vuoi (ricorda del caso in cui il dispositivo si addormenta). Quindi da quello Service quando l'aggiornamento della posizione viene ricevuto, accenderlo verso IntentService e gestirlo lì.

Problemi correlati