[英]Qt5 QGeoPositionInfoSource::createDefaultSource() crashes on Android 5.0
我正在為 Android 開發一個 Qt5 應用程序(使用 CMake!),目前我正在嘗試使用 Qt 的QGeoPositionInfoSource
讀取位置數據。 到目前為止,我所有的應用程序都運行良好,但是當我運行時
auto source = QGeoPositionInfoSource::createDefaultSource(this);
應用程序立即崩潰, logcat
給我:
I/__log_qt( 422): (II) dpw_qt5: <last output from my app>
F/libc ( 422): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 797 (QtThread)
I/DEBUG ( 333): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 333): Build fingerprint: 'samsung/trltexx/trlte:5.0.1/LRX22C/N910FXXU1BOE3:user/release-keys'
I/DEBUG ( 333): Revision: '12'
I/DEBUG ( 333): ABI: 'arm'
I/DEBUG ( 333): pid: 422, tid: 797, name: QtThread >>> org.qtproject.DPW <<<
I/DEBUG ( 333): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
I/DEBUG ( 333): r0 00000000 r1 9d2bedf8 r2 00010006 r3 be7eb61d
I/DEBUG ( 333): r4 9d2bedf4 r5 9d2bedf8 r6 00000000 r7 9cffa030
I/DEBUG ( 333): r8 9d2bedf4 r9 afd04388 sl 00000001 fp 9d2bf8dc
I/DEBUG ( 333): ip 9cff9e80 sp 9d2bedd0 lr 9cff49b7 pc 9cff612e cpsr 60070030
I/DEBUG ( 333):
I/DEBUG ( 333): backtrace:
I/DEBUG ( 333): #00 pc 0000512e /data/data/org.qtproject.DPW/qt-reserved-files/plugins/position/libqtposition_android.so
I/DEBUG ( 333): #01 pc 000039b3 /data/data/org.qtproject.DPW/qt-reserved-files/plugins/position/libqtposition_android.so
我使用了最后三個 Android NDK 和 Qt 從 5.6 到 5.9 的幾個版本——結果都一樣,所以我認為我系統地做錯了什么。
我的AndroidManifest.xml
包含以下幾行:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
你知道我可以從哪里開始調查嗎?
更新:
我一直在追溯調用堆棧的最頂層行:
I/DEBUG ( 333): #00 pc 0000512e /data/data/org.qtproject.DPW
我發現jnipositioning.cpp
中的以下行導致崩潰:
if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
所以新的問題是:什么可以使javavm->GetEnv()
(在jni.h
中聲明)崩潰?
另一個更新:
jpo38指出,使用 qmake 構建的 Android 應用程序不會崩潰。 我已經建立了一個github 項目來演示這種行為。
所以現在的問題是:配置CMake和qmake的app有什么區別?
這顯然效果很好:
TestGeo.pro:
QT += core gui
QT += positioning
QT += widgets
TARGET = TestGeo
TEMPLATE = app
SOURCES += main.cpp
CONFIG += mobility
MOBILITY =
main.cpp中:
#include <QMainWindow>
#include <QApplication>
#include <QGeoPositionInfoSource>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
qDebug() << "Creating";
auto source = QGeoPositionInfoSource::createDefaultSource(&a);
if ( source )
qDebug() << "Created";
else
qDebug() << "NULL";
w.show();
return a.exec();
}
程序輸出沒有崩潰:
Creating
Created
請注意,我沒有向項目添加AndroidManifest.xml
文件。 它既可以啟用也可以禁用“本地化”。
我正在使用Android 5.1
( armeabi-v7a
)在Nexus 6
上部署Android-22
目標。 使用Qt 5.6
( GCC 4.9
)。 使用NDK r11b
。
您的設置一定有問題。
所以做這個設置,生成工作apk。 然后提取這個工作apk的內容和你失敗的apk。 通過檢查差異(缺少庫,文件,不同的清單......),您可以確定您的CMake構建和部署環境有什么問題,然后再修復它(可能通過手動復制CMake項目中的丟失文件)!
在您的情況下,缺少對Qt定位庫的引用。 只需將它們正確添加到AndroidManifest.xml
:
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/position/libqtposition_android.so"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidAccessibility.jar:jar/QtAndroid-bundled.jar:jar/QtAndroidAccessibility-bundled.jar:jar/QtPositioning.jar:jar/QtPositioning-bundled.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.positioning.QtPositioning:org.qtproject.qt5.android.positioning.QtPositioning"/>
如果在運行時崩潰檢查這個:
CMakeLists.txt
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Positioning REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Positioning REQUIRED)
target_link_libraries(PositioningAndroidTest PRIVATE Qt${QT_VERSION_MAJOR}::Positioning)
AndroidManifest.xml
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidExtras.jar:jar/QtPositioning.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.positioning.QtPositioning"/>
和 res/values/libs.xml
<array name="qt_libs">
<item>armeabi-v7a;Qt5Positioning_armeabi-v7a</item>
</array>
<array name="load_local_libs">
<item>armeabi-v7a;libplugins_platforms_qtforandroid_armeabi-v7a.so:libplugins_position_qtposition_android_armeabi-v7a.so</item>
</array>
這段代碼工作正常:
QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
if (source)
{
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
source->setUpdateInterval(1000);
source->startUpdates();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.