Come posso deridere la mia posizione su un dispositivo fisico (Nexus One)? So che puoi farlo con l'emulatore nel pannello di controllo dell'emulatore, ma questo non funziona per un dispositivo fisico.
Come posso deridere la mia posizione su un dispositivo fisico (Nexus One)? So che puoi farlo con l'emulatore nel pannello di controllo dell'emulatore, ma questo non funziona per un dispositivo fisico.
Risposte:
Sembra che l'unico modo per fare sia usare un provider di localizzazione fittizia.
Devi abilitare posizioni simulate nel pannello di sviluppo nelle tue impostazioni e aggiungere
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
al tuo manifest.
Ora puoi inserire il tuo codice e creare il tuo provider di posizioni fittizie e impostare la posizione di questo provider.
Se si utilizza questo telefono solo nel laboratorio di sviluppo, è possibile saldare il chip GPS e alimentare la porta seriale direttamente con sequenze NMEA da altri dispositivi.
Vorrei avere il cavo a portata di mano. So che puoi telnet all'emulatore per cambiare la sua posizione
$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK
Non ricordo se puoi telnet sul tuo dispositivo, ma penso che tu possa farlo. Spero che aiuti.
Per questo (CLI) è necessario adb (ponte di debug Android).
È possibile utilizzare l'autorizzazione dei servizi di localizzazione per deridere la posizione ...
"android.permission.ACCESS_MOCK_LOCATION"
e poi nel tuo codice java,
// Set location by setting the latitude, longitude and may be the altitude...
String[] MockLoc = str.split(",");
Location location = new Location(mocLocationProvider);
Double lat = Double.valueOf(MockLoc[0]);
location.setLatitude(lat);
Double longi = Double.valueOf(MockLoc[1]);
location.setLongitude(longi);
Double alti = Double.valueOf(MockLoc[2]);
location.setAltitude(alti);
Ho avuto successo con il seguente codice. Anche se mi ha dato un unico lucchetto per qualche motivo (anche se ho provato diverse coppie di LatLng), ha funzionato per me. mLocationManager
è un LocationManager
che è collegato a un LocationListener
:
private void getMockLocation()
{
mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
mLocationManager.addTestProvider
(
LocationManager.GPS_PROVIDER,
"requiresNetwork" == "",
"requiresSatellite" == "",
"requiresCell" == "",
"hasMonetaryCost" == "",
"supportsAltitude" == "",
"supportsSpeed" == "",
"supportsBearing" == "",
android.location.Criteria.POWER_LOW,
android.location.Criteria.ACCURACY_FINE
);
Location newLocation = new Location(LocationManager.GPS_PROVIDER);
newLocation.setLatitude (/* TODO: Set Some Lat */);
newLocation.setLongitude(/* TODO: Set Some Lng */);
newLocation.setAccuracy(500);
mLocationManager.setTestProviderEnabled
(
LocationManager.GPS_PROVIDER,
true
);
mLocationManager.setTestProviderStatus
(
LocationManager.GPS_PROVIDER,
LocationProvider.AVAILABLE,
null,
System.currentTimeMillis()
);
mLocationManager.setTestProviderLocation
(
LocationManager.GPS_PROVIDER,
newLocation
);
}
setTestProviderStatus
viene utilizzato qui per notificare / postare / pianificare un evento con il LocationManager che il provider GPS ha trovato una correzione "adesso" in modo che possa avvenire l'elaborazione di detto evento.
mLocationManager
is a LocationManager
che è collegato a un LocationListener"? come posso fare questo? Grazie ..
LocationManager
servizio e un LocationListener
: blog.doityourselfandroid.com/2010/12/25/…
Ciò che Dr1Ku ha pubblicato funziona. Oggi ho usato il codice ma dovevo aggiungere più loc. Quindi, ecco alcuni miglioramenti:
Facoltativo: anziché utilizzare la stringa LocationManager.GPS_PROVIDER, potresti voler definire la tua constat PROVIDER_NAME e usarla. Quando ti registri per gli aggiornamenti di posizione, scegli un provider tramite i criteri invece di specificarlo direttamente come stringa.
Primo: invece di chiamare removeTestProvider, prima controlla se c'è un provider da rimuovere (per evitare IllegalArgumentException):
if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}
Secondo: per pubblicare più di una posizione, è necessario impostare l'orario per la posizione:
newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);
Sembra anche che ci sia un test di Google che utilizza MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java
Un altro buon esempio di lavoro è disponibile all'indirizzo: http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/
Un altro buon articolo è: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 Troverai anche del codice che funziona davvero per io sull'emulatore.
Mock Provider
acceso il normale GPS non funzionava, non riuscivo a ottenere una correzione (stavo testando direttamente su un dispositivo). Questo potrebbe non essere il caso poiché da allora sono successe molte cose in Android.
Esistono app disponibili in Android Market che ti consentono di specificare una "Posizione GPS fittizia" per il tuo dispositivo.
Ho cercato https://market.android.com e trovato un'app chiamata "La mia posizione falsa" che funziona per me.
Il provider GPS Mock menzionato da Paul sopra (su http://www.cowlumbus.nl/forum/MockGpsProvider.zip ) è un altro esempio che include il codice sorgente, anche se non sono stato in grado di installare l'APK fornito (dice Failure [INSTALL_FAILED_OLDER_SDK] e potrebbe essere necessario solo ricompilare)
Per utilizzare posizioni simulate GPS è necessario abilitarlo nelle impostazioni del dispositivo. Vai su Impostazioni -> Applicazioni -> Sviluppo e seleziona "Consenti posizioni fittizie"
È quindi possibile utilizzare un'app come quelle sopra descritte per impostare le coordinate GPS e Google Maps e altre app useranno la posizione GPS finta specificata.
Questo ha funzionato per me (Android Studio):
Disabilita il tracciamento GPS e WiFi sul telefono. Su Android 5.1.1 e versioni precedenti, seleziona "abilita posizioni simulate" in Opzioni sviluppatore.
Crea una copia del tuo manifest nella directory src / debug. Aggiungere quanto segue (al di fuori del tag "applicazione"):
usi-permesso android: name = "android.permission.ACCESS_MOCK_LOCATION"
Imposta un frammento di mappa chiamato "mappa". Includi il seguente codice in onCreate ():
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new MyLocationListener();
if (lm.getProvider("Test") == null) {
lm.addTestProvider("Test", false, false, false, false, false, false, false, 0, 1);
}
lm.setTestProviderEnabled("Test", true);
lm.requestLocationUpdates("Test", 0, 0, ll);
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng l) {
Location loc = new Location("Test");
loc.setLatitude(l.latitude);
loc.setLongitude(l.longitude);
loc.setAltitude(0);
loc.setAccuracy(10f);
loc.setElapsedRealtimeNanos(System.nanoTime());
loc.setTime(System.currentTimeMillis());
lm.setTestProviderLocation("Test", loc);
}
};
Si noti che potrebbe essere necessario aumentare temporaneamente "minSdkVersion" nel file di gradle del modulo su 17 per utilizzare il metodo "setElapsedRealtimeNanos".
Includi il codice seguente nella classe di attività principale:
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}
Esegui la tua app con AS. Su Android 6.0 e versioni successive otterrai un'eccezione di sicurezza. Ora vai su Opzioni sviluppatore in Impostazioni e seleziona "Seleziona app di posizione fittizia". Seleziona la tua app dall'elenco.
Ora quando tocchi sulla mappa, onLocationChanged () si attiva con le coordinate del tuo tocco.
L'ho appena capito, quindi ora non devo andare in giro per il quartiere con i telefoni in mano.
Ho creato un semplice gestore simulando una posizione mobile da una posizione iniziale.
Avviarlo nel callback della connessione:
private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
if (BuildConfig.USE_MOCK_LOCATION) {
LocationServices.FusedLocationApi.setMockMode(mGoogleApiClient, true);
new MockLocationMovingHandler(mGoogleApiClient).start(48.873399, 2.342911);
}
}
@Override
public void onConnectionSuspended(int i) {
}
};
La classe Handler:
private static class MockLocationMovingHandler extends Handler {
private final static int SET_MOCK_LOCATION = 0x000001;
private final static double STEP_LATITUDE = -0.00005;
private final static double STEP_LONGITUDE = 0.00002;
private final static long FREQUENCY_MS = 1000;
private GoogleApiClient mGoogleApiClient;
private double mLatitude;
private double mLongitude;
public MockLocationMovingHandler(final GoogleApiClient googleApiClient) {
super(Looper.getMainLooper());
mGoogleApiClient = googleApiClient;
}
public void start(final double initLatitude, final double initLongitude) {
if (hasMessages(SET_MOCK_LOCATION)) {
removeMessages(SET_MOCK_LOCATION);
}
mLatitude = initLatitude;
mLongitude = initLongitude;
sendEmptyMessage(SET_MOCK_LOCATION);
}
public void stop() {
if (hasMessages(SET_MOCK_LOCATION)) {
removeMessages(SET_MOCK_LOCATION);
}
}
@Override
public void handleMessage(Message message) {
switch (message.what) {
case SET_MOCK_LOCATION:
Location location = new Location("network");
location.setLatitude(mLatitude);
location.setLongitude(mLongitude);
location.setTime(System.currentTimeMillis());
location.setAccuracy(3.0f);
location.setElapsedRealtimeNanos(System.nanoTime());
LocationServices.FusedLocationApi.setMockLocation(mGoogleApiClient, location);
mLatitude += STEP_LATITUDE;
mLongitude += STEP_LONGITUDE;
sendEmptyMessageDelayed(SET_MOCK_LOCATION, FREQUENCY_MS);
break;
}
}
}
Spero che possa aiutare ..
La soluzione menzionata da icyerasor e fornita da Pedro all'indirizzo http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/ ha funzionato molto bene per me. Tuttavia, non offre supporto per l'avvio, l'arresto e il riavvio corretti del provider GPS finto.
Ho modificato un po 'il suo codice e riscritto la classe in modo che fosse un AsyncTask anziché un thread. Questo ci consente di comunicare con il thread dell'interfaccia utente, in modo da poter riavviare il provider nel punto in cui eravamo quando lo abbiamo interrotto. Questo è utile quando cambia l'orientamento dello schermo.
Il codice, insieme a un progetto di esempio per Eclipse, è disponibile su GitHub: https://github.com/paulhoux/Android-MockProviderGPS
Tutto il merito dovrebbe essere affidato a Pedro per aver svolto gran parte del duro lavoro.
Aggiungi al tuo manifest
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation,ProtectedPermissions" />
Funzione di localizzazione fittizia
void setMockLocation() {
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
mockLocation.setLatitude(-33.852); // Sydney
mockLocation.setLongitude(151.211);
mockLocation.setAltitude(10);
mockLocation.setAccuracy(5);
mockLocation.setTime(System.currentTimeMillis());
mockLocation.setElapsedRealtimeNanos(System.nanoTime());
locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mockLocation);
}
Dovrai anche abilitare posizioni simulate nelle impostazioni dello sviluppatore dei tuoi dispositivi. Se questo non è disponibile, imposta "finta applicazione di localizzazione" sulla tua applicazione una volta implementato quanto sopra.
La falsa app GPS di Google Play ha fatto il trucco per me. Assicurati di leggere tutte le indicazioni nella descrizione dell'app. Devi disabilitare altri servizi di localizzazione e avviare l'app dopo aver abilitato "Fake GPS". Ha funzionato alla grande per quello che mi serviva.
Ecco il link all'app su Google Play: GPS falso
Il tutorial di Google per fare questo può essere trovato qui, fornisce esempi di codice e spiega il processo.
http://developer.android.com/training/location/location-testing.html#SendMockLocations
Installa l'app Fake GPS https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en
Opzioni sviluppatore -> Seleziona app di localizzazione fittizia (È media, App di posizione falsa selezionata).
App GPS falsa :
Doppia scheda sulla mappa per aggiungere -> fai clic sul pulsante di riproduzione -> Mostra il brindisi "Posizione falsa interrotta"
infine controlla con le app di google map.
Ho scritto un'app che esegue un WebServer (simile a REST) sul tuo telefono Android, in modo da poter impostare la posizione GPS da remoto . Il sito Web fornisce una mappa su cui è possibile fare clic per impostare una nuova posizione o utilizzare i tasti "wasd" per spostarsi in qualsiasi direzione. L'app è stata una soluzione rapida, quindi non c'è quasi nessuna interfaccia utente né documentazione, ma l'implementazione è semplice e puoi cercare tutto nelle (solo quattro) classi.
Archivio del progetto: https://github.com/juliusmh/RemoteGeoFix
Se il dispositivo è collegato al computer e si sta tentando di modificare i cavi di invio GPS tramite il controllo dell'emulatore, non funzionerà.
Questo è un controllo EMULATOR per un motivo.
Basta configurarlo per aggiornarti sul cambio GPS.
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
onGPSLocationChanged(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
bigInfo.setText("Changed "+ status);
}
public void onProviderEnabled(String provider) {
bigInfo.setText("Enabled "+ provider);
}
public void onProviderDisabled(String provider) {
bigInfo.setText("Disabled "+ provider);
}
};
Quando il GPS viene aggiornato, riscrivi il seguente metodo per fare ciò che desideri;
public void onGPSLocationChanged(Location location){
if(location != null){
double pLong = location.getLongitude();
double pLat = location.getLatitude();
textLat.setText(Double.toString(pLat));
textLong.setText(Double.toString(pLong));
if(autoSave){
saveGPS();
}
}
}
Non dimenticare di metterli nel manifest
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
Mi chiedo se hai bisogno dell'elaborata configurazione di Mock Location. Nel mio caso, una volta trovata una posizione fissa, chiamavo una funzione per fare qualcosa con quella nuova posizione. In un timer creare una posizione simulata. E chiama invece la funzione con quella posizione. Sapendo tutto questo in breve tempo il GPS avrebbe trovato una posizione reale reale. Che va bene Se il tempo di aggiornamento è impostato su un tempo sufficientemente lungo.
Forse non è un approccio da "programmatore", ma se vuoi risparmiare tempo e trovare subito una soluzione funzionante prova una delle app dedicate alla posizione simulata disponibili in Google Play:
Utilizza il simulatore di posizione interattivo molto conveniente e gratuito per telefoni e tablet Android (chiamato CATLES). Rileva la posizione GPS a livello di sistema (anche all'interno delle app di Google Maps o Facebook) e funziona su dispositivi fisici e virtuali:
Utilizzare questa autorizzazione nel file manifest
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">
Android Studio raccomanderà che "La posizione simulata dovrebbe essere richiesta solo in un file manifest specifico per test o debug (in genere src / debug / AndroidManifest.xml)" disabilita semplicemente l'ispezione
Ora assicurati di aver selezionato " Consenti posizioni simulate " nelle impostazioni dello sviluppatore del tuo telefono
Usa LocationManager
locationManager.addTestProvider(mocLocationProvider, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);
Ora imposta la posizione dove vuoi
Location mockLocation = new Location(mocLocationProvider);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lng);
mockLocation.setAltitude(alt);
mockLocation.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation);
Le soluzioni di cui sopra non hanno funzionato per me perché stavo testando su un dispositivo Android con l'ultima versione di Google Play Services che utilizza FusedLocationProviderClient . Dopo aver impostato l'autorizzazione di posizione fittizia nel manifest dell'app e l'app come app di posizione fittizia specificata nelle impostazioni dello sviluppatore (come menzionato nelle risposte precedenti), ho quindi aggiunto il codice Kotlin di seguito che ha deriso correttamente la posizione.
locationProvider = FusedLocationProviderClient(context)
locationProvider.setMockMode(true)
val loc = Location(providerName)
val mockLocation = Location(providerName) // a string
mockLocation.latitude = latitude // double
mockLocation.longitude = longitude
mockLocation.altitude = loc.altitude
mockLocation.time = System.currentTimeMillis()
mockLocation.accuracy = 1f
mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mockLocation.bearingAccuracyDegrees = 0.1f
mockLocation.verticalAccuracyMeters = 0.1f
mockLocation.speedAccuracyMetersPerSecond = 0.01f
}
// locationManager.setTestProviderLocation(providerName, mockLocation)
locationProvider.setMockLocation(mockLocation)