diff --git a/commonLib/build.gradle b/commonLib/build.gradle index b8c21ce..9701236 100644 --- a/commonLib/build.gradle +++ b/commonLib/build.gradle @@ -38,6 +38,8 @@ dependencies { implementation 'com.aill:AndroidSerialPort:1.0.8' + implementation 'com.airbnb.android:lottie:5.0.2' + implementation(rootProject.ext.dependencies.mmkv) // 添加kotlin依赖 diff --git a/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt b/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt index 0eef4fe..3d030bc 100644 --- a/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt +++ b/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt @@ -38,7 +38,7 @@ interface IBluetoothClient { * @param mac 需要连接蓝牙设备的地址 * @return 成功,返回连接设备的地址 */ - fun connect(mac: String): Observable + fun connect(mac: String, callback: BaseResultCallback) /** * 断开蓝牙连接, 释放蓝牙连接占用的蓝牙服务 diff --git a/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java index b7e18f6..9b0b621 100644 --- a/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java +++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java @@ -114,6 +114,21 @@ public class BLEClientService extends Service { } }; + /** + * 连接回调 + */ + private final BaseResultCallback connectCallback = new BaseResultCallback() { + @Override + public void onSuccess(String data) { + Log.d(TAG, "got connectCallback onSuccess = " + data); + } + + @Override + public void onFail(String msg) { + Log.d(TAG, "got connectCallback onFail = " + msg); + } + }; + /** * 连接服务端设备 * @@ -127,49 +142,75 @@ public class BLEClientService extends Service { if (TextUtils.isEmpty(connectMac)) { connectMac = BtUtils.INSTANCE.getConnectMac(BLEClientService.this); } - Observable[] observables = new Observable[2]; - observables[0] = mBtClient.connect(connectMac); - // 判断是否需要启动通知 - if (enableNotify) { - observables[1] = mBtClient.registerNotify(connectMac, BtConstants.INSTANCE.getUUID_SERVICE(), - BtConstants.INSTANCE.getUUID_CHARACTERISTIC_READ_NOTIFY(), notifyCallback); - } - Observable.concatArray(observables).subscribe(new Observer() { + mBtClient.connect(connectMac, new BaseResultCallback() { @Override - public void onSubscribe(@NonNull Disposable d) { - Log.d(TAG, "connect onSubscribe"); - } + public void onSuccess(String data) { + Log.d(TAG, "got connectCallback onSuccess = " + data); + if (enableNotify) { + mBtClient.registerNotify(connectMac, BtConstants.INSTANCE.getUUID_SERVICE(), + BtConstants.INSTANCE.getUUID_CHARACTERISTIC_READ_NOTIFY(), notifyCallback).subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.d(TAG, "connect onSubscribe"); + } - @Override - public void onNext(@NonNull String value) { - Log.d(TAG, String.format("connect onNext: %s", value)); + @Override + public void onNext(@NonNull String value) { + Log.d(TAG, String.format("connect onNext: %s", value)); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e(TAG, "connect onError: ", e); + // 链接过程报错,断开链接 + mBtClient.disconnect(connectMac); + connectMac = ""; + + if (clientListener != null) { + clientListener.onResult(new CommonMsg(BtConstants.CONNECT_ERROR, e.getMessage())); + } + if (connectListener != null) { + connectListener.onFail(e.getMessage()); + } + } + + @Override + public void onComplete() { + Log.d(TAG, "connect onComplete"); + // 将链接成功的MAC地址保存 + BtUtils.INSTANCE.saveConnectMac(BLEClientService.this, mac); + if (clientListener != null) { + clientListener.onResult(new CommonMsg(CONNECT_SUCCESS, mac)); + } + if (connectListener != null) { + connectListener.onSuccess(); + } + } + }); + } else { + // 将链接成功的MAC地址保存 + BtUtils.INSTANCE.saveConnectMac(BLEClientService.this, mac); + if (clientListener != null) { + clientListener.onResult(new CommonMsg(CONNECT_SUCCESS, mac)); + } + if (connectListener != null) { + connectListener.onSuccess(); + } + } } @Override - public void onError(@NonNull Throwable e) { - Log.e(TAG, "connect onError: ", e); + public void onFail(String msg) { + Log.d(TAG, "got connectCallback onFail = " + msg); // 链接过程报错,断开链接 mBtClient.disconnect(connectMac); connectMac = ""; if (clientListener != null) { - clientListener.onResult(new CommonMsg(BtConstants.CONNECT_ERROR, e.getMessage())); - } - if (connectListener != null) { - connectListener.onFail(e.getMessage()); - } - } - - @Override - public void onComplete() { - Log.d(TAG, "connect onComplete"); - // 将链接成功的MAC地址保存 - BtUtils.INSTANCE.saveConnectMac(BLEClientService.this, mac); - if (clientListener != null) { - clientListener.onResult(new CommonMsg(CONNECT_SUCCESS, mac)); + clientListener.onResult(new CommonMsg(BtConstants.CONNECT_ERROR, msg)); } if (connectListener != null) { - connectListener.onSuccess(); + connectListener.onFail(msg); } } }); diff --git a/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java index 0b67b2e..946a354 100644 --- a/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java +++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java @@ -46,7 +46,6 @@ public class BluetoothClientBLEAdapter implements IBluetoothClient { public BluetoothClientBLEAdapter(BluetoothBLeClient client) { mClient = client; - HandlerThread workThread = new HandlerThread("bluetooth ble worker"); workThread.start(); } @@ -101,34 +100,27 @@ public class BluetoothClientBLEAdapter implements IBluetoothClient { mClient.getBluetoothSearcher(BtConstants.BLUETOOTH_TYPE.BLE).stopScan(); } - @NonNull @Override - public Observable connect(@NonNull final String mac) { - return Observable.create(new ObservableOnSubscribe() { - @Override - public void subscribe(@NonNull final ObservableEmitter emitter) { - BluetoothLeConnector connector = mClient.getBluetoothLeConnector(mac); + public void connect(@NonNull final String mac, BaseResultCallback callback) { + BluetoothLeConnector connector = mClient.getBluetoothLeConnector(mac); - connector.connect(new BluetoothLeConnector.OnConnectListener() { - @Override - public void onConnect() { - } + connector.connect(new BluetoothLeConnector.OnConnectListener() { + @Override + public void onConnect() { + } - @Override - public void onDisconnect() { - } + @Override + public void onDisconnect() { + } - @Override - public void onServiceDiscover() { - emitter.onNext(mac); - emitter.onComplete(); - } + @Override + public void onServiceDiscover() { + callback.onSuccess(mac); + } - @Override - public void onError(String msg) { - emitter.onError(new Throwable(msg)); - } - }); + @Override + public void onError(String msg) { + callback.onFail(msg); } }); } diff --git a/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java index 8a0a6a8..ef227d9 100644 --- a/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java +++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java @@ -164,7 +164,8 @@ public class BluetoothLeConnector { mConnectHandler.postDelayed(() -> mWorkHandler.post(() -> { if (!mIsStartService.get()) { - gatt.disconnect(); + disconnectGatt(); + mOnConnectListener.onError("disCoverServices time out"); } }), 3000L); @@ -309,6 +310,11 @@ public class BluetoothLeConnector { mIsStartService.set(false); mConnectTime.set(SystemClock.elapsedRealtime()); + // 再次链接前检查是否存在上一次的链接,如果存在,尝试断开连接 + if (getBluetoothGatt() != null) { + getBluetoothGatt().disconnect(); + getBluetoothGatt().close(); + } setBluetoothGatt(device.connectGatt(mContext, false, mGattCallback)); if (getBluetoothGatt() == null) { String err = "bluetooth is not open!"; @@ -320,7 +326,7 @@ public class BluetoothLeConnector { // 自定义MTU // getBluetoothGatt().requestMtu(512); - // 开一个定时器,如果超出 20s 就强制断开连接 + // 开一个定时器,如果超出 10s 就强制断开连接 // 这个定时器必须在连接上设备之后清掉 mConnectHandler.removeCallbacksAndMessages(null); mConnectHandler.postDelayed(() -> @@ -331,7 +337,7 @@ public class BluetoothLeConnector { Log.e(TAG, err); callback.onError(err); } - }), 20000L); + }), 10000L); }); } @@ -353,16 +359,12 @@ public class BluetoothLeConnector { return; } - if (mConnectStatus.get() == BluetoothGatt.STATE_DISCONNECTED) { - close(); - return; + if (mConnectStatus.get() == BluetoothGatt.STATE_CONNECTING) { + mConnectHandler.removeCallbacksAndMessages(null); } - getBluetoothGatt().disconnect(); - // 确保 Gatt 一定会被 close - if (mConnectStatus.get() == BluetoothGatt.STATE_CONNECTING) { - mConnectHandler.removeCallbacksAndMessages(null); + if (mConnectStatus.get() != BluetoothGatt.STATE_DISCONNECTING) { close(); } } @@ -378,6 +380,7 @@ public class BluetoothLeConnector { Log.e(TAG, "BluetoothAdapter not initialized"); return; } + getBluetoothGatt().disconnect(); getBluetoothGatt().close(); setBluetoothGatt(null); mConnectStatus.set(BluetoothGatt.STATE_DISCONNECTED); diff --git a/commonbt/src/main/java/com/common/bluetooth/service/ble/BtBleSearcher.kt b/commonbt/src/main/java/com/common/bluetooth/service/ble/BtBleSearcher.kt index 7df7780..c359d69 100644 --- a/commonbt/src/main/java/com/common/bluetooth/service/ble/BtBleSearcher.kt +++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BtBleSearcher.kt @@ -134,7 +134,7 @@ class BtBleSearcher( if (mScanning.get()) { mScanning.set(false) launch(Dispatchers.Main) { - mScanCallback!!.onComplete() + mScanCallback?.onComplete() } mBluetoothAdapter?.bluetoothLeScanner?.stopScan(mScanCallback) mScanCallback = null diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClientClassicAdapter.kt b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClientClassicAdapter.kt index 9c8bd9f..15b320c 100644 --- a/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClientClassicAdapter.kt +++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClientClassicAdapter.kt @@ -28,14 +28,11 @@ class BluetoothClientClassicAdapter(private var mClient: BluetoothClassicClient) mClient.getBluetoothSearcher(BtConstants.BLUETOOTH_TYPE.CLASSIC).stopScan() } - override fun connect(mac: String): Observable { - return Observable.create { - if (!mClient.isConnected((mac))) { - mClient.connect(mac) - } - it.onNext(mac) - it.onComplete() + override fun connect(mac: String, callback: BaseResultCallback) { + if (!mClient.isConnected((mac))) { + mClient.connect(mac) } + callback.onSuccess(mac) } override fun disconnect(mac: String) { diff --git a/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt b/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt index 355fb9a..c107f5f 100644 --- a/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt +++ b/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt @@ -9,7 +9,6 @@ import com.common.bluetooth.DeviceJson import com.common.bluetooth.bean.* import com.google.gson.Gson import com.google.gson.reflect.TypeToken -import java.util.ArrayList /** * 蓝牙工具类 @@ -36,10 +35,15 @@ object BtUtils { const val MAC_KEY = "mac" /** - * MAC地址的KEY + * MAC名称的KEY */ const val MAC_AND_NAME_KEY = "mac_and_name" + /** + * MAC名字的KEY + */ + const val NAME_KEY = "name" + enum class EVENT_TYPE(val type: String, val index: String) { /** * 点击事件 @@ -374,7 +378,7 @@ object BtUtils { * @param mac 设备MAC * @param context 上下文 */ - fun saveConnectMacAndName(context: Context, mac: String,name:String) { + fun saveConnectMacAndName(context: Context, mac: String, name: String) { val sharedPreferences: SharedPreferences = context.getSharedPreferences(SP_DEVICE_NAME, Context.MODE_PRIVATE) val edit = sharedPreferences.edit() @@ -382,14 +386,19 @@ object BtUtils { var deviceNameList: ArrayList = ArrayList() var deviceMacList1: ArrayList = ArrayList() var deviceNameList1: ArrayList = ArrayList() + var seatNameList: ArrayList = ArrayList() + var seatNameList1: ArrayList = ArrayList() val gson = Gson() deviceMacList.clear() deviceNameList.clear() + seatNameList.clear() if (TextUtils.isEmpty(getConnectMacAndName(context, MAC_AND_NAME_KEY))) { deviceMacList.add(mac) deviceNameList.add(name) + seatNameList.add(name) edit.putString(MAC_AND_NAME_KEY, gson.toJson(deviceNameList)) edit.putString(MAC_KEY, gson.toJson(deviceMacList)) + edit.putString(NAME_KEY, gson.toJson(seatNameList)) } else { val listType = object : TypeToken?>() {}.type deviceMacList1 = gson.fromJson>( @@ -401,17 +410,29 @@ object BtUtils { getConnectMacAndName(context, MAC_AND_NAME_KEY), listType2 ) + val listType3 = object : TypeToken?>() {}.type + seatNameList1 = gson.fromJson>( + getConnectMacAndName(context, NAME_KEY), + listType3 + ) var i = 0 for (s in deviceMacList1) { if (deviceMacList1.get(i) == mac) { break - } else if (deviceMacList1.get(deviceMacList1.size - 1) != mac ) { + } else if (deviceMacList1.get(deviceMacList1.size - 1) != mac) { + deviceMacList.clear() deviceMacList.add(mac) deviceMacList.addAll(deviceMacList1) + deviceNameList.clear() deviceNameList.add(name) deviceNameList.addAll(deviceNameList1) + seatNameList.clear() + seatNameList.add(name) + seatNameList.addAll(seatNameList1) edit.putString(MAC_AND_NAME_KEY, gson.toJson(deviceNameList)) edit.putString(MAC_KEY, gson.toJson(deviceMacList)) + edit.putString(NAME_KEY, gson.toJson(seatNameList)) + } i++ } @@ -433,6 +454,8 @@ object BtUtils { return sharedPreferences.getString(MAC_AND_NAME_KEY, "") } else if (string == MAC_KEY) { return sharedPreferences.getString(MAC_KEY, "") + } else if (string == NAME_KEY) { + return sharedPreferences.getString(NAME_KEY, "") } return "" } @@ -456,21 +479,29 @@ object BtUtils { * @param mac 设备MAC * @param context 上下文 */ - fun changeConnectMacAndName(context: Context, device: MutableList) { + fun changeConnectMacAndName( + context: Context, + device: MutableList, + list: MutableList + ) { val sharedPreferences: SharedPreferences = context.getSharedPreferences(SP_DEVICE_NAME, Context.MODE_PRIVATE) val edit = sharedPreferences.edit() var deviceMacList: ArrayList = ArrayList() var deviceNameList: ArrayList = ArrayList() + var seatNameList: ArrayList = ArrayList() val gson = Gson() deviceMacList.clear() deviceNameList.clear() + seatNameList.clear() var i = 0 for (s in device) { deviceMacList.add(device.get(i).mac) deviceNameList.add(device.get(i).name) + seatNameList.add(list.get(i)) edit.putString(MAC_AND_NAME_KEY, gson.toJson(deviceNameList)) edit.putString(MAC_KEY, gson.toJson(deviceMacList)) + edit.putString(NAME_KEY, gson.toJson(seatNameList)) i++ } diff --git a/commonbt/src/main/java/com/common/bluetooth/utils/ToastUtil.kt b/commonbt/src/main/java/com/common/bluetooth/utils/ToastUtil.kt new file mode 100644 index 0000000..35de24e --- /dev/null +++ b/commonbt/src/main/java/com/common/bluetooth/utils/ToastUtil.kt @@ -0,0 +1,29 @@ +package com.common.bluetooth.utils + +import android.content.Context +import android.view.LayoutInflater +import android.widget.TextView +import android.widget.Toast +import com.common.bluetooth.R + +/** + * toast工具类 + */ +class ToastUtil { + + companion object { + /** + * 展示自定义背景和信息的toast + */ + fun showCustomToast(context: Context, msg: String) { + val view = LayoutInflater.from(context).inflate(R.layout.my_toast_layout, null, false) + val textView = view.findViewById(R.id.tv_toast_msg) + textView.text = msg + var toast: Toast = Toast(context) + toast.duration = Toast.LENGTH_SHORT + toast.view = view + toast.show() + } + + } +} \ No newline at end of file diff --git a/commonbt/src/main/java/com/common/bluetooth/view/BtDeviceListAdapter.java b/commonbt/src/main/java/com/common/bluetooth/view/BtDeviceListAdapter.java index 1fb62df..ab42f3e 100644 --- a/commonbt/src/main/java/com/common/bluetooth/view/BtDeviceListAdapter.java +++ b/commonbt/src/main/java/com/common/bluetooth/view/BtDeviceListAdapter.java @@ -33,13 +33,13 @@ public class BtDeviceListAdapter extends RecyclerView.Adapter + + + + + + \ No newline at end of file diff --git a/commonbt/src/main/res/layout/my_toast_layout.xml b/commonbt/src/main/res/layout/my_toast_layout.xml new file mode 100644 index 0000000..57627ab --- /dev/null +++ b/commonbt/src/main/res/layout/my_toast_layout.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/commonbt/src/main/res/values/colors.xml b/commonbt/src/main/res/values/colors.xml index df7101c..a6f5367 100644 --- a/commonbt/src/main/res/values/colors.xml +++ b/commonbt/src/main/res/values/colors.xml @@ -18,4 +18,5 @@ #ff000000 #ffffffff #ff777777 + #E6565D65 \ No newline at end of file diff --git a/commonbt/src/main/res/values/styles.xml b/commonbt/src/main/res/values/styles.xml index 2723a84..7a11c27 100644 --- a/commonbt/src/main/res/values/styles.xml +++ b/commonbt/src/main/res/values/styles.xml @@ -1,5 +1,6 @@ + + + \ No newline at end of file