MyTetra Share
Делитесь знаниями!
Тестирование приложений в Android с использованием фиктивных данных о местоположении
11.01.2019
10:12
Текстовые метки: андроид, android, навигация, геолокация, фиктивные, фейковые, координаты, местоположение
Раздел: Компьютер - Программирование - Язык C++ - Библиотека Qt - Картография в Qt и QML

Перевод статьи "Testing with Mock Location Data in Android"


Dalvik Debug Monitor Server (DDMS) — это полезный инструмент для отладки приложений. Он идет в комплекте с Android SDK. С помошью него можно протолкнуть в память приложения фейковые координаты во время тестирования. Однако у него есть два серьезных ограничения:


  1. DDMS устанавливает местоположение только для провайдера местоположения GPS. Если ваше приложение использует какой-либо "сетевой" провайдер (например, по точкам доступа WiFi или по триангуляции GSM сигнала с вышек GSM), то вам не повезло.
  2. DDMS может установить местоположение только для эмулятора устройства. Вы не можете проводить тестирование с использованием реального устройства.


Если вам нужно протестировать работу приложения на реальном устройстве, или если приложение использует данные "сетевого" провайдера местоположения, то вам необходимо разработать фиктивный провайдер в приложении. Этот промежуточный макетный провайдер может представлять данные от любого провайдера местоположения - от "сетевого" или GPS. Написание такого фиктивного провайдера само по себе просто. Однако будьте осторожны, и не забудьте удалить этот функционал перед публикацией приложения.


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


Сначала мы разработаем класс, который будет инкапсулировать детали реализации:



public class MockLocationProvider {

String providerName;

Context ctx;


// Конструктор фиктивного провайдера

public MockLocationProvider(String name, Context ctx) {

this.providerName = name;

this.ctx = ctx;


LocationManager lm = (LocationManager) ctx.getSystemService(

Context.LOCATION_SERVICE);


lm.addTestProvider(providerName,

false, // requiresNetwork

false, // requiresSatellite

false, // requiresCell

false, // hasMonetaryCost

false, // supportsAltitude

true, // supportsSpeed

true, // supportsBearing

0, // powerRequirement

5 // accuracy

);

lm.setTestProviderEnabled(providerName, true);

}


// Установка координат в фиктивном провайдере

public void pushLocation(double lat, double lon) {

LocationManager lm = (LocationManager) ctx.getSystemService(

Context.LOCATION_SERVICE);


Location mockLocation = new Location(providerName);

mockLocation.setLatitude(lat);

mockLocation.setLongitude(lon);

mockLocation.setAltitude(0);

mockLocation.setTime(System.currentTimeMillis());

lm.setTestProviderLocation(providerName, mockLocation);

}


// Выключение фиктивного провайдера

public void shutdown() {

LocationManager lm = (LocationManager) ctx.getSystemService(

Context.LOCATION_SERVICE);

lm.removeTestProvider(providerName);

}

}



Краткое описание класса MockLocationProvider (может быть полезным):


  • Конструктор получает в качестве параметра имя поставщика данных о местоположении, который этот фиктивный поставщик заменит собой (в указанном контексте). Например, LocationManager.GPS_PROVIDER. Вызовы addTestProvider () и setTestProviderEnabled () сообщают LocationManager, что данный поставщик будет заменен поставщиком фиктивных данных.
  • Метод pushLocation () устанавливает данные фиктивного местоположения для данного провайдера.


Любые Активности или Сервисы могут легко использовать этот класс. Ниже показано, как заменяется провайдер сети LocationManager.NETWORK_PROVIDER фиктивным провадером:



public class MainActivity extends Activity {

MockLocationProvider mock;


// Действия при создании Активности

public void onCreate(Bundle savedInstanceState) {


// Вызов действий при создании Активности родительского класса

super.onCreate(savedInstanceState);


setContentView(R.layout.activity_main);


// Создание экземпляра вышеописаного класса MockLocationProvider

// с контекстом данной Активности

mock = new MockLocationProvider(LocationManager.NETWORK_PROVIDER, this);


//Set test location

mock.pushLocation(-12.34, 23.45);


LocationManager locMgr = (LocationManager)

getSystemService(LOCATION_SERVICE);


LocationListener lis = new LocationListener() {

public void onLocationChanged(Location location) {

// Здесь получаются фиктивные координаты местоположения

}

};


locMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,

1000, 1, lis);

}


// Действия при удалении Активности

protected void onDestroy() {

mock.shutdown();

super.onDestroy();

}

}



Настройки безопасности


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


Вам нужно будет запросить разрешение android.permission.ACCESS_MOCK_LOCATION в дополнение к остальным разрешениям.


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

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


Наконец, нужно включить использование фиктивных местоположений для устройства, используя:


Настройки > Параметры разработчика > Разрешить фиктивные местоположения.



Отключение провайдера фиктивного местоположения


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


Вот пример проверки, установлен ли флаг отладки:



if ((getApplication().getApplicationInfo().flags &

ApplicationInfo.FLAG_DEBUGGABLE) != 0) {

mock = new MockLocationProvider(

LocationManager.NETWORK_PROVIDER, this);


//Set test location

mock.pushLocation(-12.34, 23.45);

}



При тестировании приложения с помощью отладки по USB или с помощью эмулятора, флаг отладки устанавливается автоматически.



Примечание: при чем тут Qt и QML, если весь код выше написан на Java? При том, что данный Java-код можно вызывать из C++ через JNI.


Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования