我正在Qt Creator中开发一个跨平台应用程序,该应用程序具有通过经典蓝牙控制设备的功能。我有一个通讯协议。首先:我可以连接到设备并使用BluetoothSocket将数据写入其中。如果在命令startMotor()
之后将socketConnected
函数放入beepBuzzor()
SLOT中,则它可以正常工作,并且得到state()
connected
。
我的问题是,如果我在Android上的应用程序中切换页面并单击“启动电动机”按钮,则会得到state()
unconnected
,但我仍然连接到设备,因为设备上的LED显示已连接。我的应用程序不会崩溃。我认为问题与socket->connectToService(...)
一致,但是我不确定要更改什么。 beepBuzzor命令可以正常运行,startMotor命令也可以。但是,如果我在成功connectToService()之后调用该函数,则该函数将不起作用,因为状态未连接。
BluetoothManager::BluetoothManager(QObject *parent) : QObject(parent)
{
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
}
void BluetoothManager::startDiscovery()
{
// Check if Bluetooth is available on this device
if (localDevice.isValid()) {
qDebug() << "Bluetooth is available on this device";
//Turn BT on
localDevice.powerOn();
// Make it visible to others
localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
//Read local device name & address
qDebug() << "Local Device:" << localDevice.name() << "(" << "Address:" << localDevice.address() << ")";
// Create a discovery agent and connect to its signals
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, SIGNAL(finished()), this, SLOT(deviceDiscoverFinished()));
// Start a discovery
// Trick: da es kein DiscoveryTimer für Classic gibt, suchen wir nach LE devices, da BT121 BLE unterstützt.
// Die Verbindung erfolgt jedoch über RFCOMM sobald man sich mit dem Gerät verbindet.
discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
qDebug() << "Device discover started";
}
else
{
qDebug() << "Bluetooth is not available on this device";
}
}
//SLOT for the finish of device Discovery
void BluetoothManager::deviceDiscoverFinished()
{
qDebug() << "Device discover finished";
listOfDevices = discoveryAgent->discoveredDevices();
qDebug() << "Found new devices:";
for (int i = 0; i < listOfDevices.size(); i++)
{
//Q_OS_IOS / MAC do not need here cuz the run is on android device, delete later
//We do not find galileo device on MacBook
#if defined (Q_OS_IOS) || defined (Q_OS_MAC)
// On MacOS and iOS we get no access to device address,
// only unique UUIDs generated by Core Bluetooth.
qDebug() << "getting address from deviceUuid()" << listOfDevices.at(i).name().trimmed()
<< " ( " << listOfDevices.at(i).deviceUuid().toString().trimmed() << " ) ";
setDevice(listOfDevices.at(i).name().trimmed() + " (" + listOfDevices.at(i).deviceUuid().toString().trimmed() + ")");
#else
qDebug() << listOfDevices.at(i).name().trimmed()
<< " ("
<< listOfDevices.at(i).address().toString().trimmed()
<< ")";
setDevice(listOfDevices.at(i).name().trimmed() + " (" + listOfDevices.at(i).address().toString().trimmed() + ")");
#endif
}
}
/**
* In GUI (QML) user select a device with index i.
* Create a new socket, using Rfcomm protocol to communicate
*/
void BluetoothManager::deviceSelected(int i)
{
selectedDevice = listOfDevices.at(i);
#if defined (Q_OS_IOS) || defined (Q_OS_MAC)
qDebug() << "User select a device: " << selectedDevice.name() << " ("
<< selectedDevice.deviceUuid().toString().trimmed() << ")";
#else
qDebug() << "User select a device: " << selectedDevice.name() << " ("
<< selectedDevice.address().toString().trimmed() << ")";
#endif
if (localDevice.pairingStatus(selectedDevice.address())== QBluetoothLocalDevice::Paired)
{
qDebug() << "Pairing is allready done";
}
else
{
qDebug() << "Not paired. Please do pairing first for communication with device!";
}
selecDevAdress = selectedDevice.address();
connectToSvc();
//Connect SIGNALS with SLOTS
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(socketError(QBluetoothSocket::SocketError)));
connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(socketRead()));
connect(socket, SIGNAL(stateChanged(QBluetoothSocket::SocketState)), this, SLOT(socketStateChanged()));
}
void BluetoothManager::connectToSvc()
{
qDebug() << "Create socket";
//socket->connectToService(selecDevAdress, QBluetoothUuid(QString("00001101-0000-1000-8000-00805F9B34FB")), QIODevice::ReadWrite);
//static const QString serviceUuid(QStringLiteral("00001101-0000-1000-8000-00805F9B34FB"));
socket->connectToService(selectedDevice.address(), QBluetoothUuid(QString("00001101-0000-1000-8000-00805F9B34FB")), QIODevice::ReadWrite);
//Also works with this line instead of the two above (with declaration of serviceUuid)
//socket->connectToService(QBluetoothAddress(selectedDevice.address()),QBluetoothUuid(QBluetoothUuid::SerialPort));
socket->open(QIODevice::ReadWrite);
socket->openMode();
}
//SLOT wenn Socket verbunden ist
void BluetoothManager::socketConnected()
{
//qDebug() << ("Connected to: "+socket->peerAddress().toString() +":"+socket->peerPort());
qDebug() << ("Connected to: "+socket->peerAddress().toString());
qDebug() << "Socket connected";
qDebug() << "Local: "
<< socket->localName()
<< socket->localAddress().toString()
<< socket->localPort();
qDebug() << "Peer: "
<< socket->peerName()
<< socket->peerAddress().toString()
<< socket->peerPort();
//Do "beep" sound commando after succesfull connection to Galileo device
beepBuzzor();
}
/**
* Socket disconnected.
* Delete socket, free the memory.
*/
//SLOT für Verbindungsabbruch von Socket
void BluetoothManager::socketDisconnected()
{
qDebug() << "Socket disconnected";
socket->deleteLater();
}
void BluetoothManager::socketError(QBluetoothSocket::SocketError error)
{
qDebug() << "Socket error: " << error;
}
void BluetoothManager::socketStateChanged()
{
int socketState = socket->state();
if(socketState == QAbstractSocket::UnconnectedState)
{
qDebug() << "unconnected";
}
else if(socketState == QAbstractSocket::HostLookupState)
{
qDebug() << "host lookup";
}
else if(socketState == QAbstractSocket::ConnectingState )
{
qDebug() << "connecting";
}
else if(socketState == QAbstractSocket::ConnectedState)
{
qDebug() << "connected";
}
else if(socketState == QAbstractSocket::BoundState)
{
qDebug() << "bound";
}
else if(socketState == QAbstractSocket::ClosingState)
{
qDebug() << "closing";
}
else if(socketState == QAbstractSocket::ListeningState)
{
qDebug() << "listening";
}
}
// SLOT when data ready on bluetooth socket
void BluetoothManager::socketRead()
{
qDebug() << "socketRead()";
QByteArray recievedData = socket->readAll();
emit dataRecieved(recievedData);
}
/**
* Get a string with device info
*/
const QString &BluetoothManager::device() const
{
return deviceInfo;
}
void BluetoothManager::setDevice(const QString &newDevice)
{
if (newDevice != deviceInfo) {
deviceInfo = newDevice;
emit deviceChanged();
}
}
void BluetoothManager::beepBuzzor()
{
QByteArray beep;
beep.append(QByteArray::fromRawData("\x04\x00\x09\xD0\x07\x32\x00", 7));
command(beep);
}
void BluetoothManager::startMotor()
{
qDebug() << "startMotor slot";
if(socket->state() == QBluetoothSocket::UnconnectedState){
qDebug() << "Socket Unconnected";
}
else{
qDebug() << "Socket Unonnected";
}
socketStateChanged();
//command(start);
}
void BluetoothManager::command(QByteArray &cmdBuf)
{
socket->write(cmdBuf);
}