Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Problem to use QAndroidJniObject (as a part of QBluetoothDeviceDiscoveryAgent) as a .SO library in native Android App.



  • I am writing the code to make able to get android Bluetooth connection via QT library using JNI. The main idea is to have a black box that connects to devices to get data, analyze and so on, that is why I need to use QT Bluetooth to do not pass device data from Java code to lib.

    So, the library should use QBluetoothDeviceDiscoveryAgent to find devices, get data and so on. And there are some issue when it is used as library not in QT.

    In my application I load all libraries and jars and use JNI wrapper to call C++ code from QT .so lib, and there are no problems, I have tested threads, and some other code, and it works.

    So I have tried to find the problem with Bluetooth part.
    At first, I used JNIEnv* env to check if I can get a Bluetooth adapter, and it works. Then I used QAndroidJniEnvironment and also got Bluetooth adapter name. Look at the code, please. (that code are in lib and I call it from Java).

      static jclass jniMathClassID = 0;
      static jmethodID jniMathConstructorMethodID = 0;
      static jmethodID jniMathElevenMethodID = 0;
    
      QAndroidJniEnvironment qjniEnv;
    
      jclass classBta = qjniEnv->FindClass("android/bluetooth/BluetoothAdapter");
    
      jmethodID methodIdGetAdapter =
                    qjniEnv->GetStaticMethodID(classBta,
                                           "getDefaultAdapter",
                                           "()Landroid/bluetooth/BluetoothAdapter;");
      jmethodID methodIdGetName =
                    qjniEnv->GetMethodID(classBta,
                                     "getName",
                                     "()Ljava/lang/String;");
    
      jobject objBta = (jobject) qjniEnv->CallStaticObjectMethod(classBta, methodIdGetAdapter);
    
      jstring strName = (jstring) qjniEnv->CallObjectMethod(objBta, methodIdGetName);
    
      const char *result = qjniEnv->GetStringUTFChars(strName, 0);
      qDebug() << "Adapter name "<< result;
    

    So, here I can see the real device Bluetooth adapter name which was received via QAndroidJniEnvironment.

    The issue happens when I want to use QBluetoothDeviceDiscoveryAgent. I got a message: qt.bluetooth.android: Device does not support Bluetooth

    I have looked at the "qbluetoothdevicediscoveryagent_android.cpp" file and saw that in the constructor it uses QAndroidJniObject.

    Here is a code from constructor (I have tested this code separately):

    QAndroidJniEnvironment env;
        adapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
                                                            "getDefaultAdapter",
                                                            "()Landroid/bluetooth/BluetoothAdapter;");
    

    and it has nothing in the adapter variable, but if I call that QAndroidJniObject::callStaticObjectMethod in my own method and change "android/bluetooth/BluetoothAdapter" to classBta (which you saw above) It works ok.

    QAndroidJniObject adapter=QAndroidJniObject::callStaticObjectMethod( classBta, "getDefaultAdapter", 
    "()Landroid/bluetooth/BluetoothAdapter;");
    

    So, I don't undarstand why, but the QAndroidJniObject doesn't find classes by String name like "android/bluetooth/BluetoothAdapter".
    Because of this the QBluetoothDeviceDiscoveryAgent doesn't work, it uses QAndroidJniObject inside.

    Could you please help me with this? I really need to make QBluetoothDeviceDiscoveryAgent work in library via Java.

    P. S.
    Bluetooth and androidextras are included in .pro file.



  • @Gor-Ivanov I got exactly the same issue. Does anyone here have the solution? Thanks!


Log in to reply