Qt5 QGeoPositionInfoSource :: createDefaultSource()在Android 5.0上崩溃

fra*_*ans 13 c++ qt android location android-ndk

我正在为Android开发一个Qt5应用程序(使用CMake!),目前我正在尝试使用Qt读取位置数据QGeoPositionInfoSource.到目前为止,我的所有应用程序都做得很好,但是当我跑步时

auto source = QGeoPositionInfoSource::createDefaultSource(this);
Run Code Online (Sandbox Code Playgroud)

应用程序立即崩溃并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
Run Code Online (Sandbox Code Playgroud)

我已经使用了最后三个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" />
Run Code Online (Sandbox Code Playgroud)

你有什么想法我可以开始调查吗?

更新:

我一直在追溯调用堆栈的最顶层:

I/DEBUG   (  333):     #00 pc 0000512e  /data/data/org.qtproject.DPW
Run Code Online (Sandbox Code Playgroud)

我发现里面的以下行jnipositioning.cpp会导致崩溃:

if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
Run Code Online (Sandbox Code Playgroud)

所以新的问题是:什么可以使javavm->GetEnv()(声明jni.h)崩溃?

另一个更新:

jpo38指出,使用qmake进行构建会导致Android应用程序无法崩溃.我已经建立了一个github项目来演示这种行为.

现在的问题是:使用CMake和qmake配置的应用程序之间有什么区别?

jpo*_*o38 1

这显然效果很好:

测试地理.pro:

QT += core gui
QT += positioning
QT += widgets

TARGET = TestGeo
TEMPLATE = app

SOURCES += main.cpp

CONFIG += mobility
MOBILITY = 
Run Code Online (Sandbox Code Playgroud)

主要.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();
}
Run Code Online (Sandbox Code Playgroud)

程序输出没有崩溃:

Creating
Created
Run Code Online (Sandbox Code Playgroud)

请注意,我没有AndroidManifest.xml向项目添加任何文件。它可以在启用或禁用“本地化”的情况下工作。

我正在以( ) 为Android-22目标进行部署。使用()。使用NDK 。Nexus 6Android 5.1armeabi-v7aQt 5.6GCC 4.9r11b

你的设置肯定有问题。

因此,进行此设置,生成工作 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"/>
Run Code Online (Sandbox Code Playgroud)