程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android 上的 Qt 蓝牙“无法启动经典发现”大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Android 上的 Qt 蓝牙“无法启动经典发现”?

开发过程中遇到Android 上的 Qt 蓝牙“无法启动经典发现”的问题如何解决?下面主要结合日常开发的经验,给出你关于Android 上的 Qt 蓝牙“无法启动经典发现”的解决方法建议,希望对你解决Android 上的 Qt 蓝牙“无法启动经典发现”有所启发或帮助;

我正在使用 Qt 5.15.2 为 AndroID 开发应用程序。 SDK 版本为 3.0,NDK 为 21.1.6352462,目标 SDK 为 30。目前,当我在 Samsung galaxy Tab S7+ 上使用 discoveryAgent->start(QBluetoothDevicediscoveryAgent::Classicmethod); 启动设备发现时,我在应用程序中得到以下输出输出:

    W libBtTrial_arm64-v8a.so: qt.bluetooth.androID: ACCESS_COARSE|FINE_LOCATION permission available
    I BluetoothAdapter: startdiscovery
    I libBtTrial_arm64-v8a.so: WriTing or reading from the device resulted in an error. "Classic discovery cAnnot be started"

我试图理解这个问题,因为应用程序的第一个版本没有这个问题,我发现导致这种行为的原因是 .pro 中的以下行:

ANDROID_TARGET_SDK_VERSION = 30

这是必需的,因为在 Google Play 商店中,您只能上传面向 SDK 版本 29 或更高版本的应用。如果我将版本设置为 28,蓝牙将开始工作,但我必须针对 SDK 版本 30。我是否遗漏了什么? 任何提示将不胜感激。

这是一个可重现的小例子:

BtTrial.pro

QT += bluetooth qml quick

androID: QT+= androIDextras
CONfig += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so,uncomment the following line.
#defines += QT_disABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

sourcES += \
        bluetoothsearcher.cpp \
        main.cpp

resourcES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_import_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_import_PATH =

ANDROID_TARGET_SDK_VERSION = 30

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!androID: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

disTfileS += \
    androID/AndroIDManifest.xml \
    androID/build.gradle \
    androID/gradle.propertIEs \
    androID/gradle/wrapper/gradle-wrapper.jar \
    androID/gradle/wrapper/gradle-wrapper.propertIEs \
    androID/gradlew \
    androID/gradlew.bat \
    androID/res/values/libs.xml

ANDROID_PACKAGE_sourcE_DIR = $$PWD/androID

headerS += \
    bluetoothsearcher.h

bluetoothsearcher.cpp

#include "bluetoothsearcher.h"

BluetoothSearcher::BluetoothSearcher(QObject *parent) : QObject(parent)
{

}

voID BluetoothSearcher::searchBluetooth() {

    qDeBUG() << "Bluetooth Searcher StarTing";
    if (localDevice == nullptr) {

        localDevice = new QBluetoothLocalDevice(this);
        connect(localDevice,&QBluetoothLocalDevice::pairingFinished,this,&BluetoothSearcher::pairingDonE);
        connect(localDevice,&QBluetoothLocalDevice::pairingdisplayConfirmation,&BluetoothSearcher::pairingMydisplayConfirmation);
        connect(localDevice,&QBluetoothLocalDevice::pairingdisplayPinCode,&BluetoothSearcher::displayPin);
    }

    QString localdeviceName;
    if (localDevice->isValID()) {
        localDevice->powerOn();
        localdeviceName = localDevice->name();

        QList<QBluetoothAddress> remotes;
        remotes = localDevice->connectedDevices();
        foreach (QBluetoothAddress address,remotes) {
            qInfo() << address;
        }
    } else qInfo() << "Attenzione,il bt non è valIDo";

    QBluetoothDevicediscoveryAgent *discoveryAgent = new QBluetoothDevicediscoveryAgent(this);
    connect(discoveryAgent,&QBluetoothDevicediscoveryAgent::devicediscovered,&BluetoothSearcher::devicediscovered);
    connect(discoveryAgent,&QBluetoothDevicediscoveryAgent::finished,&BluetoothSearcher::devicediscoveryFinished);
    connect(discoveryAgent,static_cast<voID (QBluetoothDevicediscoveryAgent::*)(QBluetoothDevicediscoveryAgent::Error)>(&QBluetoothDevicediscoveryAgent::error),&BluetoothSearcher::scanError);


#if Defined (Q_OS_ANDROID) || defined (Q_OS_windows)
    discoveryAgent->start(QBluetoothDevicediscoveryAgent::Classicmethod);
#else
    qWarning() << "Must Implement The Ble Communication for IOS";
#endif
}


voID BluetoothSearcher::requestPairing(QString address)
{
    QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(QBluetoothAddress(address));
    qDeBUG() << "Pairing Status:" << pairingStatus << address;
    if (pairingStatus != QBluetoothLocalDevice::Paired && pairingStatus != QBluetoothLocalDevice::AuthorizedPaired )
        localDevice->requestPairing(QBluetoothAddress(address),QBluetoothLocalDevice::Paired);
}

voID BluetoothSearcher::devicediscovered(const QBluetoothDeviceInfo &devicE)
{
    qDeBUG() << device.name();
    if (device.name().contains("_C") || device.name().contains("_V")) {
        qDeBUG() << "Found new device:" << device.name() << '(' << device.address().toString() << ')';
        QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(device.address());
        qDeBUG() << "Pairing Status:" << pairingStatus << device.address();
        bool paired = true;
        if (pairingStatus != QBluetoothLocalDevice::Paired && pairingStatus != QBluetoothLocalDevice::AuthorizedPaired )
            paired = false;

#ifdef Q_OS_WIN
        /* this is because the windows bt API on Qt 5.15.2 shows only prevIoUsly paired device from windows */
        paired = true;
#endif
        emit newDeviceFound(device.name(),device.address().toString(),paired);
    }
}

voID BluetoothSearcher::devicediscoveryFinished()
{
    emit discoveryFinished();
    qInfo() << "Device discovery Finished";
}

voID BluetoothSearcher::pairingDone(const QBluetoothAddress &address,QBluetoothLocalDevice::Pairing pairing)
{
    qInfo() << "Pairing Result:" << pairing << " for device " << address.toString();
    emit deviceCorrectlyPaired(address.toString());
}

voID BluetoothSearcher::pairingMydisplayConfirmation(const QBluetoothAddress& address,QString pin)
{
    qDeBUG() << "#PAIRING_disPLAY_CONFIRMATION_PIN: " << pin << "for" << address;
}

voID BluetoothSearcher::displayPin(QBluetoothAddress address,QString pin)
{
    qDeBUG() << "&disPLAY_CONFIRMATION_PIN: " << pin << "for" << address;
}

voID BluetoothSearcher::scanError(QBluetoothDevicediscoveryAgent::Error error)
{
    QBluetoothDevicediscoveryAgent *deviceAgent = static_cast<QBluetoothDevicediscoveryAgent*>(QObject::sender());
    if (error == QBluetoothDevicediscoveryAgent::PoweredOffError)
        qInfo() << "The Bluetooth adaptor is powered off.";
    else if (error == QBluetoothDevicediscoveryAgent::inputOutputError) {
        qInfo() << "WriTing or reading from the device resulted in an error." << deviceAgent->errorString();
        emit bluetoothError(0);
    } else {
        qInfo() << "An unkNown error has occurred." << error << deviceAgent->errorString();
        emit bluetoothError(0);
    }
}

bluetoothsearcher.h

#ifndef BLUetoOTHSEARCHER_H
#define BLUetoOTHSEARCHER_H

#include <QObject>
#include <QBluetoothDevicediscoveryAgent>
#include <QBluetoothAddress>
#include <QBluetoothLocalDevice>
#include <QDeBUG>

class BluetoothSearcher : public QObject
{
    Q_OBjeCT
public:
    explicit BluetoothSearcher(QObject *parent = nullptr);

    Q_INVOKABLE voID searchBluetooth();

signals:
    voID newDevicesFound(QStringList devicesFound);
    voID newDeviceFound(QString,QString,bool);
    voID discoveryFinished();
    voID bluetoothError(int);
    voID deviceCorrectlyPaired(QString address);

public slots:
    voID requestPairing(QString address);

private slots:
    voID devicediscovered(const QBluetoothDeviceInfo &devicE);
    voID devicediscoveryFinished();
    voID pairingDone(const QBluetoothAddress &address,QBluetoothLocalDevice::Pairing pairing);

    voID pairingMydisplayConfirmation(const QBluetoothAddress &,QString);
    voID displayPin(QBluetoothAddress,QString);
    voID scanError(QBluetoothDevicediscoveryAgent::Error error);

private:
    QBluetoothDevicediscoveryAgent *discoveryAgent{nullptr};
    QBluetoothLocalDevice *localDevice{nullptr};
};

#endif // BLUetoOTHSEARCHER_H
@H_56_2@main.cpp

#include <QGuiApplication>
#include <QQmlApplicationENGIne>
#include <QQmlContext>

#include "bluetoothsearcher.h"

#if Defined (Q_OS_ANDROID)
#include <QtAndroID>
const QVector<QString> permissions({"androID.permission.bLUetoOTH","androID.permission.bLUetoOTH_admin","androID.permission.ACCESS_COARSE_LOCATION","androID.permission.WRITE_EXTERNAL_STORAGE","androID.permission.READ_EXTERNAL_STORAGE"/*,"androID.permission.INTERNET"*/});
#endif

int main(int argc,char *argv[])
{
#if QT_VERSION < QT_VERSION_checK(6,0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc,argv);

#if Defined (Q_OS_ANDROID)
    for (const QString &permission : permissions) {
        auto result = QtAndroID::checkPermission(permission);
        if (result == QtAndroID::PermissionResult::DenIEd) {
            auto resultHash = QtAndroID::requestPermissionsSync(QStringList({permission}));
            if (resultHash[permission] == QtAndroID::PermissionResult::DenIEd)
                return 0;
        }
    }
#endif

    BluetoothSearcher bluetoothSearcher;

    QQmlApplicationENGIne ENGIne;

    ENGIne.rootContext()->setContextProperty("bluetoothSearcher",&bluetoothSearcher);

    const QUrl url(QStringliteral("qrc:/main.qml"));
    QObject::connect(&ENGIne,&QQmlApplicationENGIne::objectCreated,&app,[url](QObject *obj,const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    },Qt::QueuedConnection);
    ENGIne.load(url);

    return app.exec();
}
@H_56_2@main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    wIDth: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Rectangle {
        anchors.fill: parent


        Rectangle {
            anchors {
                right: parent.right
                left: parent.left
                bottom: parent.bottom
            }
            color: "red"

            height: 32

            MouseArea {
                anchors.fill: parent
                onClicked: bluetoothSearcher.searchBluetooth()
            }
        }
    }


}

AndroIDManifest.xml

<?xml version="1.0"?>
<manifest package="org.qtproject.example" xmlns:androID="http://scheR_299_11845@as.androID.com/apk/res/androID" androID:versionname="0.0.030" androID:versionCode="1" androID:installLOCATIOn="auto">
    <!-- The following comment will be replaced upon deployment with default permissions based on the dependencIEs of the application.
         Remove the comment if you do not require these default permissions. -->
    <!-- %%INSERT_PERMISSIONS -->

    <!-- The following comment will be replaced upon deployment with default features based on the dependencIEs of the application.
         Remove the comment if you do not require these default features. -->
    <!-- %%INSERT_FEATURES -->

    <supports-screens androID:largeScreens="true" androID:normalScreens="true" androID:anyDensity="true" androID:smallScreens="true"/>
    <application androID:harDWareAccelerated="true" androID:name="org.qtproject.qt5.androID.bindings.QtApplication" androID:label="BtTrial" androID:extractNativelibs="true">
        <activity androID:configChanges="orIEntation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|FontScale|keyboard|keyboardHIDden|navigation|mcc|mnc|density" androID:name="org.qtproject.qt5.androID.bindings.QtActivity" androID:label="BtTrial" androID:screenorIEntation="sensorLandscape" androID:launchMode="singletop">
            <intent-filter>
                <action androID:name="androID.intent.action.MAIN"/>
                <category androID:name="androID.intent.category.LAUNCHER"/>
            </intent-filter>
            <!-- Application arguments -->
            <!-- Meta-data androID:name="androID.app.arguments" androID:value="arg1 arg2 arg3"/ -->
            <!-- Application arguments -->
            <Meta-data androID:name="androID.app.lib_name" androID:value="-- %%INSERT_APP_liB_name%% --"/>
            <Meta-data androID:name="androID.app.qt_sources_resource_id" androID:resource="@array/qt_sources"/>
            <Meta-data androID:name="androID.app.repository" androID:value="default"/>
            <Meta-data androID:name="androID.app.qt_libs_resource_id" androID:resource="@array/qt_libs"/>
            <Meta-data androID:name="androID.app.bundled_libs_resource_id" androID:resource="@array/bundled_libs"/>
            <!-- Deploy Qt libs as part of package -->
            <Meta-data androID:name="androID.app.bundle_local_qt_libs" androID:value="-- %%BUNDLE_LOCAL_QT_liBS%% --"/>
            <!-- Run with local libs -->
            <Meta-data androID:name="androID.app.use_local_qt_libs" androID:value="-- %%USE_LOCAL_QT_liBS%% --"/>
            <Meta-data androID:name="androID.app.libs_prefix" androID:value="/data/local/tmp/qt/"/>
            <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="-- %%INSERT_LOCAL_JARS%% --"/>
            <Meta-data androID:name="androID.app.static_init_classes" androID:value="-- %%INSERT_INIT_CLASSES%% --"/>
            <!-- Used to specify custom system library path to run with local system libs -->
            <!-- <Meta-data androID:name="androID.app.system_libs_prefix" androID:value="/system/lib/"/> -->
            <!--  messages maps -->
            <Meta-data androID:value="@String/ministro_not_found_msg" androID:name="androID.app.ministro_not_found_msg"/>
            <Meta-data androID:value="@String/ministro_needed_msg" androID:name="androID.app.ministro_needed_msg"/>
            <Meta-data androID:value="@String/fatal_error_msg" androID:name="androID.app.fatal_error_msg"/>
            <Meta-data androID:value="@String/unsupported_androID_version" androID:name="androID.app.unsupported_androID_version"/>
            <!--  messages maps -->
            <!-- Splash screen -->
            <!-- OrIEntation-specific (porTrait/landscapE) data is checked first. If not available for current orIEntation,then androID.app.splash_screen_drawable. For best results,use together with splash_screen_sticky and
                 use hIDeSplashScreen() with a fade-out animation from Qt AndroID Extras to hIDe the splash screen when you
                 are done populaTing your window with content. -->
            <!-- Meta-data androID:name="androID.app.splash_screen_drawable_porTrait" androID:resource="@drawable/logo_porTrait" / -->
            <!-- Meta-data androID:name="androID.app.splash_screen_drawable_landscape" androID:resource="@drawable/logo_landscape" / -->
            <!-- Meta-data androID:name="androID.app.splash_screen_drawable" androID:resource="@drawable/logo"/ -->
            <!-- Meta-data androID:name="androID.app.splash_screen_sticky" androID:value="true"/ -->
            <!-- Splash screen -->
            <!-- BACkground running -->
            <!-- Warning: changing this value to true may cause unexpected crashes if the
                          application still try to draw after
                          "applicationStateChanged(Qt::ApplicationSuspended)"
                          signal is sent! -->
            <Meta-data androID:name="androID.app.BACkground_running" androID:value="false"/>
            <!-- BACkground running -->
            <!-- auto screen scale factor -->
            <Meta-data androID:name="androID.app.auto_screen_scale_factor" androID:value="false"/>
            <!-- auto screen scale factor -->
            <!-- extract androID style -->
            <!-- available androID:values :
                * default - In most cases this will be the same as "full",but it can also be something else if needed,e.g.,for compatibility reasons
                * full - useful QWidget & Quick Controls 1 apps
                * minimal - useful for Quick Controls 2 apps,it is much faster than "full"
                * none - useful for apps that don't use any of the above Qt modules
                -->
            <Meta-data androID:name="androID.app.extract_androID_style" androID:value="default"/>
            <!-- extract androID style -->
        </activity>
        <!-- For adding service(s) please check: https://wiki.qt.io/AndroIDservices -->
    </application>

<uses-permission androID:name="androID.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission androID:name="androID.permission.bLUetoOTH_admin"/>
    <uses-permission androID:name="androID.permission.bLUetoOTH"/>
    <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE"/>


</manifest>

预先感谢您的帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

大佬总结

以上是大佬教程为你收集整理的Android 上的 Qt 蓝牙“无法启动经典发现”全部内容,希望文章能够帮你解决Android 上的 Qt 蓝牙“无法启动经典发现”所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。