¿Cómo puedo burlarme de mi ubicación en un dispositivo físico (Nexus One)? Sé que puedes hacer esto con el emulador en el panel de control del emulador, pero esto no funciona para un dispositivo físico.
¿Cómo puedo burlarme de mi ubicación en un dispositivo físico (Nexus One)? Sé que puedes hacer esto con el emulador en el panel de control del emulador, pero esto no funciona para un dispositivo físico.
Respuestas:
Parece que la única forma de hacerlo es utilizar un proveedor de ubicación simulada.
Debe habilitar ubicaciones simuladas en el panel de desarrollo en su configuración y agregar
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
a tu manifiesto.
Ahora puede ingresar su código y crear su propio proveedor de ubicación simulada y establecer la ubicación de este proveedor.
Si usa este teléfono solo en el laboratorio de desarrollo, existe la posibilidad de que pueda soldar el chip GPS y alimentar el puerto serie directamente con secuencias NMEA desde otro dispositivo.
Desearía tener mi cable a mano. Sé que puedes hacer telnet al emulador para cambiar su ubicación
$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK
No recuerdo si puedes hacer telnet a tu dispositivo, pero creo que puedes. Espero que esto ayude.
Necesitará adb (puente de depuración de Android) para esto (CLI).
Puede usar el permiso de Servicios de ubicación para burlarse de la ubicación ...
"android.permission.ACCESS_MOCK_LOCATION"
y luego en tu código 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);
He tenido éxito con el siguiente código. Aunque por alguna razón me consiguió un solo bloqueo (incluso si probé diferentes pares LatLng), funcionó para mí. mLocationManager
es un LocationManager
que está conectado 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
se usa aquí para notificar / publicar / programar un evento con el LocationManager que el proveedor de GPS ha encontrado una solución "ahora" para que el procesamiento de dicho evento pueda ocurrir.
mLocationManager
es un LocationManager
que está conectado a un LocationListener"? ¿Cómo puedo hacer esto? Gracias ..
LocationManager
servicio y un LocationListener
: blog.doityourselfandroid.com/2010/12/25/…
Lo que Dr1Ku publicó funciona. Usó el código hoy pero necesitaba agregar más locs. Aquí hay algunas mejoras:
Opcional: en lugar de usar la cadena LocationManager.GPS_PROVIDER, es posible que desee definir su propia constata PROVIDER_NAME y usarla. Cuando se registre para actualizaciones de ubicación, elija un proveedor mediante criterios en lugar de especificarlo directamente como una cadena.
Primero: en lugar de llamar a removeTestProvider, primero verifique si hay un proveedor que se eliminará (para evitar IllegalArgumentException):
if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}
Segundo: para publicar más de una ubicación, debe establecer la hora de la ubicación:
newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);
También parece haber una prueba de Google que utiliza MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java
Otro buen ejemplo de trabajo se puede encontrar en: http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/
Otro buen artículo es: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 También encontrará un código que realmente funciona para yo en el emulador
Mock Provider
GPS normal no funcionaría, no pude obtener una solución (estaba probando directamente en un dispositivo). Este puede no ser el caso, ya que muchas cosas han sucedido en Android desde entonces.
Hay aplicaciones disponibles en Android Market que le permiten especificar una "Ubicación GPS simulada" para su dispositivo.
Busqué en https://market.android.com y encontré una aplicación llamada "Mi ubicación falsa" que funciona para mí.
El proveedor de GPS falso mencionado por Paul anteriormente (en http://www.cowlumbus.nl/forum/MockGpsProvider.zip ) es otro ejemplo que incluye el código fuente, aunque no pude instalar el APK proporcionado (dice Falla) [INSTALL_FAILED_OLDER_SDK] y puede que solo necesite una recompilación)
Para usar ubicaciones simuladas de GPS, debe habilitarlo en la configuración de su dispositivo. Vaya a Configuración -> Aplicaciones -> Desarrollo y marque "Permitir ubicaciones simuladas"
Luego puede usar una aplicación como las descritas anteriormente para establecer las coordenadas GPS y los mapas de Google y otras aplicaciones usarán la ubicación GPS simulada que especifique.
Esto funcionó para mí (Android Studio):
Desactiva el rastreo de GPS y WiFi en el teléfono. En Android 5.1.1 y versiones inferiores, seleccione "habilitar ubicaciones simuladas" en Opciones de desarrollador.
Haga una copia de su manifiesto en el directorio src / debug. Agregue lo siguiente (fuera de la etiqueta "aplicación"):
usa-permiso android: name = "android.permission.ACCESS_MOCK_LOCATION"
Configure un Fragmento de mapa llamado "mapa". Incluya el siguiente código en 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);
}
};
Tenga en cuenta que es posible que tenga que aumentar temporalmente "minSdkVersion" en el archivo gradle de su módulo a 17 para usar el método "setElapsedRealtimeNanos".
Incluya el siguiente código dentro de la clase de actividad principal:
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}
Ejecute su aplicación con AS. En Android 6.0 y superior obtendrás una excepción de seguridad. Ahora ve a Opciones de desarrollador en Configuración y selecciona "Seleccionar aplicación de ubicación simulada". Seleccione su aplicación de la lista.
Ahora, cuando tocas el mapa, onLocationChanged () disparará con las coordenadas de tu toque.
Acabo de resolver esto, así que ahora no tengo que caminar por el vecindario con los teléfonos en la mano.
He creado un controlador simple que simula una posición en movimiento desde una posición inicial.
Comience en la devolución de llamada de conexión:
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 clase 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;
}
}
}
Espero que pueda ayudar ...
La solución mencionada por icyerasor y proporcionada por Pedro en http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/ funcionó muy bien para mí. Sin embargo, no ofrece soporte para iniciar, detener y reiniciar correctamente el proveedor de GPS simulado.
He cambiado un poco su código y reescribí la clase para que sea AsyncTask en lugar de Thread. Esto nos permite comunicarnos con el subproceso de interfaz de usuario, por lo que podemos reiniciar el proveedor en el punto donde estábamos cuando lo detuvimos. Esto es útil cuando cambia la orientación de la pantalla.
El código, junto con un proyecto de muestra para Eclipse, se puede encontrar en GitHub: https://github.com/paulhoux/Android-MockProviderGPS
Todo el crédito debe ir a Pedro por hacer la mayor parte del trabajo duro.
Añadir a su manifiesto
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation,ProtectedPermissions" />
Función de ubicación simulada
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);
}
También deberá habilitar ubicaciones simuladas en la configuración de desarrollador de sus dispositivos. Si eso no está disponible, configure la "aplicación de ubicación simulada" en su aplicación una vez que se haya implementado lo anterior.
La aplicación falsa de GPS de Google Play me sirvió. Solo asegúrese de leer todas las instrucciones en la descripción de la aplicación. Debe deshabilitar otros servicios de ubicación, así como iniciar su aplicación después de habilitar "GPS falso". Funcionó muy bien para lo que necesitaba.
Aquí está el enlace a la aplicación en GooglePlay: GPS falso
El tutorial de Google para hacer esto se puede encontrar aquí, proporciona ejemplos de código y explica el proceso.
http://developer.android.com/training/location/location-testing.html#SendMockLocations
Instale la aplicación GPS falsa https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en
Opciones de desarrollador -> Seleccionar aplicación de ubicación simulada (es decir, aplicación de ubicación falsa seleccionada).
Aplicación GPS falsa :
Doble pestaña en el mapa para agregar -> haga clic en el botón de reproducción -> Mostrar el brindis "Ubicación falsa detenida"
finalmente verifique con las aplicaciones de mapas de google.
Escribí una aplicación que ejecuta un servidor web (REST-Like) en su teléfono Android, para que pueda configurar la posición del GPS de forma remota . El sitio web proporciona un mapa en el que puede hacer clic para establecer una nueva posición, o usar las teclas "wasd" para moverse en cualquier dirección. La aplicación fue una solución rápida, por lo que casi no hay interfaz de usuario ni documentación, pero la implementación es sencilla y puedes buscar todo en las (solo cuatro) clases.
Repositorio del proyecto: https://github.com/juliusmh/RemoteGeoFix
Si su dispositivo está conectado a su computadora y está tratando de cambiar el envío de cables GPS a través del control del emulador, no funcionará.
Este es un control EMULATOR por una razón.
Simplemente configúrelo para actualizarlo en el cambio de 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);
}
};
Cuando se actualiza el GPS, vuelva a escribir el siguiente método para hacer lo que desea;
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();
}
}
}
No olvide poner estos en el manifiesto
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
Me pregunto si necesita la configuración elaborada de Mock Location. En mi caso, una vez que obtuve una ubicación fija, estaba llamando a una función para hacer algo con esa nueva ubicación. En un temporizador, crea una ubicación simulada. Y llame a la función con esa ubicación en su lugar. Sabiendo todo el tiempo que en poco tiempo el GPS generaría una ubicación actual real. Lo cual está bien. Si tiene el tiempo de actualización establecido suficientemente largo.
Tal vez no sea un enfoque de "programador", pero si desea ahorrar tiempo y obtener una solución de trabajo instantánea, pruebe una de las aplicaciones dedicadas a la ubicación simulada disponible en Google Play:
Utilice el simulador de ubicación interactivo muy conveniente y gratuito para teléfonos y tabletas Android (llamado CATLES). Se burla de la ubicación del GPS a nivel de todo el sistema (incluso dentro de las aplicaciones de Google Maps o Facebook) y funciona tanto en dispositivos físicos como virtuales:
Sitio web: http://ubicom.snet.tu-berlin.de/catles/index.html
Use este permiso en el archivo de manifiesto
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">
Android Studio recomendará que "la ubicación simulada solo se solicite en un archivo de manifiesto de prueba o de depuración específico (generalmente src / debug / AndroidManifest.xml)" simplemente deshabilite la inspección
Ahora asegúrese de haber marcado la opción " Permitir ubicaciones falsas " en la configuración de desarrollador de su teléfono
Usar LocationManager
locationManager.addTestProvider(mocLocationProvider, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);
Ahora configura la ubicación donde quieras
Location mockLocation = new Location(mocLocationProvider);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lng);
mockLocation.setAltitude(alt);
mockLocation.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation);
Las soluciones anteriores no me funcionaron porque estaba probando en un dispositivo Android con la última versión de Google Play Services que utiliza el cliente FusedLocationProviderClient . Después de configurar el permiso de ubicación simulada en el manifiesto de la aplicación y la aplicación como la aplicación de ubicación simulada especificada en la configuración del desarrollador (como se menciona en las respuestas anteriores), agregué el código de Kotlin a continuación que se burló con éxito de la ubicación.
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)