summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java10
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java30
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java19
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java17
-rw-r--r--src/bluetooth/android/androidutils.cpp24
-rw-r--r--src/bluetooth/android/androidutils_p.h4
-rw-r--r--src/bluetooth/android/jni_android_p.h2
-rw-r--r--src/bluetooth/android/serveracceptancethread.cpp3
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp19
-rw-r--r--src/bluetooth/qbluetoothserver_android.cpp3
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp4
13 files changed, 103 insertions, 44 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java
index c3795b2b..7b163efb 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java
@@ -121,7 +121,15 @@ public class QtBluetoothBroadcastReceiver extends BroadcastReceiver
static public boolean setPairingMode(String address, boolean isPairing)
{
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ if (manager == null)
+ return false;
+
+ BluetoothAdapter adapter = manager.getAdapter();
+ if (adapter == null)
+ return false;
+
// Uses reflection as the removeBond() is not part of public API
try {
BluetoothDevice device = adapter.getRemoteDevice(address);
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java
index 8f0a0f09..9671f11a 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java
@@ -11,6 +11,7 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
@@ -39,7 +40,7 @@ import java.util.UUID;
public class QtBluetoothLE {
private static final String TAG = "QtBluetoothGatt";
- private final BluetoothAdapter mBluetoothAdapter;
+ private BluetoothAdapter mBluetoothAdapter = null;
private boolean mLeScanRunning = false;
private BluetoothGatt mBluetoothGatt = null;
@@ -163,14 +164,23 @@ public class QtBluetoothLE {
Context qtContext = null;
@SuppressWarnings("WeakerAccess")
- public QtBluetoothLE() {
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ public QtBluetoothLE(Context context) {
+ qtContext = context;
+
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ if (manager == null)
+ return;
+
+ mBluetoothAdapter = manager.getAdapter();
+ if (mBluetoothAdapter == null)
+ return;
+
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
public QtBluetoothLE(final String remoteAddress, Context context) {
- this();
- qtContext = context;
+ this(context);
mRemoteGattAddress = remoteAddress;
}
@@ -185,6 +195,11 @@ public class QtBluetoothLE {
if (isEnabled == mLeScanRunning)
return true;
+ if (mBluetoothLeScanner == null) {
+ Log.w(TAG, "Cannot start LE scan, no bluetooth scanner");
+ return false;
+ }
+
if (isEnabled) {
Log.d(TAG, "Attempting to start BTLE scan");
ScanSettings.Builder settingsBuilder = new ScanSettings.Builder();
@@ -682,6 +697,11 @@ public class QtBluetoothLE {
public synchronized boolean connect() {
BluetoothDevice mRemoteGattDevice;
+ if (mBluetoothAdapter == null) {
+ Log.w(TAG, "Cannot connect, no bluetooth adapter");
+ return false;
+ }
+
try {
mRemoteGattDevice = mBluetoothAdapter.getRemoteDevice(mRemoteGattAddress);
} catch (IllegalArgumentException ex) {
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
index e8b4bd1f..f595dec0 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
@@ -43,7 +43,7 @@ public class QtBluetoothLEServer {
private Context qtContext = null;
// Bluetooth members
- private final BluetoothAdapter mBluetoothAdapter;
+ private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothManager mBluetoothManager = null;
private BluetoothGattServer mGattServer = null;
private BluetoothLeAdvertiser mLeAdvertiser = null;
@@ -249,16 +249,21 @@ public class QtBluetoothLEServer {
public QtBluetoothLEServer(Context context)
{
qtContext = context;
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
- if (mBluetoothAdapter == null || qtContext == null) {
- Log.w(TAG, "Missing Bluetooth adapter or Qt context. Peripheral role disabled.");
+ if (qtContext == null) {
+ Log.w(TAG, "Missing context object. Peripheral role disabled.");
return;
}
- mBluetoothManager = (BluetoothManager) qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ mBluetoothManager =
+ (BluetoothManager) qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
- Log.w(TAG, "Bluetooth service not available.");
+ Log.w(TAG, "Bluetooth service not available. Peripheral role disabled.");
+ return;
+ }
+
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ if (mBluetoothAdapter == null) {
+ Log.w(TAG, "Missing Bluetooth adapter. Peripheral role disabled.");
return;
}
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
index 4c470a55..cc78c5d7 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
@@ -5,7 +5,9 @@ package org.qtproject.qt.android.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothSocket;
+import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.util.UUID;
@@ -19,6 +21,8 @@ public class QtBluetoothSocketServer extends Thread
long qtObject = 0;
@SuppressWarnings({"WeakerAccess", "CanBeFinal"})
public boolean logEnabled = false;
+ @SuppressWarnings("WeakerAccess")
+ static Context qtContext = null;
private static final String TAG = "QtBluetooth";
private boolean m_isSecure = false;
@@ -31,8 +35,9 @@ public class QtBluetoothSocketServer extends Thread
private static final int QT_LISTEN_FAILED = 1;
private static final int QT_ACCEPT_FAILED = 2;
- public QtBluetoothSocketServer()
+ public QtBluetoothSocketServer(Context context)
{
+ qtContext = context;
setName("QtSocketServerThread");
}
@@ -46,7 +51,15 @@ public class QtBluetoothSocketServer extends Thread
public void run()
{
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+
+ if (manager == null) {
+ errorOccurred(qtObject, QT_NO_BLUETOOTH_SUPPORTED);
+ return;
+ }
+
+ BluetoothAdapter adapter = manager.getAdapter();
if (adapter == null) {
errorOccurred(qtObject, QT_NO_BLUETOOTH_SUPPORTED);
return;
diff --git a/src/bluetooth/android/androidutils.cpp b/src/bluetooth/android/androidutils.cpp
index b33275b2..7b7c9cc1 100644
--- a/src/bluetooth/android/androidutils.cpp
+++ b/src/bluetooth/android/androidutils.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "androidutils_p.h"
+#include "jni_android_p.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qandroidextras_p.h>
@@ -43,4 +44,27 @@ bool ensureAndroidPermission(BluetoothPermission permission)
return false;
}
+QJniObject getDefaultBluetoothAdapter()
+{
+ QJniObject service = QJniObject::getStaticField<QtJniTypes::AndroidContext, jstring>(
+ "BLUETOOTH_SERVICE");
+ QJniObject context = QNativeInterface::QAndroidApplication::context();
+ QJniObject manager =
+ context.callMethod<jobject>("getSystemService", service.object<jstring>());
+ QJniObject adapter;
+ if (manager.isValid())
+ adapter = manager.callMethod<QtJniTypes::BluetoothAdapter>("getAdapter");
+
+ // ### Qt 7 check if the below double-get of the adapter can be removed.
+ // It is a workaround for QTBUG-57489, fixed in 2016. According to the bug it occurred on
+ // a certain device running Android 6.0.1 (Qt 6 supports Android 6.0 as the minimum).
+ // For completeness: the original workaround was for the deprecated getDefaultAdapter()
+ // method, and it is thus unclear if this is needed even in Qt 6 anymore. In addition the
+ // impacted device is updateable to Android 8 which may also have fixed the issue.
+ if (!adapter.isValid())
+ adapter = manager.callMethod<QtJniTypes::BluetoothAdapter>("getAdapter");
+
+ return adapter;
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/android/androidutils_p.h b/src/bluetooth/android/androidutils_p.h
index a28a0fd5..9912ad38 100644
--- a/src/bluetooth/android/androidutils_p.h
+++ b/src/bluetooth/android/androidutils_p.h
@@ -16,6 +16,7 @@
//
#include <qglobal.h>
+#include <QtCore/QJniObject>
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
@@ -30,6 +31,9 @@ enum class BluetoothPermission {
// Returns true if permission is successfully authorized
bool ensureAndroidPermission(BluetoothPermission permission);
+// Returns the default bluetooth adapter, or an invalid object if not available
+QJniObject getDefaultBluetoothAdapter();
+
QT_END_NAMESPACE
#endif // QANDROIDBLUETOOTHUTILS_H
diff --git a/src/bluetooth/android/jni_android_p.h b/src/bluetooth/android/jni_android_p.h
index d4da9075..e172f637 100644
--- a/src/bluetooth/android/jni_android_p.h
+++ b/src/bluetooth/android/jni_android_p.h
@@ -41,12 +41,14 @@ Q_DECLARE_JNI_CLASS(BluetoothGattDescriptor, "android/bluetooth/BluetoothGattDes
Q_DECLARE_JNI_CLASS(BluetoothGattCharacteristic, "android/bluetooth/BluetoothGattCharacteristic")
Q_DECLARE_JNI_CLASS(BluetoothDevice, "android/bluetooth/BluetoothDevice")
Q_DECLARE_JNI_CLASS(IntentFilter, "android/content/IntentFilter")
+Q_DECLARE_JNI_CLASS(AndroidContext, "android/content/Context")
Q_DECLARE_JNI_CLASS(UUID, "java/util/UUID")
Q_DECLARE_JNI_TYPE(ParcelableArray, "[Landroid/os/Parcelable;")
Q_DECLARE_JNI_TYPE(ParcelUuidArray, "[Landroid/os/ParcelUuid;")
Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;")
+Q_DECLARE_JNI_TYPE(BluetoothManager, "Landroid/bluetooth/BluetoothManager;")
Q_DECLARE_JNI_TYPE(AdvertiseData, "Landroid/bluetooth/le/AdvertiseData;")
Q_DECLARE_JNI_TYPE(AdvertiseSettings, "Landroid/bluetooth/le/AdvertiseSettings;")
Q_DECLARE_JNI_TYPE(InputStream, "Ljava/io/InputStream;")
diff --git a/src/bluetooth/android/serveracceptancethread.cpp b/src/bluetooth/android/serveracceptancethread.cpp
index e9dc06ed..c96fce89 100644
--- a/src/bluetooth/android/serveracceptancethread.cpp
+++ b/src/bluetooth/android/serveracceptancethread.cpp
@@ -73,7 +73,8 @@ void ServerAcceptanceThread::run()
shutdownPendingConnections();
}
- javaThread = QJniObject::construct<QtJniTypes::QtBtSocketServer>();
+ javaThread = QJniObject::construct<QtJniTypes::QtBtSocketServer>(
+ QNativeInterface::QAndroidApplication::context());
if (!javaThread.isValid())
return;
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index 3981954c..cd6327f5 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -33,8 +33,7 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
deviceDiscoveryStartAttemptsLeft(deviceDiscoveryStartMaxAttempts),
q_ptr(parent)
{
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
+ adapter = getDefaultBluetoothAdapter();
if (!adapter.isValid())
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
@@ -419,7 +418,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startLowEnergyScan()
m_active = BtleScanActive;
if (!leScanner.isValid()) {
- leScanner = QJniObject::construct<QtJniTypes::QtBtLECentral>();
+ leScanner = QJniObject::construct<QtJniTypes::QtBtLECentral>(
+ QNativeInterface::QAndroidApplication::context());
if (!leScanner.isValid()) {
qCWarning(QT_BT_ANDROID) << "Cannot load BTLE device scan class";
m_active = NoScanActive;
diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp
index f2415013..ca7faed0 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -46,23 +46,10 @@ QJniObject *QBluetoothLocalDevicePrivate::adapter()
return obj;
}
-static QJniObject getDefaultAdapter()
-{
- QJniObject adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
-
- if (!adapter.isValid()) {
- // on some BT implementations the first call to getDefaultAdapter() may fail
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(),
- "getDefaultAdapter");
- }
- return adapter;
-}
-
void QBluetoothLocalDevicePrivate::initialize(const QBluetoothAddress &address)
{
- QJniObject adapter = getDefaultAdapter();
+ QJniObject adapter = getDefaultBluetoothAdapter();
+
if (!adapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
return;
@@ -309,7 +296,7 @@ QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
// Android only supports max of one device (so far)
QList<QBluetoothHostInfo> localDevices;
- QJniObject o = getDefaultAdapter();
+ QJniObject o = getDefaultBluetoothAdapter();
if (o.isValid()) {
QBluetoothHostInfo info;
info.setName(o.callMethod<jstring>("getName").toString());
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp
index 221bf0f3..3449542b 100644
--- a/src/bluetooth/qbluetoothserver_android.cpp
+++ b/src/bluetooth/qbluetoothserver_android.cpp
@@ -132,8 +132,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por
return false;
//check Bluetooth is available and online
- QJniObject btAdapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
+ QJniObject btAdapter = getDefaultBluetoothAdapter();
if (!btAdapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index e3fa662b..f160eb75 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -58,10 +58,8 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
The logic below must change once there is more than one adapter.
*/
- if (createAdapter) {
- btAdapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
- }
+ if (createAdapter)
+ btAdapter = getDefaultBluetoothAdapter();
if (!btAdapter.isValid())
qCWarning(QT_BT_ANDROID) << "Platform does not support Bluetooth";
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index b1f90822..754f223d 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -143,9 +143,7 @@ QBluetoothSocketPrivateAndroid::QBluetoothSocketPrivateAndroid()
inputThread(0)
{
secFlags = QBluetooth::Security::Secure;
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
-
+ adapter = getDefaultBluetoothAdapter();
qRegisterMetaType<QBluetoothSocket::SocketError>();
qRegisterMetaType<QBluetoothSocket::SocketState>();
}