-
Bug
-
Resolution: Done
-
P1: Critical
-
5.3.2
-
None
-
Android 4.0.3, HTC Sensation
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.