diff --git a/FastBleLib/build.gradle b/FastBleLib/build.gradle index 121159d..8179918 100644 --- a/FastBleLib/build.gradle +++ b/FastBleLib/build.gradle @@ -16,6 +16,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { diff --git a/FastBleLib/src/main/AndroidManifest.xml b/FastBleLib/src/main/AndroidManifest.xml index 3d3bdeb..a9c4c06 100644 --- a/FastBleLib/src/main/AndroidManifest.xml +++ b/FastBleLib/src/main/AndroidManifest.xml @@ -1,9 +1,42 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastBleLib/src/main/java/com/clj/fastble/BleManager.java b/FastBleLib/src/main/java/com/clj/fastble/BleManager.java index b37f7bb..3458391 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/BleManager.java +++ b/FastBleLib/src/main/java/com/clj/fastble/BleManager.java @@ -1,5 +1,6 @@ package com.clj.fastble; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Application; import android.bluetooth.BluetoothAdapter; @@ -381,8 +382,8 @@ public BluetoothGatt connect(String mac, BleGattCallback bleGattCallback) { /** * Cancel scan */ - public void cancelScan() { - BleScanner.getInstance().stopLeScan(); + public void cancelScan(boolean isCallbackScanFinish) { + BleScanner.getInstance().stopLeScan(isCallbackScanFinish); } /** @@ -746,13 +747,13 @@ public boolean requestConnectionPriority(BleDevice bleDevice, int connectionPrio * @return */ public boolean isSupportBle() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 - && context.getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); + return context.getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); } /** * Open bluetooth */ + @SuppressLint("MissingPermission") public void enableBluetooth() { if (bluetoothAdapter != null) { bluetoothAdapter.enable(); @@ -848,6 +849,13 @@ public void removeNotifyCallback(BleDevice bleDevice, String uuid_notify) { bleBluetooth.removeNotifyCallback(uuid_notify); } + public boolean isHasNotifyCallback(BleDevice bleDevice, String uuid_notify) { + BleBluetooth bleBluetooth = getBleBluetooth(bleDevice); + if (bleBluetooth != null) + return bleBluetooth.isHasNotifyCallback(uuid_notify); + return false; + } + public void removeIndicateCallback(BleDevice bleDevice, String uuid_indicate) { BleBluetooth bleBluetooth = getBleBluetooth(bleDevice); if (bleBluetooth != null) @@ -914,6 +922,14 @@ public boolean isConnected(String mac) { return false; } + public boolean isConnected() { + List list = getAllConnectedDevice(); + if (list != null && list.size() > 0) { + return true; + } + return false; + } + public void disconnect(BleDevice bleDevice) { if (multipleBluetoothController != null) { multipleBluetoothController.disconnect(bleDevice); @@ -926,9 +942,9 @@ public void disconnectAllDevice() { } } - public void destroy() { + public void destroy(String mac) { if (multipleBluetoothController != null) { - multipleBluetoothController.destroy(); + multipleBluetoothController.destroy(mac); } } diff --git a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleBluetooth.java b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleBluetooth.java index 8c13ff4..87faeaf 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleBluetooth.java +++ b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleBluetooth.java @@ -1,5 +1,6 @@ package com.clj.fastble.bluetooth; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; @@ -30,7 +31,6 @@ import java.lang.reflect.Method; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import static android.bluetooth.BluetoothDevice.TRANSPORT_LE; @@ -38,202 +38,207 @@ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class BleBluetooth { - private BleGattCallback bleGattCallback; - private BleRssiCallback bleRssiCallback; + private BleGattCallback mBleGattCallback; + private BleRssiCallback mBleRssiCallback; private BleMtuChangedCallback bleMtuChangedCallback; + private final HashMap bleNotifyCallbackHashMap = new HashMap<>(); private final HashMap bleIndicateCallbackHashMap = new HashMap<>(); private final HashMap bleWriteCallbackHashMap = new HashMap<>(); private final HashMap bleReadCallbackHashMap = new HashMap<>(); - private LastState lastState; + private LastState mLastState; private boolean isActiveDisconnect = false; - private final BleDevice bleDevice; - private BluetoothGatt bluetoothGatt; - private final MainHandler mainHandler = new MainHandler(Looper.getMainLooper()); - private int connectRetryCount = 0; + private final BleDevice mBleDevice; + private BluetoothGatt mBluetoothGatt; + private final MainHandler mMainHandler = new MainHandler(Looper.getMainLooper()); + private final BleManager mBleManager = BleManager.getInstance(); + private BleConnector mBleConnector; public BleBluetooth(BleDevice bleDevice) { - this.bleDevice = bleDevice; + this.mBleDevice = bleDevice; } public BleConnector newBleConnector() { - return new BleConnector(this); + if (mBleConnector != null) { + return mBleConnector; + } + return mBleConnector = new BleConnector(this); } - public synchronized void addConnectGattCallback(BleGattCallback callback) { - bleGattCallback = callback; + public void addConnectGattCallback(BleGattCallback callback) { + mBleGattCallback = callback; } - public synchronized void removeConnectGattCallback() { - bleGattCallback = null; + public void removeConnectGattCallback() { + mBleGattCallback = null; + } + + public void removeBleConnector() { + if (mBleConnector != null) { + mBleConnector.removeCallbacksAndMessages(); + mBleConnector = null; + } } - public synchronized void addNotifyCallback(String uuid, BleNotifyCallback bleNotifyCallback) { + public void addNotifyCallback(String uuid, BleNotifyCallback bleNotifyCallback) { bleNotifyCallbackHashMap.put(uuid, bleNotifyCallback); } - public synchronized void addIndicateCallback(String uuid, BleIndicateCallback bleIndicateCallback) { + public void addIndicateCallback(String uuid, BleIndicateCallback bleIndicateCallback) { bleIndicateCallbackHashMap.put(uuid, bleIndicateCallback); } - public synchronized void addWriteCallback(String uuid, BleWriteCallback bleWriteCallback) { + public void addWriteCallback(String uuid, BleWriteCallback bleWriteCallback) { bleWriteCallbackHashMap.put(uuid, bleWriteCallback); } - public synchronized void addReadCallback(String uuid, BleReadCallback bleReadCallback) { + public void addReadCallback(String uuid, BleReadCallback bleReadCallback) { bleReadCallbackHashMap.put(uuid, bleReadCallback); } - public synchronized void removeNotifyCallback(String uuid) { - if (bleNotifyCallbackHashMap.containsKey(uuid)) - bleNotifyCallbackHashMap.remove(uuid); + public void removeNotifyCallback(String uuid) { + bleNotifyCallbackHashMap.remove(uuid); } - public synchronized void removeIndicateCallback(String uuid) { - if (bleIndicateCallbackHashMap.containsKey(uuid)) - bleIndicateCallbackHashMap.remove(uuid); + public boolean isHasNotifyCallback(String uuid) { + return bleNotifyCallbackHashMap.containsKey(uuid); } - public synchronized void removeWriteCallback(String uuid) { - if (bleWriteCallbackHashMap.containsKey(uuid)) - bleWriteCallbackHashMap.remove(uuid); + public void removeIndicateCallback(String uuid) { + bleIndicateCallbackHashMap.remove(uuid); } - public synchronized void removeReadCallback(String uuid) { - if (bleReadCallbackHashMap.containsKey(uuid)) - bleReadCallbackHashMap.remove(uuid); + public void removeWriteCallback(String uuid) { + bleWriteCallbackHashMap.remove(uuid); } - public synchronized void clearCharacterCallback() { + public void removeReadCallback(String uuid) { + bleReadCallbackHashMap.remove(uuid); + } + + public void clearCharacterCallback() { bleNotifyCallbackHashMap.clear(); bleIndicateCallbackHashMap.clear(); bleWriteCallbackHashMap.clear(); bleReadCallbackHashMap.clear(); } - public synchronized void addRssiCallback(BleRssiCallback callback) { - bleRssiCallback = callback; + public void addRssiCallback(BleRssiCallback callback) { + mBleRssiCallback = callback; } - public synchronized void removeRssiCallback() { - bleRssiCallback = null; + public void removeRssiCallback() { + mBleRssiCallback = null; } - public synchronized void addMtuChangedCallback(BleMtuChangedCallback callback) { + public void addMtuChangedCallback(BleMtuChangedCallback callback) { bleMtuChangedCallback = callback; } - public synchronized void removeMtuChangedCallback() { + public void removeMtuChangedCallback() { bleMtuChangedCallback = null; } public String getDeviceKey() { - return bleDevice.getKey(); + return mBleDevice.getKey(); } public BleDevice getDevice() { - return bleDevice; + return mBleDevice; } public BluetoothGatt getBluetoothGatt() { - return bluetoothGatt; - } - - public synchronized BluetoothGatt connect(BleDevice bleDevice, - boolean autoConnect, - BleGattCallback callback) { - return connect(bleDevice, autoConnect, callback, 0); + return mBluetoothGatt; } - public synchronized BluetoothGatt connect(BleDevice bleDevice, - boolean autoConnect, - BleGattCallback callback, - int connectRetryCount) { - BleLog.i("connect device: " + bleDevice.getName() - + "\nmac: " + bleDevice.getMac() - + "\nautoConnect: " + autoConnect - + "\ncurrentThread: " + Thread.currentThread().getId() - + "\nconnectCount:" + (connectRetryCount + 1)); - if (connectRetryCount == 0) { - this.connectRetryCount = 0; + @SuppressLint("MissingPermission") + public BluetoothGatt connect(BleDevice bleDevice, + boolean autoConnect, + BleGattCallback callback) { + synchronized (this) { + BleLog.i("connect device: " + bleDevice.getName() + + "\nmac: " + bleDevice.getMac() + + "\nautoConnect: " + autoConnect + + "\ncurrentThread: " + Thread.currentThread().getId()); + addConnectGattCallback(callback); + + mLastState = LastState.CONNECT_CONNECTING; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mBluetoothGatt = bleDevice.getDevice().connectGatt(mBleManager.getContext(), + autoConnect, coreGattCallback, TRANSPORT_LE); + } else { + mBluetoothGatt = bleDevice.getDevice().connectGatt(mBleManager.getContext(), + autoConnect, coreGattCallback); + } + if (mBluetoothGatt != null) { + if (mBleGattCallback != null) { + mBleGattCallback.onStartConnect(); + } + Message message = mMainHandler.obtainMessage(); + message.what = BleMsg.MSG_CONNECT_OVER_TIME; + mMainHandler.sendMessageDelayed(message, mBleManager.getConnectOverTime()); + } else { + disconnect(); + mLastState = LastState.CONNECT_FAILURE; + mBleManager.getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); + if (mBleGattCallback != null) + mBleGattCallback.onConnectFail(bleDevice, new OtherException("GATT connect exception occurred!")); + } + return mBluetoothGatt; } + } - addConnectGattCallback(callback); - - lastState = LastState.CONNECT_CONNECTING; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - bluetoothGatt = bleDevice.getDevice().connectGatt(BleManager.getInstance().getContext(), - autoConnect, coreGattCallback, TRANSPORT_LE); - } else { - bluetoothGatt = bleDevice.getDevice().connectGatt(BleManager.getInstance().getContext(), - autoConnect, coreGattCallback); + public void destroy() { + synchronized (this) { + BleLog.i("--------Ble: destroy()--------"); + clearCharacterCallback(); + removeConnectGattCallback(); + removeRssiCallback(); + removeMtuChangedCallback(); + disconnect(); + mLastState = LastState.CONNECT_IDLE; + mMainHandler.removeCallbacksAndMessages(null); } - if (bluetoothGatt != null) { - if (bleGattCallback != null) { - bleGattCallback.onStartConnect(); - } - Message message = mainHandler.obtainMessage(); - message.what = BleMsg.MSG_CONNECT_OVER_TIME; - mainHandler.sendMessageDelayed(message, BleManager.getInstance().getConnectOverTime()); + } - } else { + public void disconnect() { + synchronized (this) { + BleLog.d("--------disconnect()-----"); + removeBleConnector(); disconnectGatt(); refreshDeviceCache(); - closeBluetoothGatt(); - lastState = LastState.CONNECT_FAILURE; - BleManager.getInstance().getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); - if (bleGattCallback != null) - bleGattCallback.onConnectFail(bleDevice, new OtherException("GATT connect exception occurred!")); - } - return bluetoothGatt; } - public synchronized void disconnect() { + @SuppressLint("MissingPermission") + private void disconnectGatt() { isActiveDisconnect = true; - disconnectGatt(); - } - - public synchronized void destroy() { - lastState = LastState.CONNECT_IDLE; - disconnectGatt(); - refreshDeviceCache(); - closeBluetoothGatt(); - removeConnectGattCallback(); - removeRssiCallback(); - removeMtuChangedCallback(); - clearCharacterCallback(); - mainHandler.removeCallbacksAndMessages(null); - } - - private synchronized void disconnectGatt() { - if (bluetoothGatt != null) { - bluetoothGatt.disconnect(); + if (mBluetoothGatt != null) { + mBluetoothGatt.disconnect(); + mBluetoothGatt.close(); + mBluetoothGatt = null; } } - private synchronized void refreshDeviceCache() { - try { - final Method refresh = BluetoothGatt.class.getMethod("refresh"); - if (refresh != null && bluetoothGatt != null) { - boolean success = (Boolean) refresh.invoke(bluetoothGatt); - BleLog.i("refreshDeviceCache, is success: " + success); + public void refreshDeviceCache() { + synchronized (this) { + try { + final Method refresh = BluetoothGatt.class.getMethod("refresh"); + if (refresh != null && mBluetoothGatt != null) { + boolean success = (Boolean) refresh.invoke(mBluetoothGatt); + BleLog.i("refreshDeviceCache, is success: " + success); + } + } catch (Exception e) { + BleLog.i("exception occur while refreshing device: " + e.getMessage()); + e.printStackTrace(); } - } catch (Exception e) { - BleLog.i("exception occur while refreshing device: " + e.getMessage()); - e.printStackTrace(); - } - } - - private synchronized void closeBluetoothGatt() { - if (bluetoothGatt != null) { - bluetoothGatt.close(); } } + @SuppressLint("MissingPermission") private final class MainHandler extends Handler { MainHandler(Looper looper) { @@ -244,110 +249,72 @@ private final class MainHandler extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case BleMsg.MSG_CONNECT_FAIL: { - disconnectGatt(); - refreshDeviceCache(); - closeBluetoothGatt(); - - if (connectRetryCount < BleManager.getInstance().getReConnectCount()) { - BleLog.e("Connect fail, try reconnect " + BleManager.getInstance().getReConnectInterval() + " millisecond later"); - ++connectRetryCount; - - Message message = mainHandler.obtainMessage(); - message.what = BleMsg.MSG_RECONNECT; - mainHandler.sendMessageDelayed(message, BleManager.getInstance().getReConnectInterval()); - } else { - lastState = LastState.CONNECT_FAILURE; - BleManager.getInstance().getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); + disconnect(); + mLastState = LastState.CONNECT_FAILURE; + mBleManager.getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); - BleConnectStateParameter para = (BleConnectStateParameter) msg.obj; - int status = para.getStatus(); - if (bleGattCallback != null) - bleGattCallback.onConnectFail(bleDevice, new ConnectException(bluetoothGatt, status)); - } + BleConnectStateParameter para = (BleConnectStateParameter) msg.obj; + int status = para.getStatus(); + BleGattCallback bleGattCallback = mBleGattCallback; + mBleGattCallback = null; + if (bleGattCallback != null) + bleGattCallback.onConnectFail(mBleDevice, new ConnectException(mBluetoothGatt, status)); } break; case BleMsg.MSG_DISCONNECTED: { - lastState = LastState.CONNECT_DISCONNECT; - BleManager.getInstance().getMultipleBluetoothController().removeBleBluetooth(BleBluetooth.this); - disconnect(); - refreshDeviceCache(); - closeBluetoothGatt(); - removeRssiCallback(); - removeMtuChangedCallback(); - clearCharacterCallback(); - mainHandler.removeCallbacksAndMessages(null); + mLastState = LastState.CONNECT_DISCONNECT; + mBleManager.getMultipleBluetoothController().removeBleBluetooth(BleBluetooth.this); BleConnectStateParameter para = (BleConnectStateParameter) msg.obj; boolean isActive = para.isActive(); int status = para.getStatus(); - if (bleGattCallback != null) - bleGattCallback.onDisConnected(isActive, bleDevice, bluetoothGatt, status); - } - break; - case BleMsg.MSG_RECONNECT: { - connect(bleDevice, false, bleGattCallback, connectRetryCount); + clearCharacterCallback(); + removeRssiCallback(); + removeMtuChangedCallback(); + BleGattCallback bleGattCallback = mBleGattCallback; + mBleGattCallback = null; + if (bleGattCallback != null) + bleGattCallback.onDisConnected(isActive, mBleDevice, mBluetoothGatt, status); } break; - case BleMsg.MSG_CONNECT_OVER_TIME: { - disconnectGatt(); - refreshDeviceCache(); - closeBluetoothGatt(); - - lastState = LastState.CONNECT_FAILURE; - BleManager.getInstance().getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); - + disconnect(); + mLastState = LastState.CONNECT_FAILURE; + mBleManager.getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); + BleGattCallback bleGattCallback = mBleGattCallback; + mBleGattCallback = null; if (bleGattCallback != null) - bleGattCallback.onConnectFail(bleDevice, new TimeoutException()); + bleGattCallback.onConnectFail(mBleDevice, new TimeoutException()); } break; case BleMsg.MSG_DISCOVER_SERVICES: { - if (bluetoothGatt != null) { - boolean discoverServiceResult = bluetoothGatt.discoverServices(); + if (mBluetoothGatt != null) { + boolean discoverServiceResult = mBluetoothGatt.discoverServices(); if (!discoverServiceResult) { - Message message = mainHandler.obtainMessage(); + Message message = mMainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCOVER_FAIL; - mainHandler.sendMessage(message); + mMainHandler.sendMessage(message); } } else { - Message message = mainHandler.obtainMessage(); + Message message = mMainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCOVER_FAIL; - mainHandler.sendMessage(message); + mMainHandler.sendMessage(message); } } break; case BleMsg.MSG_DISCOVER_FAIL: { - disconnectGatt(); - refreshDeviceCache(); - closeBluetoothGatt(); - - lastState = LastState.CONNECT_FAILURE; - BleManager.getInstance().getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); - - if (bleGattCallback != null) - bleGattCallback.onConnectFail(bleDevice, - new OtherException("GATT discover services exception occurred!")); + discoverFail(); } break; - case BleMsg.MSG_DISCOVER_SUCCESS: { - lastState = LastState.CONNECT_CONNECTED; - isActiveDisconnect = false; - BleManager.getInstance().getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); - BleManager.getInstance().getMultipleBluetoothController().addBleBluetooth(BleBluetooth.this); - - BleConnectStateParameter para = (BleConnectStateParameter) msg.obj; - int status = para.getStatus(); - if (bleGattCallback != null) - bleGattCallback.onConnectSuccess(bleDevice, bluetoothGatt, status); + discoverSuccess(msg); } break; - default: super.handleMessage(msg); break; @@ -355,7 +322,28 @@ public void handleMessage(Message msg) { } } - private BluetoothGattCallback coreGattCallback = new BluetoothGattCallback() { + private void discoverSuccess(Message msg) { + mLastState = LastState.CONNECT_CONNECTED; + isActiveDisconnect = false; + mBleManager.getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); + mBleManager.getMultipleBluetoothController().addBleBluetooth(BleBluetooth.this); + + BleConnectStateParameter para = (BleConnectStateParameter) msg.obj; + int status = para.getStatus(); + if (mBleGattCallback != null) + mBleGattCallback.onConnectSuccess(mBleDevice, mBluetoothGatt, status); + } + + private void discoverFail() { + disconnect(); + mLastState = LastState.CONNECT_FAILURE; + mBleManager.getMultipleBluetoothController().removeConnectingBle(BleBluetooth.this); + + if (mBleGattCallback != null) + mBleGattCallback.onConnectFail(mBleDevice, new OtherException("GATT discover services exception occurred!")); + } + + private final BluetoothGattCallback coreGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { @@ -365,29 +353,28 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState + '\n' + "newState: " + newState + '\n' + "currentThread: " + Thread.currentThread().getId()); - bluetoothGatt = gatt; + mBluetoothGatt = gatt; - mainHandler.removeMessages(BleMsg.MSG_CONNECT_OVER_TIME); + mMainHandler.removeMessages(BleMsg.MSG_CONNECT_OVER_TIME); if (newState == BluetoothProfile.STATE_CONNECTED) { - Message message = mainHandler.obtainMessage(); + Message message = mMainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCOVER_SERVICES; - mainHandler.sendMessageDelayed(message, 500); + mMainHandler.sendMessageDelayed(message, 0); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - if (lastState == LastState.CONNECT_CONNECTING) { - Message message = mainHandler.obtainMessage(); + if (mLastState == LastState.CONNECT_CONNECTING) { + Message message = mMainHandler.obtainMessage(); message.what = BleMsg.MSG_CONNECT_FAIL; message.obj = new BleConnectStateParameter(status); - mainHandler.sendMessage(message); - - } else if (lastState == LastState.CONNECT_CONNECTED) { - Message message = mainHandler.obtainMessage(); + mMainHandler.sendMessage(message); + } else if (mLastState == LastState.CONNECT_CONNECTED) { + Message message = mMainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCONNECTED; BleConnectStateParameter para = new BleConnectStateParameter(status); para.setActive(isActiveDisconnect); message.obj = para; - mainHandler.sendMessage(message); + mMainHandler.sendMessage(message); } } } @@ -399,31 +386,25 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) { + '\n' + "status: " + status + '\n' + "currentThread: " + Thread.currentThread().getId()); - bluetoothGatt = gatt; + mBluetoothGatt = gatt; + mMainHandler.removeMessages(BleMsg.MSG_CONNECT_OVER_TIME); + Message message = mMainHandler.obtainMessage(); if (status == BluetoothGatt.GATT_SUCCESS) { - Message message = mainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCOVER_SUCCESS; message.obj = new BleConnectStateParameter(status); - mainHandler.sendMessage(message); - } else { - Message message = mainHandler.obtainMessage(); message.what = BleMsg.MSG_DISCOVER_FAIL; - mainHandler.sendMessage(message); } + mMainHandler.sendMessage(message); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); - - Iterator iterator = bleNotifyCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleNotifyCallback) { - BleNotifyCallback bleNotifyCallback = (BleNotifyCallback) callback; + for (Map.Entry entry : bleNotifyCallbackHashMap.entrySet()) { + BleNotifyCallback bleNotifyCallback = entry.getValue(); + if (bleNotifyCallback != null) { if (characteristic.getUuid().toString().equalsIgnoreCase(bleNotifyCallback.getKey())) { Handler handler = bleNotifyCallback.getHandler(); if (handler != null) { @@ -439,12 +420,9 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris } } - iterator = bleIndicateCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleIndicateCallback) { - BleIndicateCallback bleIndicateCallback = (BleIndicateCallback) callback; + for (Map.Entry entry : bleIndicateCallbackHashMap.entrySet()) { + BleIndicateCallback bleIndicateCallback = entry.getValue(); + if (bleIndicateCallback != null) { if (characteristic.getUuid().toString().equalsIgnoreCase(bleIndicateCallback.getKey())) { Handler handler = bleIndicateCallback.getHandler(); if (handler != null) { @@ -465,12 +443,9 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { super.onDescriptorWrite(gatt, descriptor, status); - Iterator iterator = bleNotifyCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleNotifyCallback) { - BleNotifyCallback bleNotifyCallback = (BleNotifyCallback) callback; + for (Map.Entry entry : bleNotifyCallbackHashMap.entrySet()) { + BleNotifyCallback bleNotifyCallback = entry.getValue(); + if (bleNotifyCallback != null) { if (descriptor.getCharacteristic().getUuid().toString().equalsIgnoreCase(bleNotifyCallback.getKey())) { Handler handler = bleNotifyCallback.getHandler(); if (handler != null) { @@ -486,12 +461,9 @@ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descri } } - iterator = bleIndicateCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleIndicateCallback) { - BleIndicateCallback bleIndicateCallback = (BleIndicateCallback) callback; + for (Map.Entry entry : bleIndicateCallbackHashMap.entrySet()) { + BleIndicateCallback bleIndicateCallback = entry.getValue(); + if (bleIndicateCallback != null) { if (descriptor.getCharacteristic().getUuid().toString().equalsIgnoreCase(bleIndicateCallback.getKey())) { Handler handler = bleIndicateCallback.getHandler(); if (handler != null) { @@ -511,13 +483,9 @@ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descri @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); - - Iterator iterator = bleWriteCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleWriteCallback) { - BleWriteCallback bleWriteCallback = (BleWriteCallback) callback; + for (Map.Entry entry : bleWriteCallbackHashMap.entrySet()) { + BleWriteCallback bleWriteCallback = entry.getValue(); + if (bleWriteCallback != null) { if (characteristic.getUuid().toString().equalsIgnoreCase(bleWriteCallback.getKey())) { Handler handler = bleWriteCallback.getHandler(); if (handler != null) { @@ -538,13 +506,9 @@ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristi @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); - - Iterator iterator = bleReadCallbackHashMap.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - Object callback = entry.getValue(); - if (callback instanceof BleReadCallback) { - BleReadCallback bleReadCallback = (BleReadCallback) callback; + for (Map.Entry entry : bleReadCallbackHashMap.entrySet()) { + BleReadCallback bleReadCallback = entry.getValue(); + if (bleReadCallback != null) { if (characteristic.getUuid().toString().equalsIgnoreCase(bleReadCallback.getKey())) { Handler handler = bleReadCallback.getHandler(); if (handler != null) { @@ -566,12 +530,12 @@ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { super.onReadRemoteRssi(gatt, rssi, status); - if (bleRssiCallback != null) { - Handler handler = bleRssiCallback.getHandler(); + if (mBleRssiCallback != null) { + Handler handler = mBleRssiCallback.getHandler(); if (handler != null) { Message message = handler.obtainMessage(); message.what = BleMsg.MSG_READ_RSSI_RESULT; - message.obj = bleRssiCallback; + message.obj = mBleRssiCallback; Bundle bundle = new Bundle(); bundle.putInt(BleMsg.KEY_READ_RSSI_BUNDLE_STATUS, status); bundle.putInt(BleMsg.KEY_READ_RSSI_BUNDLE_VALUE, rssi); diff --git a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleConnector.java b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleConnector.java index 13f29c2..aef23d1 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleConnector.java +++ b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/BleConnector.java @@ -1,6 +1,7 @@ package com.clj.fastble.bluetooth; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -213,7 +214,6 @@ public void handleMessage(Message msg) { } } }; - } private BleConnector withUUID(UUID serviceUUID, UUID characteristicUUID) { @@ -247,7 +247,7 @@ public void enableCharacteristicNotify(BleNotifyCallback bleNotifyCallback, Stri && (mCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { handleCharacteristicNotifyCallback(bleNotifyCallback, uuid_notify); - setCharacteristicNotification(mBluetoothGatt, mCharacteristic, userCharacteristicDescriptor, true, bleNotifyCallback); + setCharacteristicNotification(mBluetoothGatt, mCharacteristic, userCharacteristicDescriptor, true, bleNotifyCallback, uuid_notify); } else { if (bleNotifyCallback != null) bleNotifyCallback.onNotifyFailure(new OtherException("this characteristic not support notify!")); @@ -261,7 +261,7 @@ public boolean disableCharacteristicNotify(boolean useCharacteristicDescriptor) if (mCharacteristic != null && (mCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { return setCharacteristicNotification(mBluetoothGatt, mCharacteristic, - useCharacteristicDescriptor, false, null); + useCharacteristicDescriptor, false, null, null); } else { return false; } @@ -270,13 +270,16 @@ public boolean disableCharacteristicNotify(boolean useCharacteristicDescriptor) /** * notify setting */ + @SuppressLint("MissingPermission") private boolean setCharacteristicNotification(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, boolean useCharacteristicDescriptor, boolean enable, - BleNotifyCallback bleNotifyCallback) { + BleNotifyCallback bleNotifyCallback, + String uuid_notify) { if (gatt == null || characteristic == null) { notifyMsgInit(); + mBleBluetooth.removeNotifyCallback(uuid_notify); if (bleNotifyCallback != null) bleNotifyCallback.onNotifyFailure(new OtherException("gatt or characteristic equal null")); return false; @@ -285,6 +288,7 @@ private boolean setCharacteristicNotification(BluetoothGatt gatt, boolean success1 = gatt.setCharacteristicNotification(characteristic, enable); if (!success1) { notifyMsgInit(); + mBleBluetooth.removeNotifyCallback(uuid_notify); if (bleNotifyCallback != null) bleNotifyCallback.onNotifyFailure(new OtherException("gatt setCharacteristicNotification fail")); return false; @@ -347,6 +351,7 @@ public boolean disableCharacteristicIndicate(boolean userCharacteristicDescripto /** * indicate setting */ + @SuppressLint("MissingPermission") private boolean setCharacteristicIndication(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, boolean useCharacteristicDescriptor, @@ -394,6 +399,7 @@ private boolean setCharacteristicIndication(BluetoothGatt gatt, /** * write */ + @SuppressLint("MissingPermission") public void writeCharacteristic(byte[] data, BleWriteCallback bleWriteCallback, String uuid_write) { if (data == null || data.length <= 0) { if (bleWriteCallback != null) @@ -424,6 +430,7 @@ public void writeCharacteristic(byte[] data, BleWriteCallback bleWriteCallback, /** * read */ + @SuppressLint("MissingPermission") public void readCharacteristic(BleReadCallback bleReadCallback, String uuid_read) { if (mCharacteristic != null && (mCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) > 0) { @@ -443,6 +450,7 @@ public void readCharacteristic(BleReadCallback bleReadCallback, String uuid_read /** * rssi */ + @SuppressLint("MissingPermission") public void readRemoteRssi(BleRssiCallback bleRssiCallback) { handleRSSIReadCallback(bleRssiCallback); if (!mBluetoothGatt.readRemoteRssi()) { @@ -455,6 +463,7 @@ public void readRemoteRssi(BleRssiCallback bleRssiCallback) { /** * set mtu */ + @SuppressLint("MissingPermission") public void setMtu(int requiredMtu, BleMtuChangedCallback bleMtuChangedCallback) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { handleSetMtuCallback(bleMtuChangedCallback); @@ -479,6 +488,7 @@ public void setMtu(int requiredMtu, BleMtuChangedCallback bleMtuChangedCallback) * @throws IllegalArgumentException If the parameters are outside of their * specified range. */ + @SuppressLint("MissingPermission") public boolean requestConnectionPriority(int connectionPriority) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return mBluetoothGatt.requestConnectionPriority(connectionPriority); @@ -605,4 +615,14 @@ public void mtuChangedMsgInit() { mHandler.removeMessages(BleMsg.MSG_SET_MTU_START); } + public void removeCallbacksAndMessages() { + if (null != mHandler) + mHandler.removeCallbacksAndMessages(null); + mBluetoothGatt = null; + mGattService = null; + mCharacteristic = null; + mBleBluetooth = null; + mHandler = null; + } + } diff --git a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/MultipleBluetoothController.java b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/MultipleBluetoothController.java index 2f8fe6d..3d03593 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/bluetooth/MultipleBluetoothController.java +++ b/FastBleLib/src/main/java/com/clj/fastble/bluetooth/MultipleBluetoothController.java @@ -1,6 +1,7 @@ package com.clj.fastble.bluetooth; +import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.os.Build; @@ -25,112 +26,132 @@ public MultipleBluetoothController() { bleTempHashMap = new HashMap<>(); } - public synchronized BleBluetooth buildConnectingBle(BleDevice bleDevice) { - BleBluetooth bleBluetooth = new BleBluetooth(bleDevice); - if (!bleTempHashMap.containsKey(bleBluetooth.getDeviceKey())) { - bleTempHashMap.put(bleBluetooth.getDeviceKey(), bleBluetooth); + public BleBluetooth buildConnectingBle(BleDevice bleDevice) { + synchronized (this) { + if (!bleTempHashMap.containsKey(bleDevice.getKey())) { + BleBluetooth bleBluetooth = new BleBluetooth(bleDevice); + bleTempHashMap.put(bleDevice.getKey(), bleBluetooth); + return bleBluetooth; + } + return bleTempHashMap.get(bleDevice.getKey()); } - return bleBluetooth; } - public synchronized void removeConnectingBle(BleBluetooth bleBluetooth) { - if (bleBluetooth == null) { - return; - } - if (bleTempHashMap.containsKey(bleBluetooth.getDeviceKey())) { + public void removeConnectingBle(BleBluetooth bleBluetooth) { + synchronized (this) { + if (bleBluetooth == null) { + return; + } bleTempHashMap.remove(bleBluetooth.getDeviceKey()); } } - public synchronized void addBleBluetooth(BleBluetooth bleBluetooth) { - if (bleBluetooth == null) { - return; - } - if (!bleLruHashMap.containsKey(bleBluetooth.getDeviceKey())) { + public void addBleBluetooth(BleBluetooth bleBluetooth) { + synchronized (this) { + if (bleBluetooth == null) { + return; + } + if (bleLruHashMap.containsKey(bleBluetooth.getDeviceKey())) { + return; + } bleLruHashMap.put(bleBluetooth.getDeviceKey(), bleBluetooth); } } - public synchronized void removeBleBluetooth(BleBluetooth bleBluetooth) { - if (bleBluetooth == null) { - return; - } - if (bleLruHashMap.containsKey(bleBluetooth.getDeviceKey())) { + public void removeBleBluetooth(BleBluetooth bleBluetooth) { + synchronized (this) { + if (bleBluetooth == null) { + return; + } bleLruHashMap.remove(bleBluetooth.getDeviceKey()); } } - public synchronized boolean isContainDevice(BleDevice bleDevice) { + public boolean isContainDevice(BleDevice bleDevice) { return bleDevice != null && bleLruHashMap.containsKey(bleDevice.getKey()); } - public synchronized boolean isContainDevice(BluetoothDevice bluetoothDevice) { + @SuppressLint("MissingPermission") + public boolean isContainDevice(BluetoothDevice bluetoothDevice) { return bluetoothDevice != null && bleLruHashMap.containsKey(bluetoothDevice.getName() + bluetoothDevice.getAddress()); } - public synchronized BleBluetooth getBleBluetooth(BleDevice bleDevice) { - if (bleDevice != null) { - if (bleLruHashMap.containsKey(bleDevice.getKey())) { + public BleBluetooth getBleBluetooth(BleDevice bleDevice) { + synchronized (this) { + if (bleDevice != null) { return bleLruHashMap.get(bleDevice.getKey()); } + return null; } - return null; } - public synchronized void disconnect(BleDevice bleDevice) { - if (isContainDevice(bleDevice)) { - getBleBluetooth(bleDevice).disconnect(); - } + public void disconnect(BleDevice bleDevice) { + getBleBluetooth(bleDevice).disconnect(); } - public synchronized void disconnectAllDevice() { - for (Map.Entry stringBleBluetoothEntry : bleLruHashMap.entrySet()) { - stringBleBluetoothEntry.getValue().disconnect(); + public void disconnectAllDevice() { + synchronized (this) { + for (Map.Entry stringBleBluetoothEntry : bleLruHashMap.entrySet()) { + stringBleBluetoothEntry.getValue().disconnect(); + } + bleLruHashMap.clear(); } - bleLruHashMap.clear(); } - public synchronized void destroy() { - for (Map.Entry stringBleBluetoothEntry : bleLruHashMap.entrySet()) { - stringBleBluetoothEntry.getValue().destroy(); - } - bleLruHashMap.clear(); - for (Map.Entry stringBleBluetoothEntry : bleTempHashMap.entrySet()) { - stringBleBluetoothEntry.getValue().destroy(); + public void destroy(String mac) { + synchronized (this) { + for (Map.Entry stringBleBluetoothEntry : bleLruHashMap.entrySet()) { + if (mac != null) { + if (stringBleBluetoothEntry.getValue().getDevice().getMac().equals(mac)) { + stringBleBluetoothEntry.getValue().destroy(); + bleLruHashMap.remove(stringBleBluetoothEntry.getKey()); + } + } else { + stringBleBluetoothEntry.getValue().destroy(); + bleLruHashMap.remove(stringBleBluetoothEntry.getKey()); + } + } + for (Map.Entry stringBleBluetoothEntry : bleTempHashMap.entrySet()) { + if (mac != null) { + if (stringBleBluetoothEntry.getValue().getDevice().getMac().equals(mac)) { + stringBleBluetoothEntry.getValue().destroy(); + bleTempHashMap.remove(stringBleBluetoothEntry.getKey()); + } + } else { + stringBleBluetoothEntry.getValue().destroy(); + bleTempHashMap.remove(stringBleBluetoothEntry.getKey()); + } + } } - bleTempHashMap.clear(); } - public synchronized List getBleBluetoothList() { - List bleBluetoothList = new ArrayList<>(bleLruHashMap.values()); - Collections.sort(bleBluetoothList, new Comparator() { - @Override - public int compare(BleBluetooth lhs, BleBluetooth rhs) { - return lhs.getDeviceKey().compareToIgnoreCase(rhs.getDeviceKey()); - } - }); - return bleBluetoothList; + public List getBleBluetoothList() { + synchronized (this) { + List bleBluetoothList = new ArrayList<>(bleLruHashMap.values()); + Collections.sort(bleBluetoothList, (lhs, rhs) -> lhs.getDeviceKey().compareToIgnoreCase(rhs.getDeviceKey())); + return bleBluetoothList; + } } - public synchronized List getDeviceList() { - refreshConnectedDevice(); - List deviceList = new ArrayList<>(); - for (BleBluetooth BleBluetooth : getBleBluetoothList()) { - if (BleBluetooth != null) { - deviceList.add(BleBluetooth.getDevice()); + public List getDeviceList() { + synchronized (this) { + refreshConnectedDevice(); + List deviceList = new ArrayList<>(); + for (BleBluetooth BleBluetooth : getBleBluetoothList()) { + if (BleBluetooth != null) { + deviceList.add(BleBluetooth.getDevice()); + } } + return deviceList; } - return deviceList; } public void refreshConnectedDevice() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - List bluetoothList = getBleBluetoothList(); - for (int i = 0; bluetoothList != null && i < bluetoothList.size(); i++) { - BleBluetooth bleBluetooth = bluetoothList.get(i); - if (!BleManager.getInstance().isConnected(bleBluetooth.getDevice())) { - removeBleBluetooth(bleBluetooth); - } + List bluetoothList = getBleBluetoothList(); + for (int i = 0; bluetoothList != null && i < bluetoothList.size(); i++) { + BleBluetooth bleBluetooth = bluetoothList.get(i); + if (!BleManager.getInstance().isConnected(bleBluetooth.getDevice())) { + removeBleBluetooth(bleBluetooth); } } } diff --git a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanAndConnectCallback.java b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanAndConnectCallback.java index 9e0b08b..fe4ddaa 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanAndConnectCallback.java +++ b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanAndConnectCallback.java @@ -3,7 +3,7 @@ import com.clj.fastble.data.BleDevice; -public abstract class BleScanAndConnectCallback extends BleGattCallback implements BleScanPresenterImp { +public abstract class BleScanAndConnectCallback extends BleGattCallback implements BleScanListener { public abstract void onScanFinished(BleDevice scanResult); diff --git a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanCallback.java b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanCallback.java index cf8c2b8..59acd6f 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanCallback.java +++ b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanCallback.java @@ -5,7 +5,7 @@ import java.util.List; -public abstract class BleScanCallback implements BleScanPresenterImp { +public abstract class BleScanCallback implements BleScanListener { public abstract void onScanFinished(List scanResultList); diff --git a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanPresenterImp.java b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanListener.java similarity index 80% rename from FastBleLib/src/main/java/com/clj/fastble/callback/BleScanPresenterImp.java rename to FastBleLib/src/main/java/com/clj/fastble/callback/BleScanListener.java index 03cc2b5..bf10671 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanPresenterImp.java +++ b/FastBleLib/src/main/java/com/clj/fastble/callback/BleScanListener.java @@ -2,7 +2,7 @@ import com.clj.fastble.data.BleDevice; -public interface BleScanPresenterImp { +public interface BleScanListener { void onScanStarted(boolean success); diff --git a/FastBleLib/src/main/java/com/clj/fastble/data/BleDevice.java b/FastBleLib/src/main/java/com/clj/fastble/data/BleDevice.java index 03fcd0e..6e15d4a 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/data/BleDevice.java +++ b/FastBleLib/src/main/java/com/clj/fastble/data/BleDevice.java @@ -1,10 +1,13 @@ package com.clj.fastble.data; +import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + public class BleDevice implements Parcelable { @@ -56,6 +59,7 @@ public BleDevice[] newArray(int size) { } }; + @SuppressLint("MissingPermission") public String getName() { if (mDevice != null) { return mDevice.getName(); @@ -70,6 +74,20 @@ public String getMac() { return null; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BleDevice bleDevice = (BleDevice) o; + return mDevice.getAddress().equals(bleDevice.getMac()); + } + + @Override + public int hashCode() { + return Objects.hash(mDevice); + } + + @SuppressLint("MissingPermission") public String getKey() { if (mDevice != null) { return mDevice.getName() + mDevice.getAddress(); diff --git a/FastBleLib/src/main/java/com/clj/fastble/data/BleMsg.java b/FastBleLib/src/main/java/com/clj/fastble/data/BleMsg.java index c7b533c..323de11 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/data/BleMsg.java +++ b/FastBleLib/src/main/java/com/clj/fastble/data/BleMsg.java @@ -10,7 +10,7 @@ public class BleMsg { // Connect public static final int MSG_CONNECT_FAIL = 0x01; public static final int MSG_DISCONNECTED = 0x02; - public static final int MSG_RECONNECT = 0x03; +// public static final int MSG_RECONNECT = 0x03; public static final int MSG_DISCOVER_SERVICES = 0x04; public static final int MSG_DISCOVER_FAIL = 0x05; public static final int MSG_DISCOVER_SUCCESS = 0x06; diff --git a/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanPresenter.java b/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanPresenter.java index c788a5e..79b7cb8 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanPresenter.java +++ b/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanPresenter.java @@ -11,7 +11,7 @@ import android.os.Message; import android.text.TextUtils; -import com.clj.fastble.callback.BleScanPresenterImp; +import com.clj.fastble.callback.BleScanListener; import com.clj.fastble.data.BleDevice; import com.clj.fastble.data.BleMsg; import com.clj.fastble.utils.BleLog; @@ -30,83 +30,44 @@ public abstract class BleScanPresenter implements BluetoothAdapter.LeScanCallbac private boolean mFuzzy; private boolean mNeedConnect; private long mScanTimeout; - private BleScanPresenterImp mBleScanPresenterImp; + private BleScanListener mBleScanListener; private final List mBleDeviceList = new ArrayList<>(); - private final Handler mMainHandler = new Handler(Looper.getMainLooper()); - private HandlerThread mHandlerThread; - private Handler mHandler; - private boolean mHandling; - - private static final class ScanHandler extends Handler { - - private final WeakReference mBleScanPresenter; - - ScanHandler(Looper looper, BleScanPresenter bleScanPresenter) { - super(looper); - mBleScanPresenter = new WeakReference<>(bleScanPresenter); - } - - @Override - public void handleMessage(Message msg) { - BleScanPresenter bleScanPresenter = mBleScanPresenter.get(); - if (bleScanPresenter != null) { - if (msg.what == BleMsg.MSG_SCAN_DEVICE) { - final BleDevice bleDevice = (BleDevice) msg.obj; - if (bleDevice != null) { - bleScanPresenter.handleResult(bleDevice); - } - } - } - } - } + final Handler mMainHandler = new Handler(Looper.getMainLooper()); private void handleResult(final BleDevice bleDevice) { - mMainHandler.post(new Runnable() { - @Override - public void run() { - onLeScan(bleDevice); - } - }); + onLeScan(bleDevice); checkDevice(bleDevice); } public void prepare(String[] names, String mac, boolean fuzzy, boolean needConnect, - long timeOut, BleScanPresenterImp bleScanPresenterImp) { + long timeOut, BleScanListener bleScanListener) { mDeviceNames = names; mDeviceMac = mac; mFuzzy = fuzzy; mNeedConnect = needConnect; mScanTimeout = timeOut; - mBleScanPresenterImp = bleScanPresenterImp; - - mHandlerThread = new HandlerThread(BleScanPresenter.class.getSimpleName()); - mHandlerThread.start(); - mHandler = new ScanHandler(mHandlerThread.getLooper(), this); - mHandling = true; + mBleScanListener = bleScanListener; } public boolean ismNeedConnect() { return mNeedConnect; } - public BleScanPresenterImp getBleScanPresenterImp() { - return mBleScanPresenterImp; + public BleScanListener getBleScanListener() { + return mBleScanListener; + } + + public void setCancelBleScanListener() { + this.mBleScanListener = null; } @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { if (device == null) return; - - if (!mHandling) - return; - - Message message = mHandler.obtainMessage(); - message.what = BleMsg.MSG_SCAN_DEVICE; - message.obj = new BleDevice(device, rssi, scanRecord, System.currentTimeMillis()); - mHandler.sendMessage(message); + handleResult(new BleDevice(device, rssi, scanRecord, System.currentTimeMillis())); } private void checkDevice(BleDevice bleDevice) { @@ -148,13 +109,7 @@ private void correctDeviceAndNextStep(final BleDevice bleDevice) { + " scanRecord:" + HexUtil.formatHexString(bleDevice.getScanRecord())); mBleDeviceList.add(bleDevice); - mMainHandler.post(new Runnable() { - @Override - public void run() { - BleScanner.getInstance().stopLeScan(); - } - }); - + BleScanner.getInstance().stopLeScan(true); } else { AtomicBoolean hasFound = new AtomicBoolean(false); for (BleDevice result : mBleDeviceList) { @@ -170,12 +125,7 @@ public void run() { + " scanRecord: " + HexUtil.formatHexString(bleDevice.getScanRecord(), true)); mBleDeviceList.add(bleDevice); - mMainHandler.post(new Runnable() { - @Override - public void run() { - onScanning(bleDevice); - } - }); + onScanning(bleDevice); } } } @@ -186,37 +136,19 @@ public final void notifyScanStarted(final boolean success) { removeHandlerMsg(); if (success && mScanTimeout > 0) { - mMainHandler.postDelayed(new Runnable() { - @Override - public void run() { - BleScanner.getInstance().stopLeScan(); - } - }, mScanTimeout); + mMainHandler.postDelayed(() -> BleScanner.getInstance().stopLeScan(true), mScanTimeout); } - mMainHandler.post(new Runnable() { - @Override - public void run() { - onScanStarted(success); - } - }); + onScanStarted(success); } public final void notifyScanStopped() { - mHandling = false; - mHandlerThread.quit(); removeHandlerMsg(); - mMainHandler.post(new Runnable() { - @Override - public void run() { - onScanFinished(mBleDeviceList); - } - }); + onScanFinished(mBleDeviceList); } public final void removeHandlerMsg() { mMainHandler.removeCallbacksAndMessages(null); - mHandler.removeCallbacksAndMessages(null); } public abstract void onScanStarted(boolean success); diff --git a/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanner.java b/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanner.java index d9d47b9..11e28ed 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanner.java +++ b/FastBleLib/src/main/java/com/clj/fastble/scan/BleScanner.java @@ -1,15 +1,14 @@ package com.clj.fastble.scan; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import com.clj.fastble.BleManager; import com.clj.fastble.callback.BleScanAndConnectCallback; import com.clj.fastble.callback.BleScanCallback; -import com.clj.fastble.callback.BleScanPresenterImp; +import com.clj.fastble.callback.BleScanListener; import com.clj.fastble.data.BleDevice; import com.clj.fastble.data.BleScanState; import com.clj.fastble.utils.BleLog; @@ -34,7 +33,7 @@ private static class BleScannerHolder { @Override public void onScanStarted(boolean success) { - BleScanPresenterImp callback = mBleScanPresenter.getBleScanPresenterImp(); + BleScanListener callback = getBleScanListener(); if (callback != null) { callback.onScanStarted(success); } @@ -42,23 +41,21 @@ public void onScanStarted(boolean success) { @Override public void onLeScan(BleDevice bleDevice) { + BleScanListener callback = mBleScanPresenter.getBleScanListener(); if (mBleScanPresenter.ismNeedConnect()) { - BleScanAndConnectCallback callback = (BleScanAndConnectCallback) - mBleScanPresenter.getBleScanPresenterImp(); if (callback != null) { - callback.onLeScan(bleDevice); + ((BleScanAndConnectCallback) callback).onLeScan(bleDevice); } } else { - BleScanCallback callback = (BleScanCallback) mBleScanPresenter.getBleScanPresenterImp(); if (callback != null) { - callback.onLeScan(bleDevice); + ((BleScanCallback) callback).onLeScan(bleDevice); } } } @Override public void onScanning(BleDevice result) { - BleScanPresenterImp callback = mBleScanPresenter.getBleScanPresenterImp(); + BleScanListener callback = mBleScanPresenter.getBleScanListener(); if (callback != null) { callback.onScanning(result); } @@ -66,31 +63,25 @@ public void onScanning(BleDevice result) { @Override public void onScanFinished(List bleDeviceList) { + final BleScanListener callback = + mBleScanPresenter.getBleScanListener(); if (mBleScanPresenter.ismNeedConnect()) { - final BleScanAndConnectCallback callback = (BleScanAndConnectCallback) - mBleScanPresenter.getBleScanPresenterImp(); if (bleDeviceList == null || bleDeviceList.size() < 1) { if (callback != null) { - callback.onScanFinished(null); + ((BleScanAndConnectCallback) callback).onScanFinished(null); } } else { if (callback != null) { - callback.onScanFinished(bleDeviceList.get(0)); + ((BleScanAndConnectCallback) callback).onScanFinished(bleDeviceList.get(0)); } - final List list = bleDeviceList; - new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - BleManager.getInstance().connect(list.get(0), callback); - } - }, 100); + BleManager.getInstance().connect(bleDeviceList.get(0), ((BleScanAndConnectCallback) callback)); } } else { - BleScanCallback callback = (BleScanCallback) mBleScanPresenter.getBleScanPresenterImp(); if (callback != null) { - callback.onScanFinished(bleDeviceList); + ((BleScanCallback) callback).onScanFinished(bleDeviceList); } } + mBleScanPresenter.setCancelBleScanListener(); } }; @@ -106,29 +97,39 @@ public void scanAndConnect(UUID[] serviceUuids, String[] names, String mac, bool startLeScan(serviceUuids, names, mac, fuzzy, true, timeOut, callback); } - private synchronized void startLeScan(UUID[] serviceUuids, String[] names, String mac, boolean fuzzy, - boolean needConnect, long timeOut, BleScanPresenterImp imp) { - - if (mBleScanState != BleScanState.STATE_IDLE) { - BleLog.w("scan action already exists, complete the previous scan action first"); - if (imp != null) { - imp.onScanStarted(false); + @SuppressLint("MissingPermission") + private void startLeScan(UUID[] serviceUuids, String[] names, String mac, boolean fuzzy, + boolean needConnect, long timeOut, BleScanListener imp) { + synchronized (this) { + if (mBleScanState != BleScanState.STATE_IDLE) { + BleLog.w("scan action already exists, complete the previous scan action first"); + if (imp != null) { + imp.onScanStarted(false); + } + return; } - return; - } - mBleScanPresenter.prepare(names, mac, fuzzy, needConnect, timeOut, imp); + mBleScanPresenter.prepare(names, mac, fuzzy, needConnect, timeOut, imp); - boolean success = BleManager.getInstance().getBluetoothAdapter() - .startLeScan(serviceUuids, mBleScanPresenter); - mBleScanState = success ? BleScanState.STATE_SCANNING : BleScanState.STATE_IDLE; - mBleScanPresenter.notifyScanStarted(success); + boolean success = BleManager.getInstance().getBluetoothAdapter() + .startLeScan(serviceUuids, mBleScanPresenter); + mBleScanState = success ? BleScanState.STATE_SCANNING : BleScanState.STATE_IDLE; + mBleScanPresenter.notifyScanStarted(success); + } } - public synchronized void stopLeScan() { - BleManager.getInstance().getBluetoothAdapter().stopLeScan(mBleScanPresenter); - mBleScanState = BleScanState.STATE_IDLE; - mBleScanPresenter.notifyScanStopped(); + @SuppressLint("MissingPermission") + public void stopLeScan(boolean isCallbackScanFinish) { + synchronized (this) { + BleManager.getInstance().getBluetoothAdapter().stopLeScan(mBleScanPresenter); + mBleScanState = BleScanState.STATE_IDLE; + if (!isCallbackScanFinish) { + mBleScanPresenter.removeHandlerMsg(); + mBleScanPresenter.setCancelBleScanListener(); + return; + } + mBleScanPresenter.notifyScanStopped(); + } } public BleScanState getScanState() { diff --git a/FastBleLib/src/main/java/com/clj/fastble/utils/BleLog.java b/FastBleLib/src/main/java/com/clj/fastble/utils/BleLog.java index 38f17d6..01e0817 100644 --- a/FastBleLib/src/main/java/com/clj/fastble/utils/BleLog.java +++ b/FastBleLib/src/main/java/com/clj/fastble/utils/BleLog.java @@ -3,28 +3,30 @@ import android.util.Log; +import com.clj.fastble.BuildConfig; + public final class BleLog { public static boolean isPrint = true; private static final String defaultTag = "FastBle"; public static void d(String msg) { - if (isPrint && msg != null) + if (isPrint && BuildConfig.DEBUG && msg != null) Log.d(defaultTag, msg); } public static void i(String msg) { - if (isPrint && msg != null) + if (isPrint && BuildConfig.DEBUG && msg != null) Log.i(defaultTag, msg); } public static void w(String msg) { - if (isPrint && msg != null) + if (isPrint && BuildConfig.DEBUG && msg != null) Log.w(defaultTag, msg); } public static void e(String msg) { - if (isPrint && msg != null) + if (isPrint && BuildConfig.DEBUG && msg != null) Log.e(defaultTag, msg); } diff --git a/app/build.gradle b/app/build.gradle index acb8ba0..95130dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { diff --git a/app/src/main/java/com/clj/blesample/MainActivity.java b/app/src/main/java/com/clj/blesample/MainActivity.java index a958057..06a08a4 100644 --- a/app/src/main/java/com/clj/blesample/MainActivity.java +++ b/app/src/main/java/com/clj/blesample/MainActivity.java @@ -92,7 +92,7 @@ protected void onResume() { protected void onDestroy() { super.onDestroy(); BleManager.getInstance().disconnectAllDevice(); - BleManager.getInstance().destroy(); + BleManager.getInstance().destroy(null); } @Override @@ -102,7 +102,7 @@ public void onClick(View v) { if (btn_scan.getText().equals(getString(R.string.start_scan))) { checkPermissions(); } else if (btn_scan.getText().equals(getString(R.string.stop_scan))) { - BleManager.getInstance().cancelScan(); + BleManager.getInstance().cancelScan(true); } break; @@ -147,7 +147,7 @@ private void initView() { @Override public void onConnect(BleDevice bleDevice) { if (!BleManager.getInstance().isConnected(bleDevice)) { - BleManager.getInstance().cancelScan(); + BleManager.getInstance().cancelScan(true); connect(bleDevice); } } diff --git a/config.gradle b/config.gradle index fbd28fc..66077b7 100644 --- a/config.gradle +++ b/config.gradle @@ -6,8 +6,8 @@ ext { android = [ minSdkVersion : 14, - targetSdkVersion : 30, - compileSdkVersion: 30, + targetSdkVersion : 31, + compileSdkVersion: 31, buildToolsVersion: "30.0.3", ]