Расположение макета Android на устройстве?


147

Как я могу смоделировать свое местоположение на физическом устройстве (Nexus One)? Я знаю, что вы можете сделать это с эмулятором на панели управления эмулятором, но это не работает для физического устройства.


Для настольных компьютеров вы можете создавать / устанавливать драйверы, которые имитируют устройство GPS / устройство с последовательным портом с целью проведения такого рода тестирования. Возможно, вы могли бы создать или найти что-то подобное для Android.
AaronLS

6
В Маркете есть несколько приложений, которые могут эмулировать местоположение GPS. Например "Расположение спуфер".
Влад

В магазине есть множество приложений, которые делают это .. Вы можете попробовать это - play.google.com/store/apps/… или это - play.google.com/store/apps/…
Yehuda

1
В магазине также есть приложение, которое поддерживает команды "geo fix" и "geo nmea", как эмулятор! play.google.com/store/apps/...
Luv

@Iuv более того, это с открытым исходным кодом github.com/luv/mockgeofix
Влад

Ответы:


166

Похоже, единственный способ сделать это - использовать провайдера фиктивного местоположения.

Вы должны включить макеты мест на панели разработки в настройках и добавить

   <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> 

к вашему манифесту.

Теперь вы можете зайти в свой код и создать своего собственного провайдера для определения местоположения и указать местоположение этого провайдера.


83
На рынке есть приложение под названием «Fake GPS». Если вы включите Mock Locations на вашем устройстве, он предлагает хороший графический интерфейс для установки вашего местоположения. Я понимаю, что это не самостоятельное решение, а, безусловно, достойное решение для быстрого тестирования.
Тим Грин

2
это может быть ссылка - та же дата и соответствующий контент.
DefenestrationDay

4
@TimGreen Ваш ответ должен быть принят (а не только комментарий)! Безусловно самый простой способ проверить
Бостоне

На самом деле, приложение «поддельный GPS» не является лучшим, потому что оно может только устанавливать местоположения и случайным образом перемещаться. Их новая версия может проложить маршрут, но она перебирает только путевые точки, поэтому огромные скачки в локации. Ответ Януша действительно верен, что вам нужно создать своего собственного провайдера. Мы недавно сделали это, и если кому-то это понадобится или если этот вопрос все еще нуждается в помощи, я выложу код.
vkinra

5
Утверждение «зайди в свой код и создай свой собственный провайдер фиктивного местоположения» должно быть объяснено более подробно.
Dims

102

Если вы используете этот телефон только в лаборатории разработки, есть вероятность, что вы сможете припаять чип GPS и напрямую подключить последовательный порт с последовательностями NMEA от другого устройства.


68
Почему ненавистники? Этот ответ является очень сложным.
Бен Зотто

61
Потрясающе хардкорный, хотя и совершенно бесполезный / не относящийся к делу.
olivervbk

13
Достаточно весело, хотя.
Этьен

23
хм, я думаю, что любой, для кого этот ответ был бы уместен, уже знает, что может это сделать. Я сомневаюсь, что эти три человека ищут решение в стеке потока.
ToolmakerSteve

10
Если у вас возникли проблемы с выяснением того, как генерировать реалистичные последовательности NMEA в ваше распаянное устройство, есть замечательный вариант: припаять туда реальное внешнее устройство GPS и переместить всю лабораторию разработки на реальный трек, на вершину команды бегунов / байкеров / автомобили / самолеты / что угодно в зависимости от скорости, которую вы хотите имитировать. Не забудьте открыть отверстие в крыше лаборатории разработки, чтобы устройство могло принимать радиосигналы со спутников. Пожалуйста. ;-)
Стефан Гурихон

32

Я хотел бы иметь свой кабель под рукой. Я знаю, что вы можете telnet к эмулятору, чтобы изменить его местоположение

$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK

Я не могу вспомнить, если вы можете telnet к вашему устройству, но я думаю, что вы можете. Надеюсь, это поможет.

Для этого вам понадобится adb (мост отладки Android) (CLI).


вы получаете отказ в доступе ко всему, что отправляете в виде команды на консоль вашего устройства. Может быть, это возможно с терминальным приложением, но я думаю, что требуется root-доступ
Janusz

Просто мы на одной странице: вы не говорите о "оболочке adb"? То, о чем я говорю, отличается, это что-то, что позволяет вам устанавливать специфичные для Android параметры. Я знаю, например, что вы можете настроить переадресацию портов (т. Е. Localhost: 1234 идет на телефон: 1234) без корневого доступа, поэтому вы можете настроить прокси-сервер SOCKS и туннель через кабель без root.
Тим Грин

Вы можете использовать adb forward tcp: 6000 tcp: 23 для перенаправления порта 6000 на вашей машине на порт 23 на устройстве, но я не смог подключиться, даже если порт отображается как открытый. Использование telnet-клиента на устройстве и подключение к localhost также не удается
Janusz

15
Это хорошо работает для эмулятора, но не работает для реального устройства. Так что это не отвечает на вопрос ОП вообще :(
Мэтью Гиллиард

4
@TimGreen Ваше решение только для эмулятора. Вопрос был о реальном устройстве.
Игорь Ганапольский

29

Вы можете использовать разрешение Службы определения местоположения, чтобы смоделировать местоположение ...

"android.permission.ACCESS_MOCK_LOCATION"

а затем в вашем коде 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);

9
что в значении mocLocationProvider?
Виктор

например, LocationManager.GPS_PROVIDER
enigma969

25

Я имел успех со следующим кодом. Хотя по какой-то причине у меня была одна блокировка (даже если я пробовал разные пары LatLng), это сработало для меня. mLocationManagerэто LocationManagerкоторый подключен к 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
    );      
}

1
Хороший пост, см. Мой ответ ниже для дополнений.
icyerasor

Насколько я помню, setTestProviderStatusздесь используется для уведомления / публикации / планирования события с LocationManager о том, что провайдер GPS обнаружил исправление «сейчас», чтобы могла произойти обработка указанного события.
Dr1Ku

Что значит « mLocationManagerэто , LocationManagerкоторый подключен к LocationListener»? как я могу это сделать? Спасибо ..
Иегуда

Вот одна статья, объясняющая, как проверить изменение местоположения с помощью LocationManagerсервиса и LocationListener: blog.doityourselfandroid.com/2010/12/25/…
Dr1Ku

2
плюс 1 за то, как вы представляли true (s) и false (s) в методе addTestProvider
A.Alqadomi

16

На что Dr1Ku выложил работы. Использовал код сегодня, но нужно было добавить больше locs. Итак, вот некоторые улучшения:

Необязательно: Вместо использования строки LocationManager.GPS_PROVIDER может потребоваться определить собственное constat PROVIDER_NAME и использовать его. При регистрации для получения обновлений местоположения выберите поставщика с помощью критериев, а не указывайте его в виде строки.

Во-первых: вместо вызова removeTestProvider, сначала проверьте, есть ли провайдер, которого нужно удалить (чтобы избежать IllegalArgumentException):

if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
  mLocationManager.removeTestProvider(PROVIDER_NAME);
}

Второе: чтобы опубликовать более одного местоположения, вы должны установить время для местоположения:

newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);

Также, похоже, есть тест Google, который использует MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java

Еще один хороший рабочий пример можно найти по адресу: http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/

Еще одна хорошая статья: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 Вы также найдете некоторый код, который действительно работает для меня на эмуляторе.


Классное предложение по определению вашего собственного провайдера. С помощью GPS_PROVIDER вы, по-видимому, не можете избавиться от фиктивного провайдера (точнее, вы не можете переключиться на обычный GPS) до перезагрузки. Отличный пост, я проверю ссылки!
Dr1Ku

@ Dr1KU Неужели вы не можете вернуться к обычному GPS? Это указано где-то?
Каз Дракон

@KazDragon Так было тогда. Из того, что я могу вспомнить, после включения Mock Providerнормальный GPS не работал, я не мог получить исправление (я тестировал непосредственно на устройстве). Это может быть не так, поскольку с тех пор в Android много чего произошло.
Dr1Ku

@ Dr1Ku А, ну, сейчас я делаю нечто очень похожее и получаю результаты, аналогичные тем, которые вы описали. Я надеялся узнать, было ли это ограничение, встроенное в платформу, или я просто где-то пропускал вызов функции. Я, наверное, должен сделать из этого вопрос.
Kaz Dragon

9

В Android Market есть приложения, которые позволяют вам указать «Местоположение GPS-макета» для вашего устройства.

Я искал https://market.android.com и нашел приложение под названием «Мое поддельное местоположение», которое работает для меня.

Поставщик Mock GPS, упомянутый Полом выше (по адресу http://www.cowlumbus.nl/forum/MockGpsProvider.zip ), является еще одним примером, включающим исходный код - хотя я не смог установить прилагаемый APK (он говорит Failure [INSTALL_FAILED_OLDER_SDK] и может понадобиться перекомпиляция)

Для того, чтобы использовать макеты местоположений GPS, вы должны включить его в настройках вашего устройства. Зайдите в Настройки -> Приложения -> Разработка и проверьте «Разрешить фиктивные местоположения»

Затем вы можете использовать приложение, подобное описанному выше, для установки координат GPS, а карты Google и другие приложения будут использовать фиктивное местоположение GPS, которое вы укажете.


Поддельный GPS проще. Мне просто интересно, почему они спрашивают идентификатор вызывающего абонента в разрешении приложения: S
Гийом Масс

8

Это сработало для меня (Android Studio):

Отключить GPS и WiFi отслеживание на телефоне. На Android 5.1.1 и ниже выберите «Включить макет местоположения» в разделе «Параметры разработчика».

Сделайте копию своего манифеста в каталоге src / debug. Добавьте к нему следующее (за пределами тега «application»):

использует-разрешение android: name = "android.permission.ACCESS_MOCK_LOCATION"

Настройте фрагмент карты под названием «карта». Включите следующий код в 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);
    }
};

Обратите внимание, что вам, возможно, придется временно увеличить minSdkVersion в файле Gradle вашего модуля до 17, чтобы использовать метод setElapsedRealtimeNanos.

Включите следующий код в основной класс деятельности:

private class MyLocationListener implements LocationListener {
    @Override
    public void onLocationChanged(Location location) {
        // do whatever you want, scroll the map, etc.
    }
}

Запустите ваше приложение с AS. На Android 6.0 и выше вы получите исключение безопасности. Теперь перейдите в «Параметры разработчика» в «Настройках» и выберите «Выбор приложения для определения местоположения». Выберите ваше приложение из списка.

Теперь, когда вы нажимаете на карту, onLocationChanged () будет срабатывать с координатами вашего касания.

Я только что понял это, так что теперь мне не нужно бродить по окрестностям с телефонами в руках.


я думаю, что это работает на Android 6, если вы
Хамза

7

Я создал простой обработчик, имитирующий перемещение позиции из начальной позиции.

Запустите его в обратном вызове вашего соединения:

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) {

    }
};

Класс 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;
        }
    }
}

Надеюсь, что это может помочь ..


6

Решение, упомянутое icyerasor и предоставленное Педро по адресу http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/, сработало для меня очень хорошо. Тем не менее, он не предлагает поддержку для правильного запуска, остановки и перезапуска провайдера фиктивного GPS.

Я немного изменил его код и переписал класс, чтобы он стал AsyncTask вместо Thread. Это позволяет нам взаимодействовать с потоком пользовательского интерфейса, поэтому мы можем перезапустить провайдера с того места, где мы были, когда мы его остановили. Это удобно, когда меняется ориентация экрана.

Код вместе с примером проекта для Eclipse можно найти на GitHub: https://github.com/paulhoux/Android-MockProviderGPS.

Вся заслуга должна пойти на Педро за большую часть тяжелой работы.


6

Добавить в свой манифест

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    tools:ignore="MockLocation,ProtectedPermissions" />

Функция фиктивного местоположения

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);
}

Вам также необходимо включить макет местоположения в настройках разработчика вашего устройства. Если это недоступно, установите «приложение для определения местоположения» в своем приложении, как только будет реализовано вышеизложенное.


3

Поддельное приложение GPS от Google Play помогло мне. Просто убедитесь, что вы прочитали все указания в описании приложения. Вы должны отключить другие службы определения местоположения, а также запустить свое приложение после включения «Fake GPS». Отлично работал для того, что мне нужно.

Вот ссылка на приложение в GooglePlay: Поддельный GPS



2

Установите приложение Fake GPS https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en.

Параметры разработчика -> Выбрать приложение для определения местоположения (это означает, что выбрано приложение с поддельным местоположением).

Поддельное приложение GPS :

Двойную вкладку на карте, чтобы добавить -> нажмите кнопку воспроизведения -> Показать тост "Поддельное местоположение остановлено"

наконец, проверьте с помощью приложений Google Map.


2

Я написал приложение, которое запускает WebServer (REST-Like) на вашем телефоне Android, чтобы вы могли удаленно устанавливать GPS-положение . Веб-сайт предоставляет карту, на которой вы можете щелкнуть, чтобы установить новую позицию, или использовать клавиши «wasd» для перемещения в любом направлении. Приложение было быстрым решением, поэтому почти нет ни пользовательского интерфейса, ни документации, но реализация проста, и вы можете посмотреть все в (только четырех) классах.

Репозиторий проекта: https://github.com/juliusmh/RemoteGeoFix


1

Если ваше устройство подключено к вашему компьютеру и вы пытаетесь изменить отправку GPS-шнуров с помощью эмулятора, это не сработает.
Это ЭМУЛЯТОР управления по причине.
Просто установите его, чтобы сообщить вам об изменении 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);
        }
      };

Когда GPS обновится, перепишите следующий метод, чтобы сделать то, что вы хотите;

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();  
        }
    }
}

Не забудьте поместить их в манифест
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION


0

Интересно, нужна ли вам сложная настройка Mock Location. В моем случае, как только я получил фиксированное местоположение, я вызывал функцию, чтобы сделать что-то с этим новым местоположением. В таймере создайте макет локации. И вместо этого вызовите функцию с этим местоположением. Зная все это в скором времени, GPS определит реальное текущее местоположение. Что в порядке. Если у вас установлено достаточно большое время обновления.


0

Возможно, это не «программистский» подход, но если вы хотите сэкономить свое время и мгновенно получить рабочее решение, попробуйте одно из приложений, предназначенных для определения местоположения, доступных в Google Play:

Поддельный GPS Location Spoofer

Ложные Места

Поддельное местоположение GPS


1
Ты пробовал их? Работали ли они так, как было задано в вопросе?
ареколек

Любые предпочтения? Или все они нужны? : P
arekolek

Поддельный GPS Location Spoofer достаточно хорош, но Mock Locations позволяет установить маршрут, что является хорошей особенностью.
климат

0

Воспользуйтесь очень удобным и бесплатным интерактивным симулятором местоположения для телефонов и планшетов с ОС Android (названным CATLES). Он проверяет местоположение GPS на уровне всей системы (даже в приложениях Google Maps или Facebook) и работает как на физических, так и на виртуальных устройствах:

Веб-сайт: http://ubicom.snet.tu-berlin.de/catles/index.html

Видео: https://www.youtube.com/watch?v=0WSwH5gK7yg


0

Используйте это разрешение в файле манифеста

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">

android studio рекомендует, чтобы «Макетное местоположение запрашивалось только в тестовом или отладочном файле манифеста (обычно src / debug / AndroidManifest.xml)», просто отключите проверку

Теперь убедитесь, что вы отметили « Разрешить фиктивные местоположения » в настройках разработчика вашего телефона

Используйте LocationManager

locationManager.addTestProvider(mocLocationProvider, false, false,
                false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);

Теперь установите местоположение, где вы хотите

Location mockLocation = new Location(mocLocationProvider); 
mockLocation.setLatitude(lat); 
mockLocation.setLongitude(lng); 
mockLocation.setAltitude(alt); 
mockLocation.setTime(System.currentTimeMillis()); 
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation); 

0

Вышеуказанные решения не работали для меня, потому что я тестировал на устройстве Android с последней версией Сервисов Google Play, которая использует FusedLocationProviderClient . После установки разрешения на фиктивное местоположение в манифесте приложения и в качестве указанного приложения для фиктивного местоположения в настройках разработчика (как упомянуто в предыдущих ответах) я добавил код Kotlin, приведенный ниже, который успешно смоделировал местоположение.

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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.