QT中使用低功耗蓝牙

本代码适用QT for Android (其他平台没有测试,不知道可不可以)

pro文件中添加bluetooth模块
QT +=bluetooth
// 头文件
#include
#include
#include
namespace Ui {
class bluetooth;
}
class bluetooth : public QWidget
{
    Q_OBJECT

public:
    explicit bluetooth(QWidget *parent = 0);
    ~bluetooth();
    void    connectDev(QBluetoothDeviceInfo dev);
    void    searchCharteris();
    void    msgSendToServer(QByteArray arry);
signals:
    void SigSendto(QString);
public slots:
    void SlotAddDevicesToList(QBluetoothDeviceInfo info);
    void SlotItemActivated(QListWidgetItem *item);
    void SlotBluetoothConnected();
    void SlotBluetoothDisConnected();
    void SlotBluetoothReadData();
private slots:
    void on_openBtn_clicked();

    void on_scanBtn_clicked();

    void on_sendBtn_2_clicked();

    void on_clearBtn_clicked();

    void on_closeBtn_clicked();

    void on_disconnectBtn_clicked();
private:
    Ui::bluetooth *ui;
    QBluetoothDeviceDiscoveryAgent *m_discoveryAgent;
    QBluetoothLocalDevice *m_localDevice;
    
    QString m_vector;
    QList<QBluetoothDeviceInfo> m_devList;
    QLowEnergyController *m_controler;
    QLowEnergyService*m_bluetoothServer;
    bool   m_oneDevHaveConnected = false; // 当前已连接一台蓝牙设备
    QVector<QLowEnergyService::WriteMode>  m_writeMode;
    QVector<QLowEnergyCharacteristic> m_writeChars;
    QLowEnergyCharacteristic  m_readChars;
    QLowEnergyDescriptor m_notifiDesc;
    int                  m_whichChars =-1;
    QBluetoothUuid m_uuid;
    int                   m_whichChange = -1;
};

cpp文件

bluetooth::bluetooth(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::bluetooth)
  ,m_discoveryAgent(new QBluetoothDeviceDiscoveryAgent())
  ,m_localDevice(new QBluetoothLocalDevice())
 ,m_controler(NULL)
  ,m_bluetoothServer(NULL)
{
    ui->setupUi(this);
    ui->lineEdit->setEnabled(false);
    m_localDevice->hostMode() == QBluetoothLocalDevice::HostDiscoverable;
    //ui->checkBox->setCheckable(true);
    ui->listWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                       "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                       "QScrollBar::handle:hover{background:green;width:10px}"
                                                       "QScrollBar::sub-line{background:transparent;}"
                                                       "QScrollBar::add-line{background:transparent;}");
    ui->textEditFromClient->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                               "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                               "QScrollBar::handle:hover{background:green;width:10px}"
                                                               "QScrollBar::sub-line{background:transparent;}"
                                                               "QScrollBar::add-line{background:transparent;}");
    ui->textEditFromSever->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                              "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                              "QScrollBar::handle:hover{background:green;width:5px}"
                                                              "QScrollBar::sub-line{background:transparent;}"
                                                              "QScrollBar::add-line{background:transparent;}");

    ui->textEditFromSever_3->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                                "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                                "QScrollBar::handle:hover{background:green;width:10px}"
                                                                "QScrollBar::sub-line{background:transparent;}"
                                                                "QScrollBar::add-line{background:transparent;}");


    ui->listWidget_2->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                                        "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                                        "QScrollBar::handle:hover{background:green;width:10px}"
                                                                        "QScrollBar::sub-line{background:transparent;}"
                                                                        "QScrollBar::add-line{background:transparent;}");
    ui->listWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
                                                         "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
                                                         "QScrollBar::handle:hover{background:green;width:10px}"
                                                         "QScrollBar::sub-line{background:transparent;}"
                                                         "QScrollBar::add-line{background:transparent;}");

    setRadioButtonStyle(ui->changIpBtn, 16, "#D7DBDE", "#1ABC9C");
    setRadioButtonStyle(ui->changeYmBtn, 16, "#D7DBDE", "#1ABC9C");
    setRadioButtonStyle(ui->changeVolBtn, 16, "#D7DBDE", "#1ABC9C");
    // 鉴权
    connect(ui->autoMationBtn,&QToolButton::clicked,[=](){
        QString autoMationInfo("automation");
        QByteArray array = autoMationInfo.toLatin1();
         msgSendToServer(array);
    });
    connect(ui->changIpBtn,&QRadioButton::clicked,[=](){
        m_whichChange = 1;
    });
    connect(ui->changeYmBtn,&QRadioButton::clicked,[=](){
        m_whichChange = 2;
    });
    connect(ui->changeVolBtn,&QRadioButton::clicked,[=](){
        m_whichChange = 3;
    });
    connect(ui->kcCheckBox,&QCheckBox::clicked,[=](bool flag){
        QString msg="";
        if(flag) // 打开快充
        {
           msg="fastchargeon";
        }
        else
        {
           msg="fastchargeoff";
        }
        msgSendToServer(msg.toLatin1());
    });
    connect(ui->buzzCheckBox,&QCheckBox::clicked,[=](bool flag){
        QString msg="";
        if(flag) // 打开蜂鸣器
        {
           msg = "buzzeron";
        }
        else
        {
           msg = "buzzeroff";
        }
        msgSendToServer(msg.toLatin1());
    });
    ui->label_4->hide();
    ui->lineEdit->hide();
    connect(ui->listWidget_2,&QListWidget::doubleClicked,[=](const QModelIndex &index){
       m_whichChars =  index.row();
       ui->label->setText("当前选中:"+index.data().toString());
    });
    m_discoveryAgent->setLowEnergyDiscoveryTimeout(20000);
    connect(m_discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
            this,SLOT(SlotAddDevicesToList(QBluetoothDeviceInfo)));
    //connect(m_discoveryAgent,SIGNAL(sto()),this)
    connect(m_discoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished,[=](){
        //m_devList = m_discoveryAgent->discoveredDevices();
        //addDevIntoList();
    });
    if(m_socket) // 经典蓝牙才用
    {
        connect(m_socket,SIGNAL(connected()),this,SLOT(SlotBluetoothConnected()));
        connect(m_socket,SIGNAL(disconnected()),this,SLOT(SlotBluetoothDisConnected()));
        connect(m_socket,SIGNAL(readyRead()),this,SLOT(SlotBluetoothReadData()));
    }
    connect(ui->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(SlotItemActivated(QListWidgetItem*)));
     if( m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff )
     {
         ui->openBtn->setEnabled(true);
         ui->closeBtn->setEnabled(false);
     }
     else
     {
         ui->openBtn->setEnabled(false);
         ui->closeBtn->setEnabled(true);
     }

   QString text = "efefefefefefef";
   QByteArray arry = text.toLatin1();
   char buf[124];
   for(int i = 0;i<arry.size();++i)
   {
      sprintf(buf,"%02x",arry.at(i));
   }
   qDebug()<<buf;
}

bluetooth::~bluetooth()
{
    delete ui;
    if(m_discoveryAgent)
    {
        delete m_discoveryAgent;
        m_discoveryAgent = NULL;
    }
    if(m_localDevice)
    {
        delete m_localDevice;
        m_localDevice =NULL;
    }
    if(m_socket)
    {
        delete m_socket;
        m_socket =NULL;
    }
    if(m_controler)
    {
        delete m_controler;
        m_controler= NULL;
    }
   /* if(m_bluetoothServer)
    {
        delete m_bluetoothServer;
        m_bluetoothServer = NULL;
    }*/
}
static const QLatin1String serverUUID("{00007900-0000-1000-8000-00805F9B34FB}");

void bluetooth::searchCharteris()
{
    if(!m_bluetoothServer)
    {
        return;
    }
    QList<QLowEnergyCharacteristic> tmpList  = m_bluetoothServer->characteristics();
    ui->textEditFromSever->append(QString::number(tmpList.size()));
    for(int i = 0;i<tmpList.count();++i)
    {
        QLowEnergyCharacteristic charsrs=tmpList.at(i);
        if(charsrs.isValid())
        {
            QString serT = QString("%1").arg(charsrs.uuid().toString());
            ui->textEditFromSever->append("發現charsrs:"+serT);


            //if(charsrs.properties()&QLowEnergyCharacteristic::WriteNoResponse||charsrs.properties()&QLowEnergyCharacteristic::Write)
            if((charsrs.properties()&QLowEnergyCharacteristic::Write)||(charsrs.properties()&QLowEnergyCharacteristic::WriteNoResponse)||(charsrs.properties()&QLowEnergyCharacteristic::Read))
            {
                ui->textEditFromSever->append("charsrs對象有寫權限!");
                m_writeChars.push_back(charsrs);
                //m_writeChars[i] = charsrs;
                //m_whichChars = i;
                QLowEnergyService::WriteMode tmpMode;
                QString qx;
                if(charsrs.properties()&QLowEnergyCharacteristic::WriteNoResponse)
                {
                    tmpMode =  QLowEnergyService::WriteWithoutResponse;
                    qx = "只写不回应";
                }
                else if(charsrs.properties()&QLowEnergyCharacteristic::Read)
                {
                    tmpMode =  QLowEnergyService::WriteWithResponse;
                    qx = "读";
                }
                else if(charsrs.properties()&QLowEnergyCharacteristic::Write)
                {
                    tmpMode =  QLowEnergyService::WriteWithoutResponse;
                    qx = "写";
                }
                else if(charsrs.properties()&QLowEnergyCharacteristic::Notify)
                {
                    qx = "通知";
                }
                   m_writeMode.push_back(tmpMode);

                   ui->listWidget_2->addItem(serT+" 权限:"+qx);
            }

            if(charsrs.properties()&QLowEnergyCharacteristic::Read)
            {
                m_readChars = charsrs; // 保存讀權限
                ui->textEditFromSever->append("保存讀權限!");
            }
            // 描述符定义特征如何由特定客户端配置
            m_notifiDesc = charsrs.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
            if(m_notifiDesc.isValid())
            {
                // 寫描述符
                m_bluetoothServer->writeDescriptor(m_notifiDesc,QByteArray::fromHex("0100"));
                ui->textEditFromClient->append("寫文件描述符!");
            }
        }
    }
}

void bluetooth::msgSendToServer(QByteArray array)
{
    if(m_bluetoothServer)
    {
        if(m_whichChars == -1)
        {
            return;
        }
       m_bluetoothServer->writeCharacteristic(m_writeChars.at(m_whichChars),array,m_writeMode.at(m_whichChars));
    }
    else
    {
        QMessageBox::critical(this,"致命錯誤","服務為空!");
    }
}
void bluetooth::connectDev(QBluetoothDeviceInfo dev)
{


       m_controler = new QLowEnergyController(dev,this);//QLowEnergyController::createCentral(dev,this);
       if(m_controler == 0)
       {
           ui->textEditFromSever->append("传建中央设备创建失敗!");
          return;
       }
       else
       {
         ui->textEditFromSever->append("传建中央设备创建成功!");
       }



    ui->textEditFromSever->append("正在连接设备!");
    // 發現新服務
    connect(m_controler,&QLowEnergyController::serviceDiscovered,[=](QBluetoothUuid uuid){
        ui->textEditFromSever->append("找到uuid:"+uuid.toString());

    });
    // 發現正在運行的服務
    connect(m_controler,&QLowEnergyController::discoveryFinished,[=](){
        ui->textEditFromSever->append("serviceDiscovered!");
        if(m_bluetoothServer)
        {
            delete m_bluetoothServer;
            m_bluetoothServer = NULL;
        }
        m_bluetoothServer = m_controler->createServiceObject(QBluetoothUuid(serverUUID),this);
        if(!m_bluetoothServer)
        {
          ui->textEditFromSever->append("建立服務失敗!");
          return;
        }
         ui->textEditFromSever->append("建立服務成功!");
         //m_bluetoothServer->discoverDetails(); // 掃描服務
         if(m_bluetoothServer->state() == QLowEnergyService::DiscoveryRequired)
         {
             ui->textEditFromSever->append("手動掃描特徵服務!");
             m_bluetoothServer->discoverDetails(); // 掃描服務
         }
         else
         {   ui->textEditFromSever->append("无法触发手動掃描特徵服務!");
             searchCharteris();
         }
         // 服務綁定
         connect(m_bluetoothServer,&QLowEnergyService::stateChanged,[=](QLowEnergyService::ServiceState state){
           if(state == QLowEnergyService::DiscoveringServices)
           {
             ui->textEditFromSever->append("正在查找細節...");
             //searchCharteris();
           }
           else if(state == QLowEnergyService::ServiceDiscovered)
           {
               ui->textEditFromSever->append("發現所有細節...");
               searchCharteris();
           }
           else
           {
             ui->textEditFromSever->append("沒有發現服務細節!");
           }
           //emit aliveChanged();
         });


         // 讀寫數據綁定
         connect(m_bluetoothServer,&QLowEnergyService::characteristicChanged,[=](QLowEnergyCharacteristic info, QByteArray value){

               QString  text = QString("%1").arg(QString(value.data()));//.arg(info.uuid().toString());
               ui->textEditFromSever_3->append("status change:"+value.toHex());
               //m_bluetoothServer->readCharacteristic(info);

         });
         connect(m_bluetoothServer,&QLowEnergyService::characteristicRead,[=](QLowEnergyCharacteristic info, QByteArray value){
              ui->textEditFromSever_3->append("read:"+QString(value));
         });
         connect(m_bluetoothServer,&QLowEnergyService::characteristicWritten,[=](QLowEnergyCharacteristic info, QByteArray value){

                  ui->textEditFromSever_3->append("write:"+QString(value.data()));
         });

         connect(m_bluetoothServer, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
                 [=](QLowEnergyService::ServiceError newErrorr){
             if(QLowEnergyService::NoError == newErrorr)
             {
                 ui->textEditFromSever->append("没有发生错误");
             }
             if(QLowEnergyService::OperationError==newErrorr)
             {
                 ui->textEditFromSever->append("错误: 当服务没有准备好时尝试进行操作!");
             }
             if(QLowEnergyService::CharacteristicReadError==newErrorr)
             {
                 ui->textEditFromSever->append("尝试读取特征值失败!");
             }
             if(QLowEnergyService::CharacteristicWriteError==newErrorr)
             {
                 ui->textEditFromSever->append("尝试为特性写入新值失败!");
             }
             if(QLowEnergyService::DescriptorReadError==newErrorr)
             {
                 ui->textEditFromSever->append("尝试读取描述符值失败!");
             }
             if(QLowEnergyService::DescriptorWriteError==newErrorr)
             {
                ui->textEditFromSever->append(" 尝试向描述符写入新值失败!");
             }
             if(QLowEnergyService::UnknownError==newErrorr)
             {
                 ui->textEditFromSever->append("与服务交互时发生未知错误!");
             }
         });

    });
    connect(m_controler,&QLowEnergyController::connected,[=](){
        ui->textEditFromSever->append("蓝牙连接成功!");
        m_oneDevHaveConnected = true;
        m_controler->discoverServices();
    });
    connect(m_controler,&QLowEnergyController::disconnected,[=](){
        m_oneDevHaveConnected = false;
        ui->textEditFromSever->append("蓝牙已断开!");
    });
    connect(m_controler,static_cast<void(QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),[=](QLowEnergyController::Error error){
        if(error==QLowEnergyController::NoError)
        {
            ui->textEditFromSever->append("没有发生错误");
        }
        else if(error==QLowEnergyController::UnknownError)
        {
            ui->textEditFromSever->append("出现未知错误");
        }
        else if(error==QLowEnergyController::UnknownRemoteDeviceError)
        {
            ui->textEditFromSever->append("无法找到传递给此类构造函数的远程Bluetooth Low Energy设备");
        }
        else if(error==QLowEnergyController::NetworkError)
        {
            ui->textEditFromSever->append("尝试读取或写入远程设备失败");

        }
        else if(error==QLowEnergyController::InvalidBluetoothAdapterError)
        {
            ui->textEditFromSever->append("传递给此类构造函数的本地蓝牙设备无法找到,或者没有本地蓝牙设备");

        }
        else if(error==QLowEnergyController::InvalidBluetoothAdapterError)
        {
            ui->textEditFromSever->append("尝试连接到远程设备失败");
        }
        else
        {
            ui->textEditFromSever->append("*****未知错误!****");
        }
    });
    m_controler->connectToDevice();

}
void bluetooth::SlotAddDevicesToList(QBluetoothDeviceInfo info)
{
    if(info.coreConfigurations()&QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
    {
        QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());
        QList<QListWidgetItem *> items = ui->listWidget->findItems(label, Qt::MatchExactly);
        if (items.empty())
        {
            QListWidgetItem *item = new QListWidgetItem(label);
            /*QBluetoothLocalDevice::Pairing pairingStatus = m_localDevice->pairingStatus(info.address());
            if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired )
                item->setTextColor(QColor(Qt::green));
            else
                item->setTextColor(QColor(Qt::black));*/

            m_devList.append(info);
            ui->listWidget->addItem(item);
            //connect(ui->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(SlotItemActivated(QListWidgetItem*)));


        }
    }
}

void bluetooth::SlotBluetoothConnected()
{
    emit SigSendto("蓝牙连接成功");
    qDebug() << "The android device has been connected successfully!";
    QMessageBox::information(this,tr("Info"),tr("successful connection!"));
}

void bluetooth::SlotBluetoothDisConnected()
{
    emit SigSendto("蓝牙已断开");
    qDebug() << "The android device has been disconnected successfully!";
    QMessageBox::information(this,tr("msg"),tr("successful disconnection!"));
}

void bluetooth::SlotBluetoothReadData()
{
    if(!m_socket)
    {
        return;
    }
    QByteArray line = m_socket->readAll();
    //QString strData = line.toHex();
    QString strData(line);
    m_vector.append(strData);
    qDebug() <<"rec data is: "<<m_vector;
    qDebug() <<"The comStr length is: " << m_vector.length();
    //if(m_vector.length() >= 30) {

        ui->textEditFromClient->append(m_vector + "\n");
        m_vector.clear();
    //}
}

void bluetooth::SlotItemActivated(QListWidgetItem *item)
{
     //QString address  = item->text().left(17);
    if(m_oneDevHaveConnected)
    {
        return;
    }
    if(m_controler)
    {
       m_controler->disconnectFromDevice();
       delete m_controler;
       m_controler = NULL;
    }
    QBluetoothDeviceInfo dev;
     QString text = item->text();

     int index = text.indexOf(' ');

     if (index == -1)
         return;

     QBluetoothAddress address(text.left(index));
     for(int i = 0;i<m_devList.count();++i)
     {
         if(m_devList.at(i).address().toString()==text.left(index))
         {
            // emit SigChosedDev(m_devList.at(i));
             dev = m_devList.at(i);
             m_discoveryAgent->stop();// 停止搜索
             break;
         }
     }
      connectDev(dev);
    /*QString text = item->text();

    int index = text.indexOf(' ');

    if (index == -1)
        return;

    QBluetoothAddress address(text.left(index));
    QString name(text.mid(index + 1));
    qDebug() << "You has choice the bluetooth address is " << address;
    qDebug() << "The device is connneting.... ";
    QMessageBox::information(this,tr("提示"),tr("设备正在连接z..."));
    //const QString uuid = "00007900-0000-1000-8000-00805F9B34FB";//ui->lineEdit->text();
   //m_socket->connectToService(address, QBluetoothUuid(uuid) ,QIODevice::ReadWrite);

    for(int  i = 0;i
                emit SigSendto("正连接目标");
                m_controler = new QLowEnergyController(dev,this);
                connect(m_controler,&QLowEnergyController::connected,[=](){
                    emit SigSendto("蓝牙连接成功");
                    qDebug() << "The android device has been connected successfully!";
                    QMessageBox::information(this,tr("Info"),tr("successful connection!"));
                    m_controler->discoverServices();
                });
            }
        }
    }



     connect(m_controler,&QLowEnergyController::serviceDiscovered,[=](){

     });*/
}

void bluetooth::on_openBtn_clicked()
{
    m_localDevice->powerOn();
    ui->closeBtn->setEnabled(true);
    ui->openBtn->setEnabled(false);
    ui->scanBtn->setEnabled(true);
}

void bluetooth::on_scanBtn_clicked()
{
    emit SigSendto("蓝牙扫描中");
    if(m_discoveryAgent)
    {
        m_discoveryAgent->start();
        // m_discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
        ui->scanBtn->setEnabled(false);
    }
}

void bluetooth::on_sendBtn_2_clicked()
{
    QString  info  = ui->msgLine->text();
    QString changVol = info;
    ui->msgLine->clear();
    int len = info.size();
    char buf[20];
    sprintf(buf,"%02x",len);
    QString leny = QString::fromUtf8(buf);
    QByteArray ys = leny.toLatin1();
    QString ysstr = QString::fromLatin1(QByteArray::fromHex(ys));
    if(m_whichChange == 1)
    {
      leny = typeIp+ysstr;
    }
    else if(m_whichChange == 2)
    {
      leny = typeYm+ysstr;
    }
    else if(m_whichChange == 3)
    {
      msgSendToServer(changVol.toLatin1());
      return;
    }
    info=leny+info;
    QByteArray array = info.toLatin1();

    /*写入newValue作为特性的值。如果操作成功,将发射characteristicWritten()信号;
    低功耗设备: 每次最多写20个字节
    */
    msgSendToServer(array);
}

void bluetooth::on_clearBtn_clicked()
{
    ui->textEditFromClient->clear();
    ui->textEditFromSever_3->clear();
    ui->textEditFromSever->clear();
}

void bluetooth::on_closeBtn_clicked()
{
    m_localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
    ui->closeBtn->setEnabled(false);
    ui->openBtn->setEnabled(true);
    ui->scanBtn->setEnabled(false);
}

void bluetooth::on_disconnectBtn_clicked()
{
    //emit SigSendto("连接已断开");
    m_oneDevHaveConnected = false;
    ui->textEditFromSever->append("手动断开蓝牙设备!");
    if(m_controler)
    {
        delete m_controler;
        m_controler = NULL;
    }
    //m_socket->disconnectFromService();
}

你可能感兴趣的:(QT)