Comment puis-je moquer ma position sur un appareil physique (Nexus One)? Je sais que vous pouvez le faire avec l'émulateur dans le panneau de contrôle de l'émulateur, mais cela ne fonctionne pas pour un périphérique physique.
Comment puis-je moquer ma position sur un appareil physique (Nexus One)? Je sais que vous pouvez le faire avec l'émulateur dans le panneau de contrôle de l'émulateur, mais cela ne fonctionne pas pour un périphérique physique.
Réponses:
Il semble que le seul moyen de le faire soit d'utiliser un fournisseur de localisation fictif.
Vous devez activer les emplacements fictifs dans le panneau de développement dans vos paramètres et ajouter
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
à votre manifeste.
Vous pouvez maintenant entrer votre code et créer votre propre fournisseur d'emplacement fictif et définir l'emplacement de ce fournisseur.
Si vous utilisez ce téléphone uniquement dans un laboratoire de développement, il est possible que vous puissiez souder la puce GPS et alimenter le port série directement avec les séquences NMEA d'un autre appareil.
J'aimerais avoir mon câble à portée de main. Je sais que vous pouvez envoyer un telnet à l'émulateur pour changer son emplacement
$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK
Je ne me souviens pas si vous pouvez telnet sur votre appareil, mais je pense que vous le pouvez. J'espère que ça aide.
Vous aurez besoin d'adb (pont de débogage Android) pour cela (CLI).
Vous pouvez utiliser l'autorisation des services de localisation pour simuler l'emplacement ...
"android.permission.ACCESS_MOCK_LOCATION"
puis dans votre code 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);
J'ai eu du succès avec le code suivant. Même si cela m'a donné une seule serrure pour une raison quelconque (même si j'ai essayé différentes paires LatLng), cela a fonctionné pour moi. mLocationManager
est un LocationManager
qui est relié à 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
est utilisé ici pour notifier / publier / programmer un événement avec le LocationManager que le fournisseur de GPS a trouvé un correctif "maintenant" afin que le traitement dudit événement puisse avoir lieu.
mLocationManager
est un LocationManager
qui est connecté à un LocationListener"? Comment puis-je faire ceci? Merci ..
LocationManager
service et un LocationListener
: blog.doityourselfandroid.com/2010/12/25/…
Ce que Dr1Ku a publié fonctionne. Utilisé le code aujourd'hui mais avait besoin d'ajouter plus de locs. Voici donc quelques améliorations:
Facultatif: au lieu d'utiliser la chaîne LocationManager.GPS_PROVIDER, vous souhaiterez peut-être définir votre propre constat PROVIDER_NAME et l'utiliser. Lors de l'inscription aux mises à jour de localisation, choisissez un fournisseur via des critères au lieu de le spécifier directement sous forme de chaîne.
Premièrement: au lieu d'appeler removeTestProvider, vérifiez d'abord s'il existe un fournisseur à supprimer (pour éviter IllegalArgumentException):
if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}
Deuxièmement: pour publier plusieurs emplacements, vous devez définir l'heure de l'emplacement:
newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);
Il semble également y avoir un test google qui utilise MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java
Un autre bon exemple de travail peut être trouvé à l' adresse : http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/
Un autre bon article est: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 Vous trouverez également du code qui fonctionne réellement pour moi sur l'émulateur.
Mock Provider
GPS, le GPS normal ne fonctionnait pas, je ne pouvais pas obtenir de solution (je testais directement sur un appareil). Ce n'est peut-être pas le cas car beaucoup de choses se sont passées sur Android depuis.
Il existe des applications disponibles sur l'Android Market qui vous permettent de spécifier une «fausse position GPS» pour votre appareil.
J'ai cherché sur https://market.android.com et j'ai trouvé une application appelée "My Fake Location" qui fonctionne pour moi.
Le fournisseur de GPS simulé mentionné par Paul ci-dessus (à http://www.cowlumbus.nl/forum/MockGpsProvider.zip ) est un autre exemple qui inclut le code source - bien que je n'ai pas pu installer l'APK fourni (il indique Failure [INSTALL_FAILED_OLDER_SDK] et peut-être juste besoin d'une recompilation)
Pour utiliser les emplacements GPS simulés, vous devez l'activer dans les paramètres de votre appareil. Allez dans Paramètres -> Applications -> Développement et cochez "Autoriser les emplacements fictifs"
Vous pouvez ensuite utiliser une application comme celles décrites ci-dessus pour définir les coordonnées GPS et Google Maps et d'autres applications utiliseront la fausse position GPS que vous spécifiez.
Cela a fonctionné pour moi (Android Studio):
Désactivez le suivi GPS et WiFi sur le téléphone. Sur Android 5.1.1 et versions antérieures, sélectionnez "Activer les emplacements fictifs" dans les options pour les développeurs.
Faites une copie de votre manifeste dans le répertoire src / debug. Ajoutez-y les éléments suivants (en dehors de la balise "application"):
uses-permission android: name = "android.permission.ACCESS_MOCK_LOCATION"
Configurez un fragment de carte appelé «carte». Incluez le code suivant dans 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);
}
};
Notez que vous devrez peut-être augmenter temporairement "minSdkVersion" dans le fichier gradle de votre module à 17 pour utiliser la méthode "setElapsedRealtimeNanos".
Incluez le code suivant dans la classe d'activité principale:
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}
Exécutez votre application avec AS. Sur Android 6.0 et supérieur, vous obtiendrez une exception de sécurité. Accédez maintenant aux options pour les développeurs dans les paramètres et sélectionnez "Sélectionner une application de localisation fictive". Sélectionnez votre application dans la liste.
Maintenant, lorsque vous appuyez sur la carte, onLocationChanged () se déclenchera avec les coordonnées de votre robinet.
Je viens juste de comprendre cela, alors maintenant je n'ai plus à me promener dans le quartier avec des téléphones à la main.
J'ai créé un gestionnaire simple simulant une position en mouvement à partir d'une position initiale.
Démarrez-le dans votre rappel de connexion:
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;
}
}
}
J'espère que cela peut vous aider.
La solution mentionnée par icyerasor et fournie par Pedro à http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/ a très bien fonctionné pour moi. Cependant, il n'offre pas de support pour démarrer, arrêter et redémarrer correctement le fournisseur de GPS simulé.
J'ai un peu changé son code et réécrit la classe pour qu'elle devienne une AsyncTask au lieu d'un Thread. Cela nous permet de communiquer avec le thread d'interface utilisateur, afin que nous puissions redémarrer le fournisseur au point où nous en étions lorsque nous l'avons arrêté. Ceci est pratique lorsque l'orientation de l'écran change.
Le code, ainsi qu'un exemple de projet pour Eclipse, peuvent être trouvés sur GitHub: https://github.com/paulhoux/Android-MockProviderGPS
Tout le mérite revient à Pedro pour la plupart du travail acharné.
Ajouter à votre manifeste
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation,ProtectedPermissions" />
Fonction de localisation simulée
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);
}
Vous devrez également activer les emplacements fictifs dans les paramètres de développement de vos appareils. Si ce n'est pas disponible, définissez «l'application de localisation fictive» sur votre application une fois que ce qui précède a été implémenté.
Une fausse application GPS de Google Play a fait l'affaire pour moi. Assurez-vous simplement de lire toutes les instructions dans la description de l'application. Vous devez désactiver les autres services de localisation et démarrer votre application après avoir activé "Faux GPS". A bien fonctionné pour ce dont j'avais besoin.
Voici le lien vers l'application sur GooglePlay: Faux GPS
Le tutoriel Google pour ce faire peut être trouvé ici, il fournit des exemples de code et explique le processus.
http://developer.android.com/training/location/location-testing.html#SendMockLocations
Installez Fake GPS app https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en
Options pour les développeurs -> Sélectionnez l'application de localisation fictive (c'est moyen, application de localisation fausse sélectionnée).
Fausse application GPS :
Double onglet sur la carte à ajouter -> cliquez sur le bouton de lecture -> Afficher le toast "Faux emplacement arrêté"
vérifiez enfin avec les applications google map.
J'ai écrit une application qui exécute un serveur Web (REST-Like) sur votre téléphone Android, afin que vous puissiez définir la position GPS à distance . Le site Web fournit une carte sur laquelle vous pouvez cliquer pour définir une nouvelle position, ou utiliser les touches «wasd» pour vous déplacer dans n'importe quelle direction. L'application était une solution rapide, il n'y a donc presque pas d'interface utilisateur ni de documentation, mais l'implémentation est simple et vous pouvez tout rechercher dans les (seulement quatre) classes.
Référentiel de projet: https://github.com/juliusmh/RemoteGeoFix
Si votre appareil est branché sur votre ordinateur et que vous essayez de modifier l'envoi de cordons GPS via le contrôle Emulator, cela ne fonctionnera pas.
Il s'agit d'un contrôle EMULATOR pour une raison.
Il suffit de le configurer pour vous mettre à jour sur le changement 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);
}
};
Lorsque le GPS est mis à jour, réécrivez la méthode suivante pour faire ce que vous voulez;
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();
}
}
}
N'oubliez pas de les mettre dans le manifeste
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
Je me demande si vous avez besoin de la configuration élaborée de Mock Location. Dans mon cas, une fois que j'ai obtenu un emplacement fixe, j'appelais une fonction pour faire quelque chose avec ce nouvel emplacement. Dans une minuterie, créez un emplacement simulé. Et appelez la fonction avec cet emplacement à la place. Sachant depuis le début que dans peu de temps, le GPS trouverait une position actuelle réelle. Ce qui est OK. Si le temps de mise à jour est suffisamment long.
Ce n'est peut-être pas une approche de `` programmeur '', mais si vous voulez gagner du temps et obtenir une solution de travail instantanée, essayez l'une des applications dédiées à l'emplacement simulé disponible dans Google Play:
Utilisez le simulateur de localisation interactif très pratique et gratuit pour les téléphones et tablettes Android (nommé CATLES). Il se moque de la localisation GPS à l'échelle du système (même dans les applications Google Maps ou Facebook) et fonctionne sur les appareils physiques et virtuels:
Utilisez cette autorisation dans le fichier manifeste
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">
android studio recommandera que «l'emplacement fictif ne soit demandé que dans un fichier manifeste spécifique au test ou au débogage (généralement src / debug / AndroidManifest.xml)», désactivez simplement l'inspection
Assurez-vous maintenant d'avoir coché l' option " Autoriser les emplacements fictifs " dans les paramètres du développeur de votre téléphone
Utiliser LocationManager
locationManager.addTestProvider(mocLocationProvider, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);
Maintenant, définissez l'emplacement où vous voulez
Location mockLocation = new Location(mocLocationProvider);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lng);
mockLocation.setAltitude(alt);
mockLocation.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation);
Les solutions ci-dessus n'ont pas fonctionné pour moi car je testais sur un appareil Android avec la dernière version des services Google Play qui utilise le FusedLocationProviderClient . Après avoir défini l'autorisation de localisation fictive dans le manifeste de l'application et l'application en tant qu'application de localisation fictive spécifiée dans les paramètres du développeur (comme mentionné dans les réponses précédentes), j'ai ensuite ajouté le code Kotlin ci-dessous qui a réussi à se moquer de l'emplacement.
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)