Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.3.2
-
None
-
Android 4.0.3, HTC Sensation
Description
In my code I simply wanted to get the Bluetooth name of the device using:
QBluetoothLocalDevice btDev;
However, on the HTC sensation phone the constructor of QBluetoothLocalDevice already crashes with the following message:
W/dalvikvm(14544): Invalid indirect reference 0x40e2ace8 in decodeIndirectRef
E/dalvikvm(14544): VM aborting
F/libc (14544): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)
To see where it really crashes, I copied the code from QBluetoothLocalDevicePrivate::initialize() into my app and added some debug output after each step.
So the code is this:
QAndroidJniEnvironment env; qWarning() << "QT_XXXX 1"; jclass btAdapterClass = env->FindClass("android/bluetooth/BluetoothAdapter"); if (btAdapterClass == NULL) { qWarning() << "Native registration unable to find class android/bluetooth/BluetoothAdapter"; } else { jmethodID getDefaultAdapterID = env->GetStaticMethodID(btAdapterClass, "getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;"); qWarning() << "QT_XXXX 2"; if (getDefaultAdapterID == NULL) { qWarning() << "Native registration unable to get method ID: getDefaultAdapter of android/bluetooth/BluetoothAdapter"; } else { jobject btAdapterObject = env->CallStaticObjectMethod(btAdapterClass, getDefaultAdapterID); qWarning() << "QT_XXXX 3"; if (btAdapterObject == NULL) { qWarning() << "Device does not support Bluetooth"; env->DeleteLocalRef(btAdapterClass); } else { obj = QAndroidJniObject(btAdapterObject); qWarning() << "QT_XXXX 4"; if (!obj.isValid()) { } else { QBluetoothAddress address; qWarning() << "QT_XXXX 5"; if (!address.isNull()) { const QString localAddress = obj.callObjectMethod("getAddress", "()Ljava/lang/String;").toString(); qWarning() << "QT_XXXX 6"; //if (localAddress != address.toString()) { //passed address not local one -> invalid //} } } env->DeleteLocalRef(btAdapterObject); qWarning() << "QT_XXXX 7"; env->DeleteLocalRef(btAdapterClass); qWarning() << "QT_XXXX 8"; } } }
and the debug log on the device is mainly just printing
W/Qt (14544): ... QT_XXXX 1
W/Qt (14544): ... QT_XXXX 2
W/Qt (14544): ... QT_XXXX 3
W/dalvikvm(14544): Invalid indirect reference 0x40e2ace8 in decodeIndirectRef
Further testing shows, that the call to BluetoothAdapter.getDefaultAdapter();
throws an exception:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
When I call
obj = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
"getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
then the obj is not valid - but at least it does not crash.
So I think a modification of the QBluetoothLocalDevice ctor would be good to use the above code and does not crash.