На основании обсуждения в теме «Самописный провайдер навигационных данных под Android - возможно ли такое?»...
Взяв за основу статью «Тестирование приложений в Android с использованием фиктивных данных о местоположении»...
Я сделал следующий проект:
https://github.com/xintrea/fakeLocationProviderOnQt
Он нужен мне для проверки того, может ли провайдер, созданный через метод addTestProvider(), поставлять данные геолокации для всей ОС Android (т. е. не только для приложения, в котором он запущен).
Проект должен быть на Qt/QML, поэтому вызовы Java-кода делаются через JNI. В данном примере есть просто две кнопки (Setup и Update), и при нажатии на каждую вызывается следующий Java-код:
// Инициализация фиктивного провайдера
public void setupFakeLocationProvider() {
Log.w(TAG, "Java: setupFakeLocationProvider start");
if(this==null) {
Log.w(TAG, "For JniEventActivity this is null");
return;
}
// Создание экземпляра класса MockLocationProvider
// с контекстом данной Активности
mock = new MockLocationProvider(LocationManager.GPS_PROVIDER, this);
Log.w(TAG, "After new MockLocationProvider");
//Set test location
mock.pushLocation(45.0, 45.0);
Log.w(TAG, "After mock.pushLocation");
Log.w(TAG, "Java: setupFakeLocationProvider stop");
}
// Обновление значений координат в фиктивном провайдере
public void updateFakeLocationProvider() {
Log.w(TAG, "Java: updateFakeLocationProvider");
// Пока ничего этот код не делает
}
Проблема в том, что при выполнении метода setupFakeLocationProvider(), выводится только строчка:
Java: setupFakeLocationProvider start
и больше строчек нет. Но сегфолта сразу не происходит, приложение как будто продолжает работать. И если нажать вторую кнопку, то выполнится метод updateFakeLocationProvider(), появится строка:
Java: updateFakeLocationProvider
и после этого произойдет сегфолт:
Core::setupFakeLocationProvider()): setupFakeLocationProvider from C++
W JniEventActivity: Java: setupFakeLocationProvider start
W libJniFakeLocationSample.so: ../JniFakeLocationSampleSrc/src/core/Core.cpp:119 (void Core::updateFakeLocationProvider()): updateFakeLocationProvider from C++
F art : art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception java.lang.IllegalStateException: System services not available to Activities before onCreate()
F art : art/runtime/java_vm_ext.cc:410] at java.lang.Object android.app.Activity.getSystemService(java.lang.String) (Activity.java:5381)
F art : art/runtime/java_vm_ext.cc:410] at void ru.farwater.gnss.fakelocsample.MockLocationProvider.<init>(java.lang.String, android.content.Context) (MockLocationProvider.java:16)
F art : art/runtime/java_vm_ext.cc:410] at void ru.farwater.gnss.fakelocsample.JniEventActivity.setupFakeLocationProvider() (JniEventActivity.java:91)
F art : art/runtime/java_vm_ext.cc:410] at void org.qtproject.qt5.android.QtNative.startQtApplication() (QtNative.java:-2)
F art : art/runtime/java_vm_ext.cc:410] at void org.qtproject.qt5.android.QtNative$6.run() (QtNative.java:359)
F art : art/runtime/java_vm_ext.cc:410] at void org.qtproject.qt5.android.QtThread$1.run() (QtThread.java:61)
F art : art/runtime/java_vm_ext.cc:410] at void java.lang.Thread.run() (Thread.java:833)
F art : art/runtime/java_vm_ext.cc:410]
F art : art/runtime/java_vm_ext.cc:410] in call to CallVoidMethodV
F art : art/runtime/java_vm_ext.cc:410] from void org.qtproject.qt5.android.QtNative.startQtApplication()
F art : art/runtime/java_vm_ext.cc:410] "qtMainLoopThread" prio=5 tid=10 Runnable
Насколько я понимаю, главная проблема в том, что «System services not available to Activities before onCreate()».
Она возникает в конструкторе класса MockLocationProvider на строке:
LocationManager lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
Вот это место в коде: https://github.com/xintrea/fakeLocationProviderOnQt/blob/bdb675186094402a37c0...
Люди в интернете говорят, что проблема может быть из-за того, что переменная ctx (в которую передается указатель на текущую Activity) просто не определена, так как у активности еще не вызван метод onCreate(): https://ru.stackoverflow.com/questions/448723/Ошибка-java-lang-illegalstateex...
Но в данном случае у меня активность создается задолго до того, как пользователь будет нажимать на кнопки для вызова Java-кода.
В общем, в чем может быть проблема, как ее исправить?