Jak mogę wyszydzać swoją lokalizację na urządzeniu fizycznym (Nexus One)? Wiem, że możesz to zrobić za pomocą emulatora w panelu sterowania emulatora, ale to nie działa na urządzeniu fizycznym.
Jak mogę wyszydzać swoją lokalizację na urządzeniu fizycznym (Nexus One)? Wiem, że możesz to zrobić za pomocą emulatora w panelu sterowania emulatora, ale to nie działa na urządzeniu fizycznym.
Odpowiedzi:
Wydaje się, że jedynym sposobem jest skorzystanie z pozorowanego dostawcy lokalizacji.
Musisz włączyć pozorowane lokalizacje w panelu deweloperskim w swoich ustawieniach i dodać
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
do manifestu.
Teraz możesz przejść do kodu i utworzyć własnego dostawcę pozorowanej lokalizacji i ustawić lokalizację tego dostawcy.
Jeśli używasz tego telefonu tylko w laboratorium programistycznym, istnieje szansa, że możesz odlutować chip GPS i zasilić port szeregowy bezpośrednio sekwencjami NMEA z innego urządzenia.
Żałuję, że nie mam pod ręką kabla. Wiem, że możesz telnetować się do emulatora, aby zmienić jego lokalizację
$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK
Nie pamiętam, czy możesz telnetować się na swoje urządzenie, ale myślę, że możesz. Mam nadzieję, że to pomoże.
Będziesz potrzebował adb (mostek do debugowania Androida) do tego (CLI).
Możesz użyć uprawnienia Usługi lokalizacji, aby udawać lokalizację ...
"android.permission.ACCESS_MOCK_LOCATION"
a następnie w kodzie 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);
Odniosłem sukces z następującym kodem. Chociaż z jakiegoś powodu dostałem pojedynczy zamek (nawet jeśli wypróbowałem różne pary LatLng), zadziałał dla mnie. mLocationManager
jest połączeniem LocationManager
z 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
służy tutaj do powiadamiania / wysyłania / planowania zdarzenia za pomocą LocationManagera, że dostawca GPS znalazł poprawkę „teraz”, aby przetwarzanie wspomnianego zdarzenia mogło nastąpić.
mLocationManager
jest to, LocationManager
które jest podłączone do LocationListener”? w jaki sposób mogę to zrobić? Dziękuję ..
LocationManager
usługi i LocationListener
: blog.doityourselfandroid.com/2010/12/25/...
To, co opublikował Dr1Ku, działa. Użyłem kodu dzisiaj, ale musiałem dodać więcej lokalizacji. Oto kilka ulepszeń:
Opcjonalnie: zamiast używać ciągu LocationManager.GPS_PROVIDER, możesz zdefiniować własną stałą PROVIDER_NAME i używać jej. Podczas rejestrowania się w celu uzyskania aktualizacji lokalizacji wybierz dostawcę za pomocą kryteriów zamiast bezpośrednio określać go jako ciąg.
Po pierwsze: zamiast wywoływać removeTestProvider, najpierw sprawdź, czy istnieje dostawca do usunięcia (aby uniknąć IllegalArgumentException):
if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}
Po drugie: aby opublikować więcej niż jedną lokalizację, musisz ustawić czas dla lokalizacji:
newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);
Wydaje się również, że istnieje test Google, który korzysta z MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java
Inny dobry działający przykład można znaleźć pod adresem : http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/
Kolejny dobry artykuł to: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 Znajdziesz także kod, który faktycznie działa ja na emulatorze.
Mock Provider
normalny GPS nie działał, nie mogłem znaleźć poprawki (testowałem bezpośrednio na urządzeniu). Może tak nie być, ponieważ od tego czasu wiele wydarzyło się w Androidzie.
W Android Market dostępne są aplikacje, które umożliwiają określenie „pozorowanej lokalizacji GPS” dla urządzenia.
Przeszukałem https://market.android.com i znalazłem aplikację o nazwie „Moja fałszywa lokalizacja”, która działa dla mnie.
Mock GPS Provider wspomniany powyżej przez Paula (pod adresem http://www.cowlumbus.nl/forum/MockGpsProvider.zip ) to kolejny przykład zawierający kod źródłowy - chociaż nie byłem w stanie zainstalować dostarczonego APK (mówi [INSTALL_FAILED_OLDER_SDK] i może wymagać ponownej kompilacji)
Aby korzystać z pozorowanych lokalizacji GPS, musisz włączyć je w ustawieniach urządzenia. Przejdź do Ustawienia -> Aplikacje -> Programowanie i zaznacz „Zezwalaj na pozorowane lokalizacje”
Następnie możesz użyć aplikacji takiej jak te opisane powyżej, aby ustawić współrzędne GPS, a mapy Google i inne aplikacje będą używać określonej przez Ciebie pozorowanej lokalizacji GPS.
To zadziałało dla mnie (Android Studio):
Wyłącz śledzenie GPS i WiFi w telefonie. W Androidzie 5.1.1 i starszych wybierz „Włącz pozorowane lokalizacje” w Opcjach programisty.
Utwórz kopię swojego manifestu w katalogu src / debug. Dodaj do niego następujące elementy (poza tagiem „aplikacja”):
używa uprawnień android: name = "android.permission.ACCESS_MOCK_LOCATION"
Skonfiguruj fragment mapy o nazwie „mapa”. Uwzględnij następujący kod w 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);
}
};
Zauważ, że może być konieczne tymczasowe zwiększenie „minSdkVersion” w pliku gradle modułu do 17, aby użyć metody „setElapsedRealtimeNanos”.
Uwzględnij następujący kod w głównej klasie aktywności:
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}
Uruchom swoją aplikację z AS. W systemie Android 6.0 i nowszych otrzymasz wyjątek bezpieczeństwa. Teraz przejdź do opcji programisty w Ustawieniach i wybierz „Wybierz pozorowaną aplikację lokalizacyjną”. Wybierz swoją aplikację z listy.
Teraz, kiedy dotkniesz mapy, onLocationChanged () uruchomi się ze współrzędnymi twojego kranu.
Właśnie to rozgryzłem, więc teraz nie muszę włóczyć się po okolicy z telefonami w dłoni.
Stworzyłem prostego Handler'a symulującego ruchome położenie z pozycji początkowej.
Uruchom go w wywołaniu zwrotnym połączenia:
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) {
}
};
Klasa 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;
}
}
}
Mam nadzieję, że to pomoże ...
Rozwiązanie wspomniane przez icyerasor i dostarczone przez Pedro na http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/ działało bardzo dobrze. Jednak nie oferuje wsparcia dla prawidłowego uruchamiania, zatrzymywania i ponownego uruchamiania pozorowanego dostawcy GPS.
Zmieniłem nieco jego kod i przepisałem klasę na AsyncTask zamiast Thread. To pozwala nam komunikować się z wątkiem interfejsu użytkownika, dzięki czemu możemy ponownie uruchomić dostawcę w punkcie, w którym byliśmy, gdy go zatrzymaliśmy. Jest to przydatne, gdy zmienia się orientacja ekranu.
Kod wraz z przykładowym projektem dla Eclipse można znaleźć na GitHub: https://github.com/paulhoux/Android-MockProviderGPS
Wszelkie uznanie należy się Pedro za wykonanie większości ciężkiej pracy.
Dodaj do swojego manifestu
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation,ProtectedPermissions" />
Funkcja pozorowania lokalizacji
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);
}
Musisz także włączyć pozorowane lokalizacje w ustawieniach programisty urządzeń. Jeśli to nie jest dostępne, ustaw „pozorowaną aplikację lokalizacji” na swoją aplikację po wdrożeniu powyższego.
Fałszywa aplikacja GPS z Google Play załatwiła mi sprawę. Po prostu przeczytaj wszystkie wskazówki w opisie aplikacji. Musisz wyłączyć inne usługi lokalizacyjne, a także uruchomić aplikację po włączeniu „Fałszywy GPS”. Działał świetnie na to, czego potrzebowałem.
Oto link do aplikacji w Google Play: Fałszywy GPS
Samouczek Google, jak to zrobić, można znaleźć tutaj, zawiera przykłady kodu i wyjaśnia proces.
http://developer.android.com/training/location/location-testing.html#SendMockLocations
Zainstaluj aplikację Fake GPS https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en
Opcje programisty -> Wybierz pozorowaną aplikację lokalizacyjną (to znaczy, wybrana aplikacja Fałszywa lokalizacja).
Fałszywa aplikacja GPS :
Podwójna zakładka na mapie, aby dodać -> kliknij przycisk odtwarzania -> Pokaż toast „Fałszywa lokalizacja zatrzymana”
wreszcie sprawdź w aplikacjach map Google.
Napisałem aplikację, która uruchamia serwer sieciowy (podobny do REST) na telefonie z Androidem, dzięki czemu możesz zdalnie ustawić pozycję GPS . Witryna udostępnia mapę, na której można kliknąć, aby ustawić nową pozycję lub użyć klawiszy „wasd”, aby poruszać się w dowolnym kierunku. Aplikacja była szybkim rozwiązaniem, więc prawie nie ma interfejsu użytkownika ani dokumentacji, ale implementacja jest prosta i możesz sprawdzić wszystko w (tylko czterech) klasach.
Repozytorium projektów: https://github.com/juliusmh/RemoteGeoFix
Jeśli urządzenie jest podłączone do komputera i próbujesz zmienić wysyłanie przewodów GPS za pomocą kontrolki emulatora, nie zadziała.
To jest kontrola EMULATORA nie bez powodu.
Po prostu skonfiguruj go, aby informować Cię o zmianie 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);
}
};
Po zaktualizowaniu GPS przepisz następującą metodę, aby zrobić to, co chcesz;
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();
}
}
}
Nie zapomnij umieścić ich w manifeście
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
Zastanawiam się, czy potrzebujesz skomplikowanej konfiguracji pozorowanej lokalizacji. W moim przypadku, gdy uzyskałem ustaloną lokalizację, wywoływałem funkcję, aby zrobić coś z tą nową lokalizacją. W zegarze utwórz pozorowaną lokalizację. Zamiast tego wywołaj funkcję z tą lokalizacją. Wiedząc przez cały czas, że za chwilę GPS wskaże prawdziwą aktualną lokalizację. Co jest w porządku. Jeśli masz ustawiony wystarczająco długi czas aktualizacji.
Może nie jest to podejście `` programisty '', ale jeśli chcesz zaoszczędzić czas i uzyskać działające rozwiązanie, wypróbuj jedną z aplikacji, które są dedykowane do pozorowanej lokalizacji dostępnej w Google Play:
Skorzystaj z bardzo wygodnego i bezpłatnego interaktywnego symulatora lokalizacji dla telefonów i tabletów z systemem Android (o nazwie CATLES). Kpi z lokalizacji GPS na poziomie całego systemu (nawet w Google Maps lub aplikacji Facebook) i działa zarówno na urządzeniach fizycznych, jak i wirtualnych:
Strona internetowa: http://ubicom.snet.tu-berlin.de/catles/index.html
Użyj tego uprawnienia w pliku manifestu
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">
Android Studio zaleci, aby „Żądanie pozorowanej lokalizacji było wymagane tylko w pliku manifestu specyficznym dla testu lub debugowania (zazwyczaj src / debug / AndroidManifest.xml)” po prostu wyłącz kontrolę
Teraz upewnij się, że zaznaczyłeś „ Zezwalaj na pozorowanie lokalizacji ” w ustawieniach programisty na telefonie
Użyj LocationManager
locationManager.addTestProvider(mocLocationProvider, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);
Teraz ustaw lokalizację, gdzie chcesz
Location mockLocation = new Location(mocLocationProvider);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lng);
mockLocation.setAltitude(alt);
mockLocation.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation);
Powyższe rozwiązania nie zadziałały, ponieważ testowałem na urządzeniu z Androidem z najnowszą wersją Usług Google Play, która wykorzystuje FusedLocationProviderClient . Po ustawieniu uprawnień do pozorowanej lokalizacji w manifeście aplikacji i aplikacji jako określonej aplikacji pozorowanej lokalizacji w ustawieniach programisty (jak wspomniano w poprzednich odpowiedziach), dodałem kod Kotlin poniżej, który pomyślnie wyszydził lokalizację.
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)