Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. My Qt Android Bluetooth code is not working for an Android-13 device when using Qt5.12.3

My Qt Android Bluetooth code is not working for an Android-13 device when using Qt5.12.3

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
3 Posts 2 Posters 107 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    ZINE
    wrote on 10 Apr 2025, 18:54 last edited by
    #1

    Hi,

    I have a Qt Android-based code that scan BLE devices and display them on a widget. My code works well when it runs on a Android-8 device (API-level 26) using Qt5.12.3, jdk1.8.0_211, NDK 19.2.5345600 and SDK target=26.
    When compiling the code for an Android-13 device (API-level 33), the application is not able to find and display BLE devices. I am also using Qt5.12.3, NDK 19.2.5345600 and SDK target=28 which is the highest SDK supported in my Qt. I also included all required permissions in the manifest.xml file:
    android.permission.ACCESS_COARSE_LOCATION
    android.permission.ACCESS_FINE_LOCATION
    android.permission.BLUETOOTH
    android.permission.BLUETOOTH_ADMIN
    android.permission.BLUETOOTH_CONNECT
    android.permission.BLUETOOTH_SCAN

    Here is the output when using the Android-13 device but without correctly finding and displaying BLE devices:
    58f91f4e-343b-47ec-8ede-01b46dd729f2-BLE_scan.PNG

    I faced same issue when testing heartrate-game example from Qt: Android-8 device successfully detects nearby BLE devices while Android-13 device could not.

    Therefore, is this issue related to the used Qt version and/or the target SDK ? i.e., should I use more recent Qt version (like Qt5.15) and higher target SDK (level 33) ? I prefer to work with Qt5 since it supports .pro files which I am currently using.

    Here are the main parts of my code:
    #include <QtAndroid>
    #include <QAndroidJniObject>

    void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
    {
    qDebug() << "[BLE] Raw: " << device.name() << device.address().toString();

    if(device.coreConfigurations()&QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
    {
        qDebug() << "Discovered:" << device.name() << device.address().toString();
    
    if(BLE_liste->findItems(device.name()+"\n"+device.address().toString(),Qt::MatchExactly).count()==0)
        {
    BLE_liste->addItem(device.name()+"\n"+device.address().toString());
      *dev_info=device;
    QBluetoothDeviceInfo* temp_info=new QBluetoothDeviceInfo;
    *temp_info=device;
    dev_info_list.append(temp_info);
    }
    }
    

    }

    void MainWindow::searchCharacteristic()
    {
    if(BLE_service){
    foreach (QLowEnergyCharacteristic c, BLE_service->characteristics()) {
    if(c.isValid()){
    if (c.properties() & QLowEnergyCharacteristic::WriteNoResponse ||
    c.properties() & QLowEnergyCharacteristic::Write) {
    m_writeCharacteristic = c;
    if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
    m_writeMode = QLowEnergyService::WriteWithoutResponse;
    else
    m_writeMode = QLowEnergyService::WriteWithResponse;
    }
    if (c.properties() & QLowEnergyCharacteristic::Read)
    m_readCharacteristic = c;

                if(c.properties() & QLowEnergyCharacteristic::Notify)
                {
                m_notificationDesc = c.descriptor(
                            QBluetoothUuid::ClientCharacteristicConfiguration);
                if (m_notificationDesc.isValid())
                {
                BLE_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
                }
                }
            }
        }
    }
    

    }

    void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
    {
    string = item->text();

    string = string.split("\n").at(0); //get the 1st word in string
    
    *dev_info=*(dev_info_list.at(BLE_liste->row(item)));
    BLE_controlleur=new QLowEnergyController(*dev_info,this);
    

    connect(BLE_controlleur, SIGNAL(connected()),this,SLOT(device_connected()));
    connect(BLE_controlleur, SIGNAL(discoveryFinished()),this,SLOT(service_discovered()));
    BLE_controlleur->connectToDevice();

    }

    void MainWindow::device_connected()
    {
    BLE_controlleur->discoverServices();
    }

    void MainWindow::service_discovered()
    {
    services_discovered=1;
    m_servicesUuid = BLE_controlleur->services();

    int maxl=m_servicesUuid.length();
    for(int i=0;i<maxl;i++)
    {
    
        if(m_servicesUuid.at(i).toString()=="{6e400001-b5a3-f393-e0a9-e50e24dcca9e}")
        {
        BLE_service= BLE_controlleur->createServiceObject(m_servicesUuid.at(i), this);
        connect(BLE_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
        this, SLOT(onServiceStateChanged(QLowEnergyService::ServiceState)));
        connect(BLE_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)),
                this, SLOT(update_com_state_(QLowEnergyCharacteristic,QByteArray)));
        connect(BLE_service, SIGNAL(error(QLowEnergyService::ServiceError)),
                this, SLOT(error_slot(QLowEnergyService::ServiceError)));
        connect(Comm_timer, SIGNAL(timeout()),this, SLOT(update_com_state()));
        if(BLE_service->state() == QLowEnergyService::DiscoveryRequired)
        {
          BLE_service->discoverDetails();
         }
         else
        searchCharacteristic();
    
        BLE_liste->setStyleSheet("QListWidget{background-color: rgba(0,0,0,0);color:rgb(202,233,250);font-weight:bold;font-family:Myriad Pro Regular;font-size:64px;border:4px solid rgb(249,159,65);border-radius:12px;} QListWidget::item:selected{background:rgb(249,159,65);color:rgb(0,0,0);}");
    
        }
    
    }
    

    }

    void MainWindow::onServiceStateChanged(QLowEnergyService::ServiceState s)
    {
    if (s == QLowEnergyService::ServiceDiscovered)
    {
    searchCharacteristic();
    }
    }

    void MainWindow::BLE_search_slot()
    {
    if(agent!=nullptr)
    {
    delete agent;
    }

    if(ble_widget->isHidden()==false)
    {
    if(localDevice.hostMode()==QBluetoothLocalDevice::HostPoweredOff)
    {localDevice.powerOn();
        QTimer::singleShot(2000, this, SLOT(BLE_search_slot()));
    }
    BLE_liste->clear();
    dev_info_list.clear();
    
    QtAndroid::requestPermissionsSync({
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.BLUETOOTH_SCAN",
        "android.permission.BLUETOOTH_CONNECT"
    });
    
        agent = new QBluetoothDeviceDiscoveryAgent(); // create an object in ctors
        connect(agent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
        agent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
    
    
    
    }
    

    }

    jsulmJ 1 Reply Last reply 11 Apr 2025, 05:22
    0
    • Z ZINE
      10 Apr 2025, 18:54

      Hi,

      I have a Qt Android-based code that scan BLE devices and display them on a widget. My code works well when it runs on a Android-8 device (API-level 26) using Qt5.12.3, jdk1.8.0_211, NDK 19.2.5345600 and SDK target=26.
      When compiling the code for an Android-13 device (API-level 33), the application is not able to find and display BLE devices. I am also using Qt5.12.3, NDK 19.2.5345600 and SDK target=28 which is the highest SDK supported in my Qt. I also included all required permissions in the manifest.xml file:
      android.permission.ACCESS_COARSE_LOCATION
      android.permission.ACCESS_FINE_LOCATION
      android.permission.BLUETOOTH
      android.permission.BLUETOOTH_ADMIN
      android.permission.BLUETOOTH_CONNECT
      android.permission.BLUETOOTH_SCAN

      Here is the output when using the Android-13 device but without correctly finding and displaying BLE devices:
      58f91f4e-343b-47ec-8ede-01b46dd729f2-BLE_scan.PNG

      I faced same issue when testing heartrate-game example from Qt: Android-8 device successfully detects nearby BLE devices while Android-13 device could not.

      Therefore, is this issue related to the used Qt version and/or the target SDK ? i.e., should I use more recent Qt version (like Qt5.15) and higher target SDK (level 33) ? I prefer to work with Qt5 since it supports .pro files which I am currently using.

      Here are the main parts of my code:
      #include <QtAndroid>
      #include <QAndroidJniObject>

      void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
      {
      qDebug() << "[BLE] Raw: " << device.name() << device.address().toString();

      if(device.coreConfigurations()&QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
      {
          qDebug() << "Discovered:" << device.name() << device.address().toString();
      
      if(BLE_liste->findItems(device.name()+"\n"+device.address().toString(),Qt::MatchExactly).count()==0)
          {
      BLE_liste->addItem(device.name()+"\n"+device.address().toString());
        *dev_info=device;
      QBluetoothDeviceInfo* temp_info=new QBluetoothDeviceInfo;
      *temp_info=device;
      dev_info_list.append(temp_info);
      }
      }
      

      }

      void MainWindow::searchCharacteristic()
      {
      if(BLE_service){
      foreach (QLowEnergyCharacteristic c, BLE_service->characteristics()) {
      if(c.isValid()){
      if (c.properties() & QLowEnergyCharacteristic::WriteNoResponse ||
      c.properties() & QLowEnergyCharacteristic::Write) {
      m_writeCharacteristic = c;
      if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
      m_writeMode = QLowEnergyService::WriteWithoutResponse;
      else
      m_writeMode = QLowEnergyService::WriteWithResponse;
      }
      if (c.properties() & QLowEnergyCharacteristic::Read)
      m_readCharacteristic = c;

                  if(c.properties() & QLowEnergyCharacteristic::Notify)
                  {
                  m_notificationDesc = c.descriptor(
                              QBluetoothUuid::ClientCharacteristicConfiguration);
                  if (m_notificationDesc.isValid())
                  {
                  BLE_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
                  }
                  }
              }
          }
      }
      

      }

      void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
      {
      string = item->text();

      string = string.split("\n").at(0); //get the 1st word in string
      
      *dev_info=*(dev_info_list.at(BLE_liste->row(item)));
      BLE_controlleur=new QLowEnergyController(*dev_info,this);
      

      connect(BLE_controlleur, SIGNAL(connected()),this,SLOT(device_connected()));
      connect(BLE_controlleur, SIGNAL(discoveryFinished()),this,SLOT(service_discovered()));
      BLE_controlleur->connectToDevice();

      }

      void MainWindow::device_connected()
      {
      BLE_controlleur->discoverServices();
      }

      void MainWindow::service_discovered()
      {
      services_discovered=1;
      m_servicesUuid = BLE_controlleur->services();

      int maxl=m_servicesUuid.length();
      for(int i=0;i<maxl;i++)
      {
      
          if(m_servicesUuid.at(i).toString()=="{6e400001-b5a3-f393-e0a9-e50e24dcca9e}")
          {
          BLE_service= BLE_controlleur->createServiceObject(m_servicesUuid.at(i), this);
          connect(BLE_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
          this, SLOT(onServiceStateChanged(QLowEnergyService::ServiceState)));
          connect(BLE_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)),
                  this, SLOT(update_com_state_(QLowEnergyCharacteristic,QByteArray)));
          connect(BLE_service, SIGNAL(error(QLowEnergyService::ServiceError)),
                  this, SLOT(error_slot(QLowEnergyService::ServiceError)));
          connect(Comm_timer, SIGNAL(timeout()),this, SLOT(update_com_state()));
          if(BLE_service->state() == QLowEnergyService::DiscoveryRequired)
          {
            BLE_service->discoverDetails();
           }
           else
          searchCharacteristic();
      
          BLE_liste->setStyleSheet("QListWidget{background-color: rgba(0,0,0,0);color:rgb(202,233,250);font-weight:bold;font-family:Myriad Pro Regular;font-size:64px;border:4px solid rgb(249,159,65);border-radius:12px;} QListWidget::item:selected{background:rgb(249,159,65);color:rgb(0,0,0);}");
      
          }
      
      }
      

      }

      void MainWindow::onServiceStateChanged(QLowEnergyService::ServiceState s)
      {
      if (s == QLowEnergyService::ServiceDiscovered)
      {
      searchCharacteristic();
      }
      }

      void MainWindow::BLE_search_slot()
      {
      if(agent!=nullptr)
      {
      delete agent;
      }

      if(ble_widget->isHidden()==false)
      {
      if(localDevice.hostMode()==QBluetoothLocalDevice::HostPoweredOff)
      {localDevice.powerOn();
          QTimer::singleShot(2000, this, SLOT(BLE_search_slot()));
      }
      BLE_liste->clear();
      dev_info_list.clear();
      
      QtAndroid::requestPermissionsSync({
          "android.permission.ACCESS_FINE_LOCATION",
          "android.permission.BLUETOOTH_SCAN",
          "android.permission.BLUETOOTH_CONNECT"
      });
      
          agent = new QBluetoothDeviceDiscoveryAgent(); // create an object in ctors
          connect(agent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
          agent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
      
      
      
      }
      

      }

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on 11 Apr 2025, 05:22 last edited by
      #2

      @ZINE Please format your code properly.
      For newer Android devices you should also use newer Qt version, 5.12.3 is quite old already and I doubt it officially supports Android 13 (see https://doc.qt.io/archives/qt-5.12/android.html).

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • Z Offline
        Z Offline
        ZINE
        wrote on 11 Apr 2025, 10:19 last edited by ZINE 4 Nov 2025, 10:20
        #3

        @jsulm Thanks for the feedback. I think that at least Qt5.15 is required to supports Android 13 (see https://medium.com/@shmilysyg/set-android-target-sdk-level-33-in-qt-38bb9049924c). I prefer using Qt5.15.2 since I am using .pro files. Also, I suppose that I need higher JDK and NDK versions.

        While I do not think that the issue is related to the code (I tested Qt example and did not work), here is my formatted code:

          void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
         {
        qDebug() << "[BLE] Raw: " << device.name() << device.address().toString();
        
        if(device.coreConfigurations()&QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
        {
            qDebug() << "Discovered:" << device.name() << device.address().toString();
        
        if(BLE_liste->findItems(device.name()+"\n"+device.address().toString(),Qt::MatchExactly).count()==0)
            {
        BLE_liste->addItem(device.name()+"\n"+device.address().toString());
          *dev_info=device;
        QBluetoothDeviceInfo* temp_info=new QBluetoothDeviceInfo;
        *temp_info=device;
        dev_info_list.append(temp_info);
        }
        }
        }
        
        
        
         void MainWindow::searchCharacteristic()
        {
        if(BLE_service){
            foreach (QLowEnergyCharacteristic c, BLE_service->characteristics()) {
                if(c.isValid()){
                    if (c.properties() & QLowEnergyCharacteristic::WriteNoResponse ||
                        c.properties() & QLowEnergyCharacteristic::Write) {
                        m_writeCharacteristic = c;
                        if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
                           m_writeMode = QLowEnergyService::WriteWithoutResponse;
                        else
                            m_writeMode = QLowEnergyService::WriteWithResponse;
                    }
                    if (c.properties() & QLowEnergyCharacteristic::Read)
                        m_readCharacteristic = c;
        
                    if(c.properties() & QLowEnergyCharacteristic::Notify)
                    {
                    m_notificationDesc = c.descriptor(
                                QBluetoothUuid::ClientCharacteristicConfiguration);
                    if (m_notificationDesc.isValid())
                    {
                    BLE_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
                    }
                    }
                    }
                    }
                   }
                   }
        
        
            void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
            {
           string = item->text();
        
         string = string.split("\n").at(0); //get the 1st word in string
        
        *dev_info=*(dev_info_list.at(BLE_liste->row(item)));
         BLE_controlleur=new QLowEnergyController(*dev_info,this);
         connect(BLE_controlleur, SIGNAL(connected()),this,SLOT(device_connected()));
        connect(BLE_controlleur, SIGNAL(discoveryFinished()),this,SLOT(service_discovered()));
        BLE_controlleur->connectToDevice();
        
        }
        
        
         void MainWindow::device_connected()
        {
         BLE_controlleur->discoverServices();
        }
        
         void MainWindow::service_discovered()
        {
        services_discovered=1;
        m_servicesUuid = BLE_controlleur->services();
        
        int maxl=m_servicesUuid.length();
        for(int i=0;i<maxl;i++)
        {
        
            if(m_servicesUuid.at(i).toString()=="{6e400001-b5a3-f393-e0a9-e50e24dcca9e}")
            {
            BLE_service= BLE_controlleur->createServiceObject(m_servicesUuid.at(i), this);
            connect(BLE_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
            this, SLOT(onServiceStateChanged(QLowEnergyService::ServiceState)));
            connect(BLE_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)),
                    this, SLOT(update_com_state_(QLowEnergyCharacteristic,QByteArray)));
            connect(BLE_service, SIGNAL(error(QLowEnergyService::ServiceError)),
                    this, SLOT(error_slot(QLowEnergyService::ServiceError)));
            connect(Comm_timer, SIGNAL(timeout()),this, SLOT(update_com_state()));
            if(BLE_service->state() == QLowEnergyService::DiscoveryRequired)
            {
              BLE_service->discoverDetails();
             }
             else
            searchCharacteristic();
        
            BLE_liste->setStyleSheet("QListWidget{background-color: rgba(0,0,0,0);color:rgb(202,233,250);font-weight:bold;font-family:Myriad Pro Regular;font-size:64px;border:4px solid rgb(249,159,65);border-radius:12px;} QListWidget::item:selected{background:rgb(249,159,65);color:rgb(0,0,0);}");
        
            }
        
        }
        
        }
        
        void MainWindow::onServiceStateChanged(QLowEnergyService::ServiceState s)
        {
        if (s == QLowEnergyService::ServiceDiscovered)
        {
            searchCharacteristic();
        }
        }
        
        void MainWindow::BLE_search_slot()
        {
        if(agent!=nullptr)
        {
        delete agent;
        }
        
        if(ble_widget->isHidden()==false)
        {
        if(localDevice.hostMode()==QBluetoothLocalDevice::HostPoweredOff)
        {localDevice.powerOn();
            QTimer::singleShot(2000, this, SLOT(BLE_search_slot()));
        }
        BLE_liste->clear();
        dev_info_list.clear();
        
        QtAndroid::requestPermissionsSync({
            "android.permission.ACCESS_FINE_LOCATION",
            "android.permission.BLUETOOTH_SCAN",
            "android.permission.BLUETOOTH_CONNECT"
        });
        
            agent = new QBluetoothDeviceDiscoveryAgent(); // create an object in ctors
            connect(agent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
            agent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
        
        }
        }
        
        1 Reply Last reply
        0

        1/3

        10 Apr 2025, 18:54

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved