大佬教程收集整理的这篇文章主要介绍了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,请注明来意。