2015-05-09 16 views
10

Wie können Standort-Updates direkt an Intent Service gesendet werden? Der folgende Ansatz funktioniert nicht. OnConnected Funktion wird aufgerufen, aber dann ist es die Absicht, nie in den Dienst erhalten:Standort-Updates an IntentService senden

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

Intent Service:

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-Datei:

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

, wenn Sie sind auf dem Emulator Sie diesen Link gesetzt Geolocation sehen maually haben: http://stackoverflow.com/questions/2279647/how-to-emulate-gps-location-in-the-android-emulator hast du m_googleApiClient.connect() ?? – kamokaze

Antwort

20

Hier ist funktionierender und getesteter Code, der erfolgreich einen IntentService als Empfänger für den Intent im PendingIntent für Standortaktualisierungen basierend auf dem gefundenen Code here erstellt.

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

Und hier ist der Activity-Code, der für Standortaktualisierungen mit einem PendingIntent registriert, die zum IntentService gesendet wird:

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

Resultierende Protokolle:

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

Ich weiß nicht, warum das nicht für mich funktioniert. requestLocationUpdates wird aufgerufen, onHandleIntent jedoch nicht. –

+1

Nevermind, ich habe vergessen, den Dienst im Manifest hinzuzufügen –

-1

Sie können getService() -Methode von pendingIntent und im Service onStartCommand() können Sie die entsprechende Absicht erhalten. getBroadcast() sendet eine Broadcast-Nachricht, für die Sie einen Broadcast-Empfänger registrieren müssen, um ihn anzuhören. Hoffe das hilft.

+0

Ich habe meinen Code entsprechend Ihrem Beitrag aktualisiert, kann jedoch immer noch keine Standortaktualisierungen in meinem Intent-Service erhalten. Bitte sehen Sie meinen aktualisierten Code in der bearbeiteten Frage. –

+0

Überprüfen Sie, ob onConnected() aufgerufen wird oder nicht – Aks

+0

Es ist aber nichts passiert danach. Irgendwelche Ideen wie könnte ich das debuggen? –

0

Intent-Dienste sind von Natur aus für Terminal-Tasks gedacht, z. B. Empfangsabsicht von Aufrufaktivität oder Fragment, Start einer Task in einem separaten Thread und unbemerktes Beenden, ohne eine Entität über ihre Beendigung zu informieren. Es gibt auch eine Notiz, dass onStartCommand nicht für Intent Services ([IntentService] [1]) außer Kraft gesetzt werden sollte. Meine Vermutung ist, dass Ihr Dienst beendet wird, wenn Sie erwarten, dass es am Leben ist und daher die Absicht nicht richtig geliefert wird.

Bound Dienste wäre eine geeignete Option sein, da sie erlauben verschiedene Komponenten selbst zu befestigen und die erforderliche Kommunikation durchführen.

+0

Meine Idee ist, das Standort-Update im Intent-Dienst zu verarbeiten und dann zu beenden, bis das nächste Update kommt - für mich sieht das aus wie eine völlig akzeptable Nutzung des Intent-Dienstes, korrigiere mich, wenn ich falsch liege.Auch nicht sicher, was Sie meinen: "beendet sich selbst", sollte ich in diesem Fall keine Protokollierung von meinen Service-Methoden sehen? –

+0

Ich sehe, dann ja, Intent Service wäre eine gute Lösung für diesen Zweck. In diesem Fall müssen Sie nur onHandleIntent überschreiben und die gesamte Standortaktualisierungslogik dort handhaben. Versuchen Sie, onStartCommand zu entfernen, legen Sie Ihre Protokollanweisungen in onHandleIntent und sehen Sie, ob onHandleIntent überhaupt aufgerufen wird. – dkarmazi

+0

Nein immer noch das gleiche, ich bin wirklich verwirrt über dieses Problem. Irgendwelche Ideen, wo soll ich anfangen zu debuggen? –

0

Sie können es nicht direkt tun - ich bedeuten requestLocationUpdates und erhalten diese Updates in IntentService.

Was Sie tun können, ist eine Service im Hintergrund haben, die diese Updates über requestLocationUpdates anfordert und läuft die ganze Zeit, die Sie wollen (erinnern Sie sich an den Fall, wenn das Gerät einschläft). Dann von diesem Service, wenn das Standort-Update dort empfangen wird, feuern Sie es in Richtung IntentService und behandeln dort.