2011-11-28 11 views
5

sto targeting di Google API 2.3.3 e hanno la seguente classe di testMockLocation testProvider non chiama onLocationChanged

import android.content.Context; 
import android.location.Criteria; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.location.LocationProvider; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.test.AndroidTestCase; 
import android.util.Log; 

public class MockLocationManagerTests extends AndroidTestCase implements LocationListener{ 

    private static final String TAG = "MockLocationTests"; 
    private String locationProvider = "TestProvider"; 
    private LocationManager locationManager; 
    private Location lastLocation; 

    protected void setUp() throws Exception { 
     super.setUp(); 
     locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE); 
     if (Settings.Secure.getInt(getContext().getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) { 
       fail("Mock location must be enabled"); 
     } 
     setupLocationManager(); 
    } 

    private void setupLocationManager() { 
     if (locationManager.getProvider(locationProvider) != null) { 
      locationManager.removeTestProvider(locationProvider); 
     } 

     locationManager.addTestProvider(locationProvider, 
             false, 
             true, 
             false, 
             false, 
             false, 
             false, 
             false, 
             Criteria.POWER_LOW, 
             Criteria.ACCURACY_FINE); 
     locationManager.requestLocationUpdates(locationProvider, 0, 0, this); 
     locationManager.setTestProviderStatus(locationProvider, LocationProvider.AVAILABLE, null, System.currentTimeMillis()); 
     locationManager.setTestProviderEnabled(locationProvider, true); 
    } 

    private Location createLocation(double lat, double lon) { 
     Location location = new Location(locationProvider); 
     location.setLatitude(lat); 
     location.setLongitude(lon); 
     location.setAltitude(0); 
     location.setTime(System.currentTimeMillis()); 
     return location; 
    } 

    protected void tearDown() throws Exception { 
     super.tearDown(); 
    } 

    public final void testCanObserveLocationChanging() throws InterruptedException { 
     Location l = createLocation(19,-2); 
     locationManager.setTestProviderLocation(locationProvider,l); 
     synchronized(this){ 
      wait(5000); 
     } 
     Location l2 = createLocation(1,-10); 
     locationManager.setTestProviderLocation(locationProvider,l2); 
     synchronized(this){ 
      wait(5000); 
     } 
     assertEquals(l,lastLocation); 
    } 

    public void onLocationChanged(Location location) { 
     Log.i(TAG,"location changed"); 
     lastLocation = location;   
    } 

    public void onProviderDisabled(String provider) { 
     Log.i(TAG, provider+" disabled"); 
    } 

    public void onProviderEnabled(String provider) { 
     Log.i(TAG, provider+" enabled"); 
    } 

    public void onStatusChanged(String provider, int status, Bundle extras) { 
     Log.i(TAG,"status changed: "+provider+" to "+status); 
    } 
} 

onLocationChanged non viene chiamato e il mio google-fu e il cervello-fu mi sta venendo a mancare. Qualche consiglio molto apprezzato

UPDATE

nessuno dei messaggi di log vengono catturati in modo OnStatusChanged e onProviderEnabled non sparano?

Se chiamo getLastKnownLocation() tra le chiamate al setTestProviderLocation() il locationManager restituisce la posizione ho impostato

un altro aggiornamento

Se aggiungo la classe che utilizza questo codice per la mia domanda allora onLocationChanged() è chiamato. L'unica differenza è che non sto usando Mock_Location. Quindi sembra che setTestProviderLocation() non stia causando onLocationChanged() per sparare

+0

Stai usando un emulatore o un telefono? Neanche io vedo niente di sbagliato. Suppongo che tu abbia aggiunto il comando " " – Reno

+0

Questo sta usando l'emulatore e sì, hai impostato il permesso di posizione Mock. –

risposta

0

Hai abilitato posizioni fittizie sul tuo telefono o emulatore? Esiste un'impostazione per questo nelle applicazioni/sviluppo/posizioni simulate.

+0

È abilitato sì. Sto pensando che questo sia un bug con setTestProviderLocation che non chiama onLocationChanged poiché la stessa stessa classe di sotto test funziona sull'emulatore. Non funziona "solo" quando è eseguito da un test. –

-1

Basta fare clic su "Invia" nella scheda di controllo dell'emulazione dell'eclisse per inviare le coordinate all'app. enter image description here

+1

Sto provando a installare * test automatizzato *. Da allora mi sono trasferito all'utilizzo di robolectric e roboguice, quindi non l'ho mai effettivamente risolto –

1

Si comporta allo stesso modo su Google API 19.

L'AndroidTestCase no impostare un corretto Looper per la gestione degli eventi di aggiornamento. È necessario eseguirlo come un'attività di test ActivityInstrumentationTestCase2 o aggiungere un ThreadLooper a AndroidTestCase per gestire i messaggi di aggiornamento.

Looper mLooper; 
HandlerThread thread = new HandlerThread("LocationHandlerThread"); 
thread.start(); // starts the thread. 
mLooper = thread.getLooper(); 

Quindi utilizzare il nuovo Looper nel metodo requestLocationUpdates:

mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, mLocationListener, mLooper);