QT5 QGEOPOINTIONINFOSOURCE :: createFaultSource()在Android 5.

Qt5 QGeoPositionInfoSource::createDefaultSource() crashes on Android 5.0

本文关键字:Android QGEOPOINTIONINFOSOURCE createFaultSource QT5      更新时间:2023-10-16

我正在为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配置的应用程序有什么区别?

这显然效果很好:

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文件。它既可以使用"本地化"启用或禁用。

我正在用Nexus 6上的Android-22目标与Android 5.1armeabi-v7a)部署。使用Qt 5.6GCC 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();
}