Цитата:
Сообщение от sirota
(Сообщение 340932)
Планируете продолжить изыскания в плане работы GPS в блюстаке без костылей?
|
Не планирую, а продолжаю потрошить Bluestacks.:yes2:
В папке
/data/downloads нашел приложение
BlueStacksLocationProvider.apk. Это приложение запрашивает координаты у функции
UpdateGpsCoordinates.
Приложение состоит из двух сервисов и одного класса.
Первый сервис
"GpsServiceStartReceiver" - автозагружаемый, и после автозагрузки запускает второй сервис
"GpsService". Т.к. в Bluestacks версий 0.9.х.х и выше время до срабатывания автозагрузки составляет секунд 30, то первый сервис запустится через это время, и только потом "пойдут" координаты.
Второй сервис
"GpsService" просто запускает класс
"QueryCoordinates", который в фоне циклически запрашивает координаты у функции UpdateGpsCoordinates и устанавливает их в качестве текущих. Но делает это как-то странно, а именно:
- Каждые 20 сек посылается запрос к функции UpdateGpsCoordinates для получения координат.
- Затем, в течение следующих 20 сек, эти полученные координаты устанавливаются в качестве текущих каждые 2 сек.
И так в бесконечном цикле. Это видно на 1-м и 2-м скриншотах (цифры после "Received result" - это координаты).
Еще нашел вот что - если в папке
/data создать файл
gps_debug_log, то в логах Android появятся записи приложения
BlueStacksLocationProvider.apk. Примеры на первых 5-ти скриншотах:
- 1-й и 2-й скриншоты - координаты берутся из реестра (GpsMode=1, GpsSource=8).
- 3-й, 4-й и 5-й скриншоты - координаты берутся с датчика местоположения (GpsMode=1, GpsSource=2).
На 3-м скриншоте видно, что функция UpdateGpsCoordinates координаты не выдает, т.к. не соблюдаются
условия.
Декомпилировал
BlueStacksLocationProvider.apk и изменил так, чтобы координаты запрашивались и устанавливались каждую секунду. Но все равно осталась проблема, что координаты приложениями не определяются в реальном времени, а определяются только в момент запуска, и то после нескольких перезапусков.
Поковырявшись в
BlueStacksLocationProvider.apk решил заменить провайдера "network" на "gps". Теперь заработало так, как надо. При изменении координат в реестре они, не более, чем через секунду, обновляются в эмуляторе, и приложения их сразу видят. Правда, в логах появилось ругательство "Provider gps unknown" (4-й скриншот).
В реестре координаты меняются при наличии датчика местоположения (при этом GpsSource становится равным 2). Но функция UpdateGpsCoordinates выдает координаты только, если GpsSource=8. Изменил
HD-Frontend.exe таким образом, чтобы координаты из реестра выдавались при GpsSource=2. Получилась такая цепочка:
- Мой самописный эмулятор GPS передает координаты в GpsGate.
- GpsGate через виртуальный COM-порт выдает координаты виртуальному датчику местоположения GpsDirect.
- Bluestacks видит этот датчик и в реальном времени обновляет координаты в реестре.
- BlueStacksLocationProvider.apk каждую секунду запрашивает координаты у функции UpdateGpsCoordinates и устанавливает их в качестве текущих.
По такой схеме все заработало! :yes4: 5-й скриншот. Но в Яндекс.Навигаторе вместо дельтаплана - зеленый кружок с буквой Я, который перемещается рывками каждую секунду (6-й скриншот, маленький зеленый кружок - это откуда был рывок).
Для работы этой схемы мне пришлось:
1. Изменить
HD-Agent.exe для работы с датчиком местоположения в Win7.
2. Изменить
HD-Frontend.exe для выдачи координат из реестра при GpsSource=2.
3. Изменить
BlueStacksLocationProvider.apk для увеличения скорости получения и установки координат; так же сменил провайдера с "network" на "gps".
Можно еще попробовать:
- Увеличить скорость запроса координат до 10 раз в секунду. Но не думаю, что рывки пропадут.
- Протестировать на реальном GPS-приемнике с датчиком местоположения (например, на VK-172).
Конечно, в идеале было бы неплохо добиться чтения координат в реальном времени из COM-порта или датчика местоположения без промежуточной записи в реестр и чтения оттуда, тем более, что так вроде изначально работает, но плохо...
PS: Долго мучался с тем, что мои изменения, внесенные в
HD-Frontend.exe никак не отражались на работе, все работало по старому. В итого выяснил, что вместо моего правленного
HD-Frontend.exe запускается скомпилированный (native image) из папки
c:\windows\assembly\nativeimages_v2.0.50727_32\hd-frontend\17a65e6ccd86293d8908aa427c0f3d54\hd-frontend.ni.exe
Нашел это с помощью PETools при запущенном Bluestacks. Просто так этот файл и папку удалить нельзя. Пришлось загружаться с LiveCD и уже оттуда удалять.
http://s018.radikal.ru/i506/1510/a1/810a02901c43t.jpg http://s006.radikal.ru/i215/1510/af/9bbe52643999t.jpg http://i016.radikal.ru/1510/51/80ea6c55d89bt.jpg http://s017.radikal.ru/i403/1510/25/3d06cbea1b0ft.jpg http://s019.radikal.ru/i611/1510/c0/e7da61baf8c1t.jpg http://s005.radikal.ru/i212/1510/63/099d774a72bdt.jpg