diff --git a/commonbt/src/main/AndroidManifest.xml b/commonbt/src/main/AndroidManifest.xml
index 7b80fd7..3ff51be 100644
--- a/commonbt/src/main/AndroidManifest.xml
+++ b/commonbt/src/main/AndroidManifest.xml
@@ -25,13 +25,25 @@
             android:screenOrientation="portrait"
             android:theme="@style/Theme.AppCompat"/>
         
         
 
         
+        
+
+        
+        
+
+        
         
diff --git a/commonbt/src/main/java/com/common/bluetooth/BtConstants.kt b/commonbt/src/main/java/com/common/bluetooth/BtConstants.kt
index ea514ae..a33e5d0 100644
--- a/commonbt/src/main/java/com/common/bluetooth/BtConstants.kt
+++ b/commonbt/src/main/java/com/common/bluetooth/BtConstants.kt
@@ -2,6 +2,7 @@ package com.common.bluetooth
 
 import android.content.Context
 import android.provider.Settings
+import java.nio.charset.StandardCharsets
 import java.util.*
 
 /**
@@ -13,6 +14,8 @@ import java.util.*
 object BtConstants {
     const val BT_NAME = "innovation bt"
 
+    val DEFAULT_CHARSET = StandardCharsets.UTF_8
+
     /**
      * 蓝牙类型
      */
@@ -80,6 +83,10 @@ object BtConstants {
      */
     const val MAX_MTU = 35
 
+    /**
+     * 经典蓝牙连接UUID
+     */
+    val CLASSIC_BT_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
     val UUID_SERVICE = UUID.fromString("66f564dc-121f-3e7f-80b1-f005d3f194c9")
     val UUID_CHARACTERISTIC_NOTIFY = UUID.fromString("66f564dd-121f-3e7f-80b1-f005d3f194c9")
     val UUID_CHARACTERISTIC_WRITE = UUID.fromString("66f564de-121f-3e7f-80b1-f005d3f194c9")
diff --git a/commonbt/src/main/java/com/common/bluetooth/BtDemoActivity.java b/commonbt/src/main/java/com/common/bluetooth/BtDemoActivity.java
index 6310fa0..a8f1d75 100644
--- a/commonbt/src/main/java/com/common/bluetooth/BtDemoActivity.java
+++ b/commonbt/src/main/java/com/common/bluetooth/BtDemoActivity.java
@@ -22,6 +22,7 @@ import com.common.bluetooth.bean.CommonMsg;
 import com.common.bluetooth.bean.KeyboardEvent;
 import com.common.bluetooth.callback.BLEClientListener;
 import com.common.bluetooth.databinding.ActivityMainBinding;
+import com.common.bluetooth.utils.BtUtils;
 import com.common.bluetooth.view.BtDeviceListAdapter;
 import com.google.gson.Gson;
 
@@ -131,10 +132,23 @@ public class BtDemoActivity extends AppCompatActivity {
                 }
             }));
         });
+
+        mBinding.btcServerBuild.setOnClickListener(v -> {
+            BtManager.INSTANCE.initServer(this, BtConstants.BLUETOOTH_TYPE.CLASSIC);
+            BtManager.INSTANCE.setMsgReceiverListener(msg -> {
+                Log.d(TAG, new String(msg));
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mBinding.btcReceiveContent.setText(new String(msg));
+                    }
+                });
+            });
+        });
     }
 
     private void checkBluetooth() {
-        BtManager.INSTANCE.initClient(this, BtConstants.BLUETOOTH_TYPE.BLE);
+        BtManager.INSTANCE.initClient(this, BtConstants.BLUETOOTH_TYPE.CLASSIC);
         BtManager.INSTANCE.btPermissionCheck(this, PERMISSION_REQUEST_LOCATION);
     }
 
diff --git a/commonbt/src/main/java/com/common/bluetooth/BtManager.kt b/commonbt/src/main/java/com/common/bluetooth/BtManager.kt
index af1e96e..6fdf0f7 100644
--- a/commonbt/src/main/java/com/common/bluetooth/BtManager.kt
+++ b/commonbt/src/main/java/com/common/bluetooth/BtManager.kt
@@ -11,20 +11,25 @@ import android.content.ServiceConnection
 import android.content.pm.PackageManager
 import android.os.Build
 import android.os.IBinder
-import android.util.Log.d
-import android.util.Log.e
+import android.util.Log.*
 import androidx.core.content.ContextCompat.checkSelfPermission
 import com.common.bluetooth.BtConstants.BLUETOOTH_TYPE
-import com.common.bluetooth.adapter.BluetoothClientBLEAdapter
+import com.common.bluetooth.service.ble.BluetoothClientBLEAdapter
 import com.common.bluetooth.bean.CommonMsg
 import com.common.bluetooth.callback.BLEClientListener
-import com.common.bluetooth.callback.BleMsgReceiverListener
+import com.common.bluetooth.callback.BtMsgListener
+import com.common.bluetooth.callback.BtServiceListener
+import com.common.bluetooth.callback.MsgReceiverListener
 import com.common.bluetooth.interfaces.IBluetoothClient
-import com.common.bluetooth.service.BLEClientService
-import com.common.bluetooth.service.BLEClientService.BLEClientBinder
-import com.common.bluetooth.service.BLEReceiveService
-import com.common.bluetooth.service.BLEReceiveService.ReceiverBinder
-import com.common.bluetooth.service.BluetoothLeClient
+import com.common.bluetooth.service.ble.BLEClientService
+import com.common.bluetooth.service.ble.BLEClientService.BLEClientBinder
+import com.common.bluetooth.service.ble.BLEReceiveService
+import com.common.bluetooth.service.ble.BLEReceiveService.ReceiverBinder
+import com.common.bluetooth.service.ble.BluetoothLeClient
+import com.common.bluetooth.service.bt.BTCClientService
+import com.common.bluetooth.service.bt.BTCReceiverService
+import com.common.bluetooth.service.bt.BluetoothClassicClient
+import com.common.bluetooth.service.bt.BluetoothClientClassicAdapter
 import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
 import io.reactivex.rxjava3.core.Observer
 import io.reactivex.rxjava3.disposables.Disposable
@@ -45,34 +50,59 @@ object BtManager {
     private var mBtClient: IBluetoothClient? = null
 
     /**
-     * 客户端服务
+     * BLE客户端服务
      */
     private var clientService: BLEClientService? = null
 
     /**
-     * 服务端服务
+     * 经典蓝牙客户端服务
+     */
+    private var classicClientService: BTCClientService? = null
+
+    /**
+     * BLE服务端服务
      */
     private var serverService: BLEReceiveService? = null
 
+    /**
+     * 经典蓝牙服务端服务
+     */
+    private var classicServerService: BTCReceiverService? = null
+
     /**
      * 消息接收监听
      */
-    var msgReceiverListener: BleMsgReceiverListener? = null
+    var msgReceiverListener: MsgReceiverListener? = null
 
     /**
      * 蓝牙客户端监听
      */
     var clientListener: BLEClientListener? = null
 
+    /**
+     * 蓝牙服务链接监听
+     */
+    var btServiceListener: BtServiceListener? = null
+
     /**
      * 是否绑定了服务端
      */
-    private var isBindServer: AtomicBoolean = AtomicBoolean(false)
+    private var isBindBleServer: AtomicBoolean = AtomicBoolean(false)
 
     /**
      * 是否绑定了客户端
      */
-    private var isBindClient: AtomicBoolean = AtomicBoolean(false)
+    private var isBindBleClient: AtomicBoolean = AtomicBoolean(false)
+
+    /**
+     * 是否绑定了服务端
+     */
+    private var isBindClassicServer: AtomicBoolean = AtomicBoolean(false)
+
+    /**
+     * 是否绑定了客户端
+     */
+    private var isBindClassicClient: AtomicBoolean = AtomicBoolean(false)
 
     /**
      * 当前使用的编码 默认是UTF-8
@@ -89,77 +119,180 @@ object BtManager {
      * 初始化蓝牙服务端模块
      */
     fun initServer(context: Context, btType: BLUETOOTH_TYPE) {
-        mBtClient = BluetoothClientBLEAdapter(BluetoothLeClient.getInstance(context))
+        if (btType == BLUETOOTH_TYPE.BLE) {
+            mBtClient = BluetoothClientBLEAdapter(
+                BluetoothLeClient.getInstance(context)
+            )
+            initBleReceiverService(context)
+        } else if (btType == BLUETOOTH_TYPE.CLASSIC) {
+            mBtClient = BluetoothClientClassicAdapter(BluetoothClassicClient(context))
+            initClassicReceiverService(context)
+        }
         mBtClient!!.checkBluetoothDevice(btType)
-        initReceiverService(context)
+
     }
 
     /**
      * 初始化蓝牙客户端模块
      */
     fun initClient(context: Activity, btType: BLUETOOTH_TYPE) {
-        mBtClient = BluetoothClientBLEAdapter(BluetoothLeClient.getInstance(context))
+        if (btType == BLUETOOTH_TYPE.BLE) {
+            mBtClient = BluetoothClientBLEAdapter(
+                BluetoothLeClient.getInstance(context)
+            )
+            initBleClientService(context)
+        } else if (btType == BLUETOOTH_TYPE.CLASSIC) {
+            mBtClient = BluetoothClientClassicAdapter(
+                BluetoothClassicClient(context)
+            )
+            initClassicClientService(context)
+        }
         mBtClient!!.checkBluetoothDevice(btType)
-        initClientService(context)
     }
 
-
     /**
      * 初始化接收端服务
      */
-    private fun initReceiverService(context: Context) {
+    private fun initBleReceiverService(context: Context) {
         val intent = Intent(context, BLEReceiveService::class.java)
         // 标志位BIND_AUTO_CREATE是的服务中onCreate得到执行,onStartCommand不会执行
-        context.bindService(intent, receiverConn, Context.BIND_AUTO_CREATE)
-        isBindServer.set(true)
+        context.bindService(intent, bleReceiverConn, Context.BIND_AUTO_CREATE)
+        isBindBleServer.set(true)
+    }
+
+    private fun initClassicReceiverService(context: Context) {
+        val intent = Intent(context, BTCReceiverService::class.java)
+        // 标志位BIND_AUTO_CREATE是的服务中onCreate得到执行,onStartCommand不会执行
+        context.bindService(intent, classicReceiverConn, Context.BIND_AUTO_CREATE)
+        isBindClassicServer.set(true)
     }
 
     /**
      * 初始化客户端服务
      */
-    private fun initClientService(context: Context) {
+    private fun initBleClientService(context: Context) {
         val intent = Intent(context, BLEClientService::class.java)
         // 标志位BIND_AUTO_CREATE是的服务中onCreate得到执行,onStartCommand不会执行
-        context.bindService(intent, clientConn, Context.BIND_AUTO_CREATE)
-        isBindClient.set(true)
+        context.bindService(intent, bleClientConn, Context.BIND_AUTO_CREATE)
+        isBindBleClient.set(true)
     }
 
-    private val receiverConn: ServiceConnection = object : ServiceConnection {
-        override fun onServiceConnected(name: ComponentName, service: IBinder) {
-            serverService = (service as ReceiverBinder).service
-            serverService?.setMsgReceiveListener(object : BleMsgReceiverListener {
-                override fun onMsgReceive(msg: ByteArray) {
-                    msgReceiverListener?.onMsgReceive(msg)
-                }
-            })
+    private fun initClassicClientService(context: Context) {
+        val intent = Intent(context, BTCClientService::class.java)
+        // 标志位BIND_AUTO_CREATE是的服务中onCreate得到执行,onStartCommand不会执行
+        context.bindService(intent, classicClientConn, Context.BIND_AUTO_CREATE)
+        isBindClassicClient.set(true)
+    }
+
+    private val bleReceiverConn: ServiceConnection by lazy {
+        object : ServiceConnection {
+            override fun onServiceConnected(name: ComponentName, service: IBinder) {
+                serverService = (service as ReceiverBinder).service
+                serverService?.setMsgReceiveListener(object : MsgReceiverListener {
+                    override fun onMsgReceive(msg: ByteArray) {
+                        msgReceiverListener?.onMsgReceive(msg)
+                    }
+                })
+                btServiceListener?.onServiceReady()
+            }
+
+            override fun onServiceDisconnected(name: ComponentName) {
+                serverService = null
+                btServiceListener?.onServiceDisConnected()
+            }
         }
+    }
+
+    private val classicReceiverConn: ServiceConnection by lazy {
+        object : ServiceConnection {
+            override fun onServiceConnected(name: ComponentName, service: IBinder) {
+                classicServerService = (service as BTCReceiverService.ClassicReceiverBinder).service
+                classicServerService?.setMsgReceiveListener(object : BtMsgListener() {
+                    override fun socketNotify(state: Int, msg: String) {
+                        msgReceiverListener?.onMsgReceive(msg.toByteArray())
+                    }
+                })
+                btServiceListener?.onServiceReady()
+            }
 
-        override fun onServiceDisconnected(name: ComponentName) {}
+            override fun onServiceDisconnected(name: ComponentName) {
+                classicServerService = null
+                btServiceListener?.onServiceDisConnected()
+            }
+        }
     }
 
-    private val clientConn: ServiceConnection = object : ServiceConnection {
-        override fun onServiceConnected(name: ComponentName, service: IBinder) {
-            clientService = (service as BLEClientBinder).service
-            clientService?.setClientListener(object : BLEClientListener {
-                override fun onResult(result: CommonMsg) {
-                    // 如果连接成功,更新连接的设备
-                    if (result.msgType == BtConstants.CONNECT_SUCCESS) {
-                        curConnectMac = result.msg
-                    } else if (result.msgType == BtConstants.DISCONNECT) {
-                        curConnectMac = ""
+    private val bleClientConn: ServiceConnection by lazy {
+        object : ServiceConnection {
+            override fun onServiceConnected(name: ComponentName, service: IBinder) {
+                clientService = (service as BLEClientBinder).service
+                clientService?.setClientListener(object : BLEClientListener {
+                    override fun onResult(result: CommonMsg) {
+                        // 如果连接成功,更新连接的设备
+                        if (result.msgType == BtConstants.CONNECT_SUCCESS) {
+                            curConnectMac = result.msg
+                        } else if (result.msgType == BtConstants.DISCONNECT) {
+                            curConnectMac = ""
+                        }
+                        clientListener?.onResult(result)
                     }
-                    clientListener?.onResult(result)
-                }
 
-                override fun onNotifyMsgReceive(msg: ByteArray) {
-                    clientListener?.onNotifyMsgReceive(msg)
-                }
-            })
+                    override fun onNotifyMsgReceive(msg: ByteArray) {
+                        clientListener?.onNotifyMsgReceive(msg)
+                    }
+                })
+                btServiceListener?.onServiceReady()
+            }
+
+            override fun onServiceDisconnected(name: ComponentName) {
+                clientService = null
+                clientListener?.onResult(
+                    CommonMsg(
+                        BtConstants.DISCONNECT,
+                        "disconnect from server"
+                    )
+                )
+                btServiceListener?.onServiceDisConnected()
+            }
         }
+    }
+
+    private val classicClientConn: ServiceConnection by lazy {
+        object : ServiceConnection {
+            override fun onServiceConnected(name: ComponentName, service: IBinder) {
+                classicClientService = (service as BTCClientService.ClassicClientBinder).service
+                classicClientService?.setMsgReceiveListener(object : BtMsgListener() {
+                    override fun socketNotify(state: Int, msg: String) {
+                        when (state) {
+                            CONNECTED -> {
+                                curConnectMac = msg
+                                clientListener?.onResult(
+                                    CommonMsg(
+                                        BtConstants.CONNECT_SUCCESS,
+                                        msg
+                                    )
+                                )
+                            }
+                            DISCONNECTED -> {
+                                curConnectMac = ""
+                                clientListener?.onResult(CommonMsg(BtConstants.DISCONNECT, msg))
+                            }
+                            MSG -> {
+                                clientListener?.onNotifyMsgReceive(msg.toByteArray())
+                            }
+                            else -> {
+                                e(TAG, "got error state:$state")
+                            }
+                        }
+                    }
+                })
+                btServiceListener?.onServiceReady()
+            }
 
-        override fun onServiceDisconnected(name: ComponentName) {
-            clientService = null
-            clientListener?.onResult(CommonMsg(BtConstants.DISCONNECT, "disconnect from server"))
+            override fun onServiceDisconnected(name: ComponentName) {
+                classicClientService = null
+                btServiceListener?.onServiceDisConnected()
+            }
         }
     }
 
@@ -205,10 +338,16 @@ object BtManager {
      * @param mac MAC地址
      */
     fun connect(mac: String) {
-        if (clientService == null) {
-            e(TAG, "writeMsg pls init first")
-        } else {
+        if (clientService != null) {
             clientService!!.connect(mac, true)
+        } else {
+            w(TAG, "init clientService first")
+        }
+
+        if (classicClientService != null) {
+            classicClientService!!.connect(mac)
+        } else {
+            w(TAG, "init classicClientService first")
         }
     }
 
@@ -241,11 +380,17 @@ object BtManager {
      * @param msg 传输的内容
      */
     fun write(msg: ByteArray) {
-        if (clientService == null) {
-            e(TAG, "writeMsg pls init first")
-        } else {
+        if (clientService != null) {
             clientService!!.write(msg)
         }
+
+        if (classicClientService != null) {
+            classicClientService!!.write(msg)
+        }
+
+        if (classicServerService != null) {
+            classicServerService!!.write(msg)
+        }
     }
 
     /**
@@ -301,19 +446,28 @@ object BtManager {
      */
     fun sendNotify(msg: ByteArray) {
         serverService?.sendNotify(msg)
+        classicServerService?.write(msg)
     }
 
     /**
      * 释放链接
      */
     fun release(context: Context?) {
-        if (isBindServer.get()) {
-            context?.unbindService(receiverConn)
-            isBindServer.set(false)
+        if (isBindBleServer.get()) {
+            context?.unbindService(bleReceiverConn)
+            isBindBleServer.set(false)
+        }
+        if (isBindClassicServer.get()) {
+            context?.unbindService(classicReceiverConn)
+            isBindClassicServer.set(false)
+        }
+        if (isBindBleClient.get()) {
+            context?.unbindService(bleClientConn)
+            isBindBleClient.set(false)
         }
-        if (isBindClient.get()) {
-            context?.unbindService(clientConn)
-            isBindClient.set(false)
+        if (isBindClassicClient.get()) {
+            context?.unbindService(classicClientConn)
+            isBindClassicServer.set(false)
         }
     }
 }
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/callback/BtMsgListener.kt b/commonbt/src/main/java/com/common/bluetooth/callback/BtMsgListener.kt
new file mode 100644
index 0000000..1bc35e5
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/callback/BtMsgListener.kt
@@ -0,0 +1,33 @@
+package com.common.bluetooth.callback
+
+/**
+ * 经典蓝牙监听
+ *
+ * @author wangym
+ * @since 2021-12-1
+ */
+abstract class BtMsgListener {
+    /**
+     * 通知
+     * @param state 消息类型
+     * @param msg 消息内容
+     */
+    open fun socketNotify(state: Int, msg: String) {}
+
+    companion object {
+        /**
+         * 断开连接
+         */
+        const val DISCONNECTED = 0
+
+        /**
+         * 连接成功
+         */
+        const val CONNECTED = 1
+
+        /**
+         * 消息
+         */
+        const val MSG = 2
+    }
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/callback/BtServiceListener.kt b/commonbt/src/main/java/com/common/bluetooth/callback/BtServiceListener.kt
new file mode 100644
index 0000000..7e82915
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/callback/BtServiceListener.kt
@@ -0,0 +1,19 @@
+package com.common.bluetooth.callback
+
+/**
+ * BT服务监听
+ *
+ * @author wangym
+ * @since 2021-12-9
+ */
+interface BtServiceListener {
+    /**
+     * 服务准备完毕
+     */
+    fun onServiceReady()
+
+    /**
+     * 服务断开
+     */
+    fun onServiceDisConnected()
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/callback/BleMsgReceiverListener.kt b/commonbt/src/main/java/com/common/bluetooth/callback/MsgReceiverListener.kt
similarity index 84%
rename from commonbt/src/main/java/com/common/bluetooth/callback/BleMsgReceiverListener.kt
rename to commonbt/src/main/java/com/common/bluetooth/callback/MsgReceiverListener.kt
index 5986236..bea99f4 100644
--- a/commonbt/src/main/java/com/common/bluetooth/callback/BleMsgReceiverListener.kt
+++ b/commonbt/src/main/java/com/common/bluetooth/callback/MsgReceiverListener.kt
@@ -3,7 +3,7 @@ package com.common.bluetooth.callback
 /**
  * BLE数据接收监听
  */
-interface BleMsgReceiverListener {
+interface MsgReceiverListener {
     /**
      * 接收的消息
      *
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 963d151..c0ec305 100644
--- a/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt
+++ b/commonbt/src/main/java/com/common/bluetooth/interfaces/IBluetoothClient.kt
@@ -24,7 +24,7 @@ interface IBluetoothClient {
      * false 如果当前正在进行扫描操作则会抛出 [com.common.bluetooth.exception.BluetoothSearchConflictException] 错误
      * @return 扫描结果的列表(无重复设备)
      */
-    fun search(millis: Int, cancel: Boolean): Observable
+    fun search(millis: Long, cancel: Boolean): Observable
 
     /**
      * 停止扫描
@@ -38,7 +38,7 @@ interface IBluetoothClient {
      * @param mac 需要连接蓝牙设备的地址
      * @return 成功,返回连接设备的地址
      */
-    fun connect(mac: String?): Observable
+    fun connect(mac: String): Observable
 
     /**
      * 断开蓝牙连接, 释放蓝牙连接占用的蓝牙服务
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothCommon.kt b/commonbt/src/main/java/com/common/bluetooth/service/BluetoothCommon.kt
new file mode 100644
index 0000000..3122067
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/BluetoothCommon.kt
@@ -0,0 +1,120 @@
+package com.common.bluetooth.service
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.content.Context
+import android.content.pm.PackageManager
+import android.util.Log
+import com.common.bluetooth.BtConstants.BLUETOOTH_TYPE
+import com.common.bluetooth.interfaces.IBluetoothSearch
+import com.common.bluetooth.service.bt.BluetoothClassicBase
+import com.common.bluetooth.service.bt.BluetoothClassicSearcher
+
+/**
+ * 通用蓝牙
+ *
+ * @author wangym
+ * @since 2021-12-1
+ */
+open class BluetoothCommon(val mContext: Context) {
+    val TAG = "BluetoothCommon"
+    var mBluetoothAdapter: BluetoothAdapter? = null
+    var mBluetoothManager: BluetoothManager? = null
+    var mBluetoothSearcher: IBluetoothSearch? = null
+
+    /**
+     * 检查蓝牙设备是否支持
+     *
+     * @param btType 蓝牙类型
+     */
+    fun checkBtDevice(btType: BLUETOOTH_TYPE): Boolean {
+        if (btType === BLUETOOTH_TYPE.BLE) {
+            // 检查当前手机是否支持ble 蓝牙
+            if (!mContext.packageManager
+                    .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
+            ) {
+                Log.e(TAG, "not support ble device")
+                return false
+            }
+        }
+
+        // For API level 18 and above, get a reference to BluetoothAdapter
+        // through BluetoothManager.
+        if (mBluetoothManager == null) {
+            mBluetoothManager = mContext
+                .getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+            if (mBluetoothManager == null) {
+                Log.e(TAG, "Unable to initialize BluetoothManager.")
+                return false
+            }
+        }
+        if (mBluetoothAdapter == null) {
+            mBluetoothAdapter = mBluetoothManager?.adapter
+            if (mBluetoothAdapter == null) {
+                Log.e(TAG, "Unable to obtain a BluetoothAdapter.")
+                return false
+            }
+        }
+        return true
+    }
+
+    /**
+     * 通过MAC地址获取设备对象
+     *
+     * @param mac mac地址
+     * @return 设备对象
+     */
+    fun getBtDeviceByMac(mac: String?): BluetoothDevice? {
+        if (mBluetoothAdapter == null) {
+            Log.e(TAG, "getBtDeviceByMac mBluetoothAdapter is null")
+            return null
+        }
+        return mBluetoothAdapter!!.getRemoteDevice(mac)
+    }
+
+    /**
+     * 初始化BluetoothAdapter
+     * Initializes a reference to the local Bluetooth adapter.
+     *
+     * @return Return true if the initialization is successful.
+     */
+    fun openBt(): Boolean {
+        if (mBluetoothAdapter == null) {
+            Log.e(TAG, "BluetoothManager do not init")
+            return false
+        }
+        return mBluetoothAdapter!!.isEnabled() || mBluetoothAdapter!!.enable()
+    }
+
+    fun closeBt(): Boolean {
+        if (mBluetoothAdapter == null) {
+            Log.e(TAG, "BluetoothManager do not init")
+            return false
+        }
+        return mBluetoothAdapter!!.disable()
+    }
+
+    /**
+     * 获取已配对蓝牙设备信息
+     */
+    fun getBondedDevices(): Set? {
+        return mBluetoothAdapter?.bondedDevices
+    }
+
+    /**
+     * 获取蓝牙扫描对象
+     *
+     * @return 蓝牙扫描对象
+     */
+    fun getBluetoothSearcher(): IBluetoothSearch {
+        if (mBluetoothSearcher == null) {
+            synchronized(BluetoothClassicBase::class.java) {
+                if (mBluetoothSearcher == null) {
+                    mBluetoothSearcher = BluetoothClassicSearcher(mContext, mBluetoothAdapter)
+                }
+            }
+        }
+        return mBluetoothSearcher!!
+    }
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothConnectService.java b/commonbt/src/main/java/com/common/bluetooth/service/BluetoothConnectService.java
deleted file mode 100644
index 4631051..0000000
--- a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothConnectService.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.common.bluetooth.service;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothServerSocket;
-import android.bluetooth.BluetoothSocket;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.common.bluetooth.BtConstants;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.UUID;
-
-/**
- * This class does all the work for setting up and managing Bluetooth
- * connections with other devices. It has a thread that listens for
- * incoming connections, a thread for connecting with a device, and a
- * thread for performing data transmissions when connected.
- */
-public class BluetoothConnectService {
-    // Debugging
-    private static final String TAG = "BluetoothConnectService";
-
-    // Name for the SDP record when creating server socket
-    private static final String NAME_SECURE = "BluetoothChatSecure";
-    private static final String NAME_INSECURE = "BluetoothChatInsecure";
-
-    // Unique UUID for this application
-    private final UUID CURRENT_UUID;
-
-    // Member fields
-    private final BluetoothAdapter mAdapter;
-    private final Handler mHandler;
-    private AcceptThread mSecureAcceptThread;
-    private AcceptThread mInsecureAcceptThread;
-    private ConnectThread mConnectThread;
-    private ConnectedThread mConnectedThread;
-    private int mState;
-    private int mNewState;
-
-    // Constants that indicate the current connection state
-    public static final int STATE_NONE = 0;       // we're doing nothing
-    public static final int STATE_LISTEN = 1;     // now listening for incoming connections
-    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
-    public static final int STATE_CONNECTED = 3;  // now connected to a remote device
-
-    /**
-     * Constructor. Prepares a new BluetoothChat session.
-     *
-     * @param context The UI Activity Context
-     * @param handler A Handler to send messages back to the UI Activity
-     */
-    public BluetoothConnectService(Context context, Handler handler) {
-        CURRENT_UUID = BtConstants.INSTANCE.getUUid(context);
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mState = STATE_NONE;
-        mNewState = mState;
-        mHandler = handler;
-    }
-
-    /**
-     * Update UI title according to the current state of the chat connection
-     */
-    private synchronized void updateUserInterfaceTitle() {
-        mState = getState();
-        Log.d(TAG, "updateUserInterfaceTitle() " + mNewState + " -> " + mState);
-        mNewState = mState;
-
-        // Give the new state to the Handler so the UI Activity can update
-        mHandler.obtainMessage(BtConstants.MESSAGE_STATE_CHANGE, mNewState, -1).sendToTarget();
-    }
-
-    /**
-     * Return the current connection state.
-     */
-    public synchronized int getState() {
-        return mState;
-    }
-
-    /**
-     * Start the chat service. Specifically start AcceptThread to begin a
-     * session in listening (server) mode. Called by the Activity onResume()
-     */
-    public synchronized void start() {
-        Log.d(TAG, "start");
-
-        // Cancel any thread attempting to make a connection
-        if (mConnectThread != null) {
-            mConnectThread.cancel();
-            mConnectThread = null;
-        }
-
-        // Cancel any thread currently running a connection
-        if (mConnectedThread != null) {
-            mConnectedThread.cancel();
-            mConnectedThread = null;
-        }
-
-        // Start the thread to listen on a BluetoothServerSocket
-        if (mSecureAcceptThread == null) {
-            mSecureAcceptThread = new AcceptThread(false);
-            mSecureAcceptThread.start();
-        }
-        if (mInsecureAcceptThread == null) {
-            mInsecureAcceptThread = new AcceptThread(false);
-            mInsecureAcceptThread.start();
-        }
-        // Update UI title
-        updateUserInterfaceTitle();
-    }
-
-    /**
-     * Start the ConnectThread to initiate a connection to a remote device.
-     *
-     * @param device The BluetoothDevice to connect
-     */
-    public synchronized void connect(BluetoothDevice device) {
-        Log.d(TAG, "connect to: " + device);
-
-        // Cancel any thread attempting to make a connection
-        if (mState == STATE_CONNECTING) {
-            if (mConnectThread != null) {
-                mConnectThread.cancel();
-                mConnectThread = null;
-            }
-        }
-
-        // Cancel any thread currently running a connection
-        if (mConnectedThread != null) {
-            mConnectedThread.cancel();
-            mConnectedThread = null;
-        }
-
-        // Start the thread to connect with the given device
-        mConnectThread = new ConnectThread(device, false);
-        mConnectThread.start();
-        // Update UI title
-        updateUserInterfaceTitle();
-    }
-
-    /**
-     * Start the ConnectedThread to begin managing a Bluetooth connection
-     *
-     * @param socket The BluetoothSocket on which the connection was made
-     * @param device The BluetoothDevice that has been connected
-     */
-    public synchronized void connected(BluetoothSocket socket, BluetoothDevice
-            device, final String socketType) {
-        Log.d(TAG, "connected, Socket Type:" + socketType);
-
-        // Cancel the thread that completed the connection
-        if (mConnectThread != null) {
-            mConnectThread.cancel();
-            mConnectThread = null;
-        }
-
-        // Cancel any thread currently running a connection
-        if (mConnectedThread != null) {
-            mConnectedThread.cancel();
-            mConnectedThread = null;
-        }
-
-        // Cancel the accept thread because we only want to connect to one device
-        if (mSecureAcceptThread != null) {
-            mSecureAcceptThread.cancel();
-            mSecureAcceptThread = null;
-        }
-        if (mInsecureAcceptThread != null) {
-            mInsecureAcceptThread.cancel();
-            mInsecureAcceptThread = null;
-        }
-
-        // Start the thread to manage the connection and perform transmissions
-        mConnectedThread = new ConnectedThread(socket, socketType);
-        mConnectedThread.start();
-
-        // Send the name of the connected device back to the UI Activity
-        Message msg = mHandler.obtainMessage(BtConstants.MESSAGE_DEVICE_NAME);
-        Bundle bundle = new Bundle();
-        bundle.putString(BtConstants.DEVICE_NAME, device.getName());
-        msg.setData(bundle);
-        mHandler.sendMessage(msg);
-        // Update UI title
-        updateUserInterfaceTitle();
-    }
-
-    /**
-     * Stop all threads
-     */
-    public synchronized void stop() {
-        Log.d(TAG, "stop");
-
-        if (mConnectThread != null) {
-            mConnectThread.cancel();
-            mConnectThread = null;
-        }
-
-        if (mConnectedThread != null) {
-            mConnectedThread.cancel();
-            mConnectedThread = null;
-        }
-
-        if (mSecureAcceptThread != null) {
-            mSecureAcceptThread.cancel();
-            mSecureAcceptThread = null;
-        }
-
-        if (mInsecureAcceptThread != null) {
-            mInsecureAcceptThread.cancel();
-            mInsecureAcceptThread = null;
-        }
-        mState = STATE_NONE;
-        // Update UI title
-        updateUserInterfaceTitle();
-    }
-
-    /**
-     * Write to the ConnectedThread in an unsynchronized manner
-     *
-     * @param out The bytes to write
-     * @see ConnectedThread#write(byte[])
-     */
-    public void write(byte[] out) {
-        // Create temporary object
-        ConnectedThread r;
-        // Synchronize a copy of the ConnectedThread
-        synchronized (this) {
-            if (mState != STATE_CONNECTED) return;
-            r = mConnectedThread;
-        }
-        // Perform the write unsynchronized
-        r.write(out);
-    }
-
-    /**
-     * Indicate that the connection attempt failed and notify the UI Activity.
-     */
-    private void connectionFailed() {
-        // Send a failure message back to the Activity
-        Message msg = mHandler.obtainMessage(BtConstants.MESSAGE_TOAST);
-        Bundle bundle = new Bundle();
-        bundle.putString(BtConstants.TOAST, "Unable to connect device");
-        msg.setData(bundle);
-        mHandler.sendMessage(msg);
-
-        mState = STATE_NONE;
-        // Update UI title
-        updateUserInterfaceTitle();
-
-        // Start the service over to restart listening mode
-        BluetoothConnectService.this.start();
-    }
-
-    /**
-     * Indicate that the connection was lost and notify the UI Activity.
-     */
-    private void connectionLost() {
-        // Send a failure message back to the Activity
-        Message msg = mHandler.obtainMessage(BtConstants.MESSAGE_TOAST);
-        Bundle bundle = new Bundle();
-        bundle.putString(BtConstants.TOAST, "Device connection was lost");
-        msg.setData(bundle);
-        mHandler.sendMessage(msg);
-
-        mState = STATE_NONE;
-        // Update UI title
-        updateUserInterfaceTitle();
-
-        // Start the service over to restart listening mode
-        BluetoothConnectService.this.start();
-    }
-
-    /**
-     * This thread runs while listening for incoming connections. It behaves
-     * like a server-side client. It runs until a connection is accepted
-     * (or until cancelled).
-     */
-    private class AcceptThread extends Thread {
-        // The local server socket
-        private final BluetoothServerSocket mmServerSocket;
-        private String mSocketType;
-
-        public AcceptThread(boolean secure) {
-            BluetoothServerSocket tmp = null;
-            mSocketType = secure ? "Secure" : "Insecure";
-
-            // Create a new listening server socket
-            try {
-                tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
-                        CURRENT_UUID);
-            } catch (IOException e) {
-                Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
-            }
-            mmServerSocket = tmp;
-            mState = STATE_LISTEN;
-        }
-
-        public void run() {
-            Log.d(TAG, "Socket Type: " + mSocketType +
-                    "BEGIN mAcceptThread" + this);
-            setName("AcceptThread" + mSocketType);
-
-            BluetoothSocket socket = null;
-
-            // Listen to the server socket if we're not connected
-            while (mState != STATE_CONNECTED) {
-                try {
-                    // This is a blocking call and will only return on a
-                    // successful connection or an exception
-                    socket = mmServerSocket.accept();
-                } catch (IOException e) {
-                    Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
-                    break;
-                }
-
-                // If a connection was accepted
-                if (socket != null) {
-                    synchronized (BluetoothConnectService.this) {
-                        switch (mState) {
-                            case STATE_LISTEN:
-                            case STATE_CONNECTING:
-                                // Situation normal. Start the connected thread.
-                                connected(socket, socket.getRemoteDevice(),
-                                        mSocketType);
-                                break;
-                            case STATE_NONE:
-                            case STATE_CONNECTED:
-                                // Either not ready or already connected. Terminate new socket.
-                                try {
-                                    socket.close();
-                                } catch (IOException e) {
-                                    Log.e(TAG, "Could not close unwanted socket", e);
-                                }
-                                break;
-                        }
-                    }
-                }
-            }
-            Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
-
-        }
-
-        public void cancel() {
-            Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
-            try {
-                mmServerSocket.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
-            }
-        }
-    }
-
-
-    /**
-     * This thread runs while attempting to make an outgoing connection
-     * with a device. It runs straight through; the connection either
-     * succeeds or fails.
-     */
-    private class ConnectThread extends Thread {
-        private BluetoothSocket mmSocket;
-        private final BluetoothDevice mmDevice;
-        private String mSocketType;
-
-        public ConnectThread(BluetoothDevice device, boolean secure) {
-            mmDevice = device;
-            BluetoothSocket tmp = null;
-            mSocketType = secure ? "Secure" : "Insecure";
-
-            // Get a BluetoothSocket for a connection with the
-            // given BluetoothDevice
-            try {
-                tmp = device.createRfcommSocketToServiceRecord(
-                        CURRENT_UUID);
-            } catch (IOException e) {
-                Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
-            }
-            mmSocket = tmp;
-            mState = STATE_CONNECTING;
-        }
-
-        public void run() {
-            Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
-            setName("ConnectThread" + mSocketType);
-
-            // Always cancel discovery because it will slow down a connection
-            mAdapter.cancelDiscovery();
-
-            // Make a connection to the BluetoothSocket
-            try {
-                // This is a blocking call and will only return on a
-                // successful connection or an exception
-                mmSocket.connect();
-            } catch (IOException e) {
-                // Unable to connect; close the socket and return.
-                Log.e(TAG, e.toString());
-                try {
-                    mmSocket.close();
-                } catch (IOException ie) {
-                    connectionFailed();
-                }
-                return;
-            }
-
-            // Reset the ConnectThread because we're done
-            synchronized (BluetoothConnectService.this) {
-                mConnectThread = null;
-            }
-
-            // Start the connected thread
-            connected(mmSocket, mmDevice, mSocketType);
-        }
-
-        public void cancel() {
-            try {
-                mmSocket.close();
-            } catch (IOException e) {
-                Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
-            }
-        }
-    }
-
-    /**
-     * This thread runs during a connection with a remote device.
-     * It handles all incoming and outgoing transmissions.
-     */
-    private class ConnectedThread extends Thread {
-        private final BluetoothSocket mmSocket;
-        private final InputStream mmInStream;
-        private final OutputStream mmOutStream;
-
-        public ConnectedThread(BluetoothSocket socket, String socketType) {
-            Log.d(TAG, "create ConnectedThread: " + socketType);
-            mmSocket = socket;
-            InputStream tmpIn = null;
-            OutputStream tmpOut = null;
-
-            // Get the BluetoothSocket input and output streams
-            try {
-                tmpIn = socket.getInputStream();
-                tmpOut = socket.getOutputStream();
-            } catch (IOException e) {
-                Log.e(TAG, "temp sockets not created", e);
-            }
-
-            mmInStream = tmpIn;
-            mmOutStream = tmpOut;
-            mState = STATE_CONNECTED;
-        }
-
-        public void run() {
-            Log.i(TAG, "BEGIN mConnectedThread");
-            byte[] buffer = new byte[1024];
-            int bytes;
-
-            // Keep listening to the InputStream while connected
-            while (mState == STATE_CONNECTED) {
-                try {
-                    // Read from the InputStream
-                    bytes = mmInStream.read(buffer);
-
-                    // Send the obtained bytes to the UI Activity
-                    mHandler.obtainMessage(BtConstants.MESSAGE_READ, bytes, -1, buffer)
-                            .sendToTarget();
-                } catch (IOException e) {
-                    Log.e(TAG, "disconnected", e);
-                    connectionLost();
-                    break;
-                }
-            }
-        }
-
-        /**
-         * Write to the connected OutStream.
-         *
-         * @param buffer The bytes to write
-         */
-        public void write(byte[] buffer) {
-            try {
-                mmOutStream.write(buffer);
-
-                // Share the sent message back to the UI Activity
-                mHandler.obtainMessage(BtConstants.MESSAGE_WRITE, -1, -1, buffer)
-                        .sendToTarget();
-            } catch (IOException e) {
-                Log.e(TAG, "Exception during write", e);
-            }
-        }
-
-        public void cancel() {
-            try {
-                mmSocket.close();
-            } catch (IOException e) {
-                Log.e(TAG, "close() of connect socket failed", e);
-            }
-        }
-    }
-}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeClient.java b/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeClient.java
deleted file mode 100644
index cee6db1..0000000
--- a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeClient.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.common.bluetooth.service;
-
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.util.Log;
-
-import com.common.bluetooth.BtConstants;
-import com.common.bluetooth.interfaces.IBluetoothSearch;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 蓝牙操作管理类
- *
- * @author wangym
- * @since 2021-10-19
- */
-public class BluetoothLeClient {
-    @SuppressLint("StaticFieldLeak")
-    private static volatile BluetoothLeClient mInstance;
-
-    private final static String TAG = "BluetoothLeClient";
-    private final Context mContext;
-    private static Handler mBluetoothWorker;
-    private BluetoothAdapter mBluetoothAdapter;
-    private BluetoothManager mBluetoothManager;
-    private IBluetoothSearch mBluetoothSearcher;
-
-    private final Map mGattConnectorMap
-            = new ConcurrentHashMap<>();
-
-    private BluetoothLeClient(Context context) {
-        mContext = context.getApplicationContext();
-
-        HandlerThread thread = new HandlerThread("bluetooth client worker");
-        thread.start();
-        mBluetoothWorker = new Handler(thread.getLooper());
-    }
-
-    public static BluetoothLeClient getInstance(Context context) {
-        if (mInstance == null) {
-            synchronized (BluetoothLeClient.class) {
-                if (mInstance == null) {
-                    mInstance = new BluetoothLeClient(context);
-                }
-            }
-        }
-
-        return mInstance;
-    }
-
-    /**
-     * 检查蓝牙设备是否支持
-     *
-     * @param btType 蓝牙类型
-     */
-    public boolean checkBtDevice(BtConstants.BLUETOOTH_TYPE btType) {
-        if (btType == BtConstants.BLUETOOTH_TYPE.BLE) {
-            // 检查当前手机是否支持ble 蓝牙
-            if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
-                Log.e(TAG, "not support ble device");
-                return false;
-            }
-        }
-
-        // For API level 18 and above, get a reference to BluetoothAdapter
-        // through BluetoothManager.
-        if (mBluetoothManager == null) {
-            mBluetoothManager = (BluetoothManager) mContext
-                    .getSystemService(Context.BLUETOOTH_SERVICE);
-            if (mBluetoothManager == null) {
-                Log.e(TAG, "Unable to initialize BluetoothManager.");
-                return false;
-            }
-        }
-
-        if (mBluetoothAdapter == null) {
-            mBluetoothAdapter = mBluetoothManager.getAdapter();
-            if (mBluetoothAdapter == null) {
-                Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * 初始化BluetoothAdapter
-     * Initializes a reference to the local Bluetooth adapter.
-     *
-     * @return Return true if the initialization is successful.
-     */
-    public boolean openBt() {
-        if (mBluetoothAdapter == null) {
-            Log.e(TAG, "BluetoothManager do not init");
-            return false;
-        }
-        return mBluetoothAdapter.isEnabled() || mBluetoothAdapter.enable();
-    }
-
-    public boolean closeBt() {
-        if (mBluetoothAdapter == null) {
-            Log.e(TAG, "BluetoothManager do not init");
-            return false;
-        }
-        return mBluetoothAdapter.disable();
-    }
-
-    public IBluetoothSearch getBluetoothSearcher() {
-        if (mBluetoothSearcher == null) {
-            synchronized (BluetoothLeClient.class) {
-                if (mBluetoothSearcher == null) {
-                    if (mBluetoothAdapter == null) {
-                        String err = "cannot create BluetoothLeSearcher instance because not " +
-                                "initialize, please call initialize() method";
-                        Log.e(TAG, err);
-                        return null;
-                    }
-
-                    mBluetoothSearcher = new BluetoothLeSearcher(mContext, mBluetoothAdapter, mBluetoothWorker);
-                }
-            }
-        }
-
-        return mBluetoothSearcher;
-    }
-
-    public BluetoothLeConnector getBluetoothLeConnector(String mac) {
-        BluetoothLeConnector result;
-        if ((result = mGattConnectorMap.get(mac)) != null) {
-            return result;
-        }
-
-        result = new BluetoothLeConnector(mContext, mBluetoothAdapter, mac, mBluetoothWorker);
-        mGattConnectorMap.put(mac, result);
-        return result;
-    }
-
-    public void cleanConnector(String mac) {
-        BluetoothLeConnector result;
-        if ((result = mGattConnectorMap.get(mac)) != null) {
-            mGattConnectorMap.remove(mac);
-            result.disconnect();
-            result.setOnDataAvailableListener(null);
-        }
-    }
-
-    /**
-     * 在不在需要连接蓝牙设备的时候,
-     * 或者生命周期暂停的时候调用这一个方法
-     */
-    public void cleanAllConnector() {
-        for (String mac : mGattConnectorMap.keySet()) {
-            cleanConnector(mac);
-        }
-    }
-
-    /**
-     * 获取已配对蓝牙设备信息
-     */
-    public Set getBondedDevices() {
-        return mBluetoothAdapter.getBondedDevices();
-    }
-}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BLEClientService.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java
similarity index 98%
rename from commonbt/src/main/java/com/common/bluetooth/service/BLEClientService.java
rename to commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java
index da5b625..76669c7 100644
--- a/commonbt/src/main/java/com/common/bluetooth/service/BLEClientService.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEClientService.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.service;
+package com.common.bluetooth.service.ble;
 
 import static com.common.bluetooth.BtConstants.CONNECT_SUCCESS;
 
@@ -13,8 +13,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.common.bluetooth.BtConstants;
-import com.common.bluetooth.BtUtils;
-import com.common.bluetooth.adapter.BluetoothClientBLEAdapter;
+import com.common.bluetooth.utils.BtUtils;
 import com.common.bluetooth.bean.CommonMsg;
 import com.common.bluetooth.callback.BLEClientListener;
 import com.common.bluetooth.callback.BaseResultCallback;
@@ -29,7 +28,6 @@ import io.reactivex.rxjava3.core.Observable;
 import io.reactivex.rxjava3.core.Observer;
 import io.reactivex.rxjava3.disposables.Disposable;
 
-
 /**
  * BLE客户端服务
  *
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BLEReceiveService.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEReceiveService.java
similarity index 97%
rename from commonbt/src/main/java/com/common/bluetooth/service/BLEReceiveService.java
rename to commonbt/src/main/java/com/common/bluetooth/service/ble/BLEReceiveService.java
index fc62fd0..414dfce 100644
--- a/commonbt/src/main/java/com/common/bluetooth/service/BLEReceiveService.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BLEReceiveService.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.service;
+package com.common.bluetooth.service.ble;
 
 import android.app.Service;
 import android.bluetooth.BluetoothDevice;
@@ -18,15 +18,12 @@ import android.content.Intent;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelUuid;
-import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
 
 import com.common.bluetooth.BtConstants;
-import com.common.bluetooth.callback.BleMsgReceiverListener;
-
-import java.nio.charset.StandardCharsets;
+import com.common.bluetooth.callback.MsgReceiverListener;
 
 /**
  * BLE接收服务
@@ -51,7 +48,7 @@ public class BLEReceiveService extends Service {
     /**
      * 蓝牙消息接收监听
      */
-    private BleMsgReceiverListener receiverListener;
+    private MsgReceiverListener receiverListener;
     /**
      * 远端设备
      */
@@ -159,7 +156,7 @@ public class BLEReceiveService extends Service {
         }
     }
 
-    public void setMsgReceiveListener(BleMsgReceiverListener listener) {
+    public void setMsgReceiveListener(MsgReceiverListener listener) {
         receiverListener = listener;
     }
 
diff --git a/commonbt/src/main/java/com/common/bluetooth/adapter/BluetoothClientBLEAdapter.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java
similarity index 97%
rename from commonbt/src/main/java/com/common/bluetooth/adapter/BluetoothClientBLEAdapter.java
rename to commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java
index 71ad17a..baccdb0 100644
--- a/commonbt/src/main/java/com/common/bluetooth/adapter/BluetoothClientBLEAdapter.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothClientBLEAdapter.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.adapter;
+package com.common.bluetooth.service.ble;
 
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothGatt;
@@ -17,8 +17,6 @@ import com.common.bluetooth.exception.BluetoothSearchConflictException;
 import com.common.bluetooth.exception.BluetoothWriteException;
 import com.common.bluetooth.interfaces.IBluetoothClient;
 import com.common.bluetooth.interfaces.IBluetoothSearch;
-import com.common.bluetooth.service.BluetoothLeClient;
-import com.common.bluetooth.service.BluetoothLeConnector;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -53,7 +51,7 @@ public class BluetoothClientBLEAdapter implements IBluetoothClient {
     }
 
     @Override
-    public Observable search(final int millis, final boolean cancel) {
+    public Observable search(final long millis, final boolean cancel) {
         return Observable.create(new ObservableOnSubscribe() {
             @Override
             public void subscribe(@NonNull final ObservableEmitter emitter) {
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeClient.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeClient.java
new file mode 100644
index 0000000..fd2a243
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeClient.java
@@ -0,0 +1,79 @@
+package com.common.bluetooth.service.ble;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.common.bluetooth.service.BluetoothCommon;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 蓝牙操作管理类
+ *
+ * @author wangym
+ * @since 2021-10-19
+ */
+public class BluetoothLeClient extends BluetoothCommon {
+    @SuppressLint("StaticFieldLeak")
+    private static volatile BluetoothLeClient mInstance;
+
+    private final static String TAG = "BluetoothLeClient";
+    private final Context mContext;
+    private static Handler mBluetoothWorker;
+
+    private final Map mGattConnectorMap
+            = new ConcurrentHashMap<>();
+
+    private BluetoothLeClient(Context context) {
+        super(context.getApplicationContext());
+        mContext = context.getApplicationContext();
+        HandlerThread thread = new HandlerThread("bluetooth client worker");
+        thread.start();
+        mBluetoothWorker = new Handler(thread.getLooper());
+    }
+
+    public static BluetoothLeClient getInstance(Context context) {
+        if (mInstance == null) {
+            synchronized (BluetoothLeClient.class) {
+                if (mInstance == null) {
+                    mInstance = new BluetoothLeClient(context);
+                }
+            }
+        }
+
+        return mInstance;
+    }
+
+    public BluetoothLeConnector getBluetoothLeConnector(String mac) {
+        BluetoothLeConnector result;
+        if ((result = mGattConnectorMap.get(mac)) != null) {
+            return result;
+        }
+
+        result = new BluetoothLeConnector(mContext, getMBluetoothAdapter(), mac, mBluetoothWorker);
+        mGattConnectorMap.put(mac, result);
+        return result;
+    }
+
+    public void cleanConnector(String mac) {
+        BluetoothLeConnector result;
+        if ((result = mGattConnectorMap.get(mac)) != null) {
+            mGattConnectorMap.remove(mac);
+            result.disconnect();
+            result.setOnDataAvailableListener(null);
+        }
+    }
+
+    /**
+     * 在不在需要连接蓝牙设备的时候,
+     * 或者生命周期暂停的时候调用这一个方法
+     */
+    public void cleanAllConnector() {
+        for (String mac : mGattConnectorMap.keySet()) {
+            cleanConnector(mac);
+        }
+    }
+}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeConnector.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java
similarity index 99%
rename from commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeConnector.java
rename to commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java
index fbda5e7..932280f 100644
--- a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeConnector.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeConnector.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.service;
+package com.common.bluetooth.service.ble;
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -23,7 +23,6 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import io.reactivex.rxjava3.functions.Consumer;
 
-
 /**
  * Service for managing connection and data communication with a GATT server
  * hosted on a given Bluetooth LE device.
@@ -417,8 +416,8 @@ public class BluetoothLeConnector {
 
         try {
             action.accept(gattCharacteristic);
-        } catch (Throwable e) {
-            e.printStackTrace();
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
         }
     }
 
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeSearcher.java b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeSearcher.java
similarity index 99%
rename from commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeSearcher.java
rename to commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeSearcher.java
index 6819967..fecb3fe 100644
--- a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothLeSearcher.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/ble/BluetoothLeSearcher.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.service;
+package com.common.bluetooth.service.ble;
 
 import android.Manifest;
 import android.bluetooth.BluetoothAdapter;
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCClientService.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCClientService.java
new file mode 100644
index 0000000..8c3f24c
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCClientService.java
@@ -0,0 +1,102 @@
+package com.common.bluetooth.service.bt;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.common.bluetooth.BtConstants;
+import com.common.bluetooth.callback.BtMsgListener;
+
+/**
+ * 经典蓝牙服务端
+ *
+ * @author wangym
+ * @since 2021-10-29
+ */
+public class BTCClientService extends Service {
+    private static final String TAG = "BTCClientService";
+    /**
+     * 检点蓝牙服务端
+     */
+    private BluetoothClassicClient classicClient;
+
+    /**
+     * 消息回调
+     */
+    private final BtMsgListener mMsgListener = new BtMsgListener() {
+        @Override
+        public void socketNotify(int state, @NonNull String msg) {
+            super.socketNotify(state, msg);
+            // 将内容消息透传给外部调用者
+            if (msgListener != null) {
+                msgListener.socketNotify(state, msg);
+            }
+        }
+    };
+
+    /**
+     * 消息回调
+     */
+    private BtMsgListener msgListener = null;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        Log.i(TAG, "initialize BluetoothManager");
+        classicClient = new BluetoothClassicClient(this);
+        classicClient.checkBtDevice(BtConstants.BLUETOOTH_TYPE.CLASSIC);
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new ClassicClientBinder();
+    }
+
+    public class ClassicClientBinder extends Binder {
+        public BTCClientService getService() {
+            return BTCClientService.this;
+        }
+    }
+
+    public void setMsgReceiveListener(BtMsgListener listener) {
+        msgListener = listener;
+    }
+
+    public void connect(String mac) {
+        if (classicClient == null) {
+            Log.e(TAG, "classicClient not init success");
+            return;
+        }
+        classicClient.setListener(mMsgListener);
+        classicClient.connect(mac);
+    }
+
+    /**
+     * 向客户端发送通知
+     *
+     * @param msg 消息
+     */
+    public void write(byte[] msg) {
+        Log.i(TAG, "write msg = " + new String(msg));
+        if (classicClient != null && msg != null) {
+            Log.i(TAG, "---send msg start---");
+            classicClient.sendMsg(msg);
+            Log.i(TAG, "---send msg end---");
+        } else {
+            Log.e(TAG, "got msg null");
+        }
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        classicClient.close();
+        return super.onUnbind(intent);
+    }
+}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCReceiverService.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCReceiverService.java
new file mode 100644
index 0000000..9bc8c23
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BTCReceiverService.java
@@ -0,0 +1,108 @@
+package com.common.bluetooth.service.bt;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.common.bluetooth.callback.BtMsgListener;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 经典蓝牙服务端
+ *
+ * @author wangym
+ * @since 2021-10-29
+ */
+public class BTCReceiverService extends Service {
+    private static final String TAG = "BTCReceiverService";
+    /**
+     * 检点蓝牙服务端
+     */
+    private BluetoothClassicServer classicServer;
+
+    /**
+     * 消息回调
+     */
+    private final BtMsgListener mMsgListener = new BtMsgListener() {
+        @Override
+        public void socketNotify(int state, @NonNull String msg) {
+            super.socketNotify(state, msg);
+            // 当客户端断开连接时,需要重新开始监听客户端的连接
+            if (state == BtMsgListener.DISCONNECTED) {
+                if (classicServer != null) {
+                    classicServer.listen();
+                }
+            } else if (state == BtMsgListener.MSG) {
+                // 服务端只关心内容消息
+                // 将内容消息透传给外部调用者
+                if (msgListener != null) {
+                    msgListener.socketNotify(state, msg);
+                }
+            }
+        }
+    };
+
+    /**
+     * 消息回调
+     */
+    private BtMsgListener msgListener = null;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        Log.i(TAG, "initialize BluetoothManager");
+        classicServer = new BluetoothClassicServer(this);
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (classicServer != null) {
+            classicServer.setListener(mMsgListener);
+            classicServer.listen();
+        }
+        return new ClassicReceiverBinder();
+    }
+
+    public class ClassicReceiverBinder extends Binder {
+        public BTCReceiverService getService() {
+            return BTCReceiverService.this;
+        }
+    }
+
+    public void setMsgReceiveListener(BtMsgListener listener) {
+        msgListener = listener;
+    }
+
+    /**
+     * 向客户端发送通知
+     *
+     * @param msg 消息
+     */
+    public void write(byte[] msg) {
+        Log.i(TAG, "sendNotify msg = " + new String(msg));
+        if (classicServer != null && msg != null) {
+            Log.i(TAG, "---send msg start---");
+            classicServer.sendMsg(msg);
+            Log.i(TAG, "---send msg end---");
+        } else {
+            Log.e(TAG, "got msg null");
+        }
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        if (classicServer != null) {
+            classicServer.setListener(null);
+            classicServer.close();
+        }
+        return super.onUnbind(intent);
+    }
+}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicBase.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicBase.java
new file mode 100644
index 0000000..562b9f9
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicBase.java
@@ -0,0 +1,259 @@
+package com.common.bluetooth.service.bt;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.os.Environment;
+import android.util.Log;
+
+import com.common.bluetooth.BtConstants;
+import com.common.bluetooth.callback.BtMsgListener;
+import com.common.bluetooth.service.BluetoothCommon;
+import com.common.bluetooth.utils.BtUtils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * 客户端和服务端的基类,用于管理socket长连接
+ *
+ * @author wangym
+ * @since 2.21-12-2
+ */
+public class BluetoothClassicBase extends BluetoothCommon {
+    private static final String TAG = "BluetoothClassicBase";
+    private static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/bluetooth/";
+    private static final int FLAG_MSG = 0;  //消息标记
+    private static final int FLAG_FILE = 1; //文件标记
+
+    protected BluetoothSocket mSocket;
+    private DataOutputStream mOut;
+    private BtMsgListener mListener;
+    /**
+     * 是否在读取中
+     */
+    private final AtomicBoolean isRead = new AtomicBoolean(false);
+    /**
+     * 是否在发送中
+     */
+    private final AtomicBoolean isSending = new AtomicBoolean(false);
+
+    /**
+     * 消息队列
+     */
+    private final LinkedBlockingQueue msgQueue = new LinkedBlockingQueue<>();
+
+    public BluetoothClassicBase(Context context) {
+        super(context);
+    }
+
+    /**
+     * 设置消息的监听
+     *
+     * @param mListener 监听
+     */
+    public void setListener(BtMsgListener mListener) {
+        this.mListener = mListener;
+    }
+
+    /**
+     * 循环读取对方数据(若没有数据,则阻塞等待)
+     */
+    void loopRead(BluetoothSocket socket) {
+        mSocket = socket;
+        try {
+            if (!mSocket.isConnected()) {
+                mSocket.connect();
+            }
+            String mac = mSocket.getRemoteDevice().getAddress();
+            notifyUI(BtMsgListener.CONNECTED, mac);
+            // 将链接成功的MAC地址保存下来
+            BtUtils.INSTANCE.saveConnectMac(getMContext(), mac);
+            mOut = new DataOutputStream(mSocket.getOutputStream());
+            DataInputStream in = new DataInputStream(mSocket.getInputStream());
+            isRead.set(true);
+            while (isRead.get()) { //死循环读取
+                switch (in.readInt()) {
+                    case FLAG_MSG: //读取短消息
+                        String msg = in.readUTF();
+                        Log.d(TAG, "接收短消息:" + msg);
+                        notifyUI(BtMsgListener.MSG, msg);
+                        break;
+                    case FLAG_FILE: //读取文件
+                        new File(FILE_PATH).mkdirs();
+                        String fileName = in.readUTF(); //文件名
+                        long fileLen = in.readLong(); //文件长度
+                        // 读取文件内容
+                        long len = 0;
+                        int r;
+                        byte[] b = new byte[4 * 1024];
+                        FileOutputStream out = new FileOutputStream(FILE_PATH + fileName);
+                        Log.d(TAG, "正在接收文件(" + fileName + "),请稍后...");
+                        while ((r = in.read(b)) != -1) {
+                            out.write(b, 0, r);
+                            len += r;
+                            if (len >= fileLen) {
+                                break;
+                            }
+                        }
+                        Log.d(TAG, "文件接收完成(存放在:" + FILE_PATH + ")");
+                        break;
+                }
+            }
+        } catch (Throwable e) {
+            close();
+        }
+    }
+
+    /**
+     * 发送短消息
+     */
+    public void sendMsg(byte[] msg) {
+        Log.d(TAG, "send msg");
+        if (mSocket == null || !mSocket.isConnected()) {
+            Log.e(TAG, "sendMsg got socket is not connect");
+            return;
+        }
+        msgQueue.add(msg);
+        if (checkSend()) {
+            Log.d(TAG, "sending wait");
+            return;
+        }
+        synchronized (BluetoothClassicBase.class) {
+            isSending.set(true);
+            // 循环发送消息
+            while (true) {
+                if (!doSendMsg()) {
+                    break;
+                }
+            }
+            isSending.set(false);
+        }
+    }
+
+    /**
+     * 发送消息
+     */
+    public boolean doSendMsg() {
+        final byte[] msgItem = msgQueue.poll();
+        if (msgItem == null) {
+            Log.d(TAG, "doTranslate Queue is null");
+            return false;
+        }
+        try {
+            mOut.writeInt(FLAG_MSG); //消息标记
+            mOut.writeUTF(new String(msgItem, BtConstants.INSTANCE.getDEFAULT_CHARSET()));
+            mOut.flush();
+            Log.d(TAG, "发送短消息:" + new String(msgItem, BtConstants.INSTANCE.getDEFAULT_CHARSET()));
+        } catch (Throwable e) {
+            close();
+            isSending.set(false);
+        }
+        return true;
+    }
+
+    /**
+     * 发送文件
+     */
+    public void sendFile(final String filePath) {
+        if (checkSend()) return;
+        isSending.set(true);
+        Executors.newCachedThreadPool().execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    FileInputStream in = new FileInputStream(filePath);
+                    File file = new File(filePath);
+                    mOut.writeInt(FLAG_FILE); //文件标记
+                    mOut.writeUTF(file.getName()); //文件名
+                    mOut.writeLong(file.length()); //文件长度
+                    int r;
+                    byte[] b = new byte[4 * 1024];
+                    notifyUI(BtMsgListener.MSG, "正在发送文件(" + filePath + "),请稍后...");
+                    while ((r = in.read(b)) != -1)
+                        mOut.write(b, 0, r);
+                    mOut.flush();
+                    notifyUI(BtMsgListener.MSG, "文件发送完成.");
+                } catch (Throwable e) {
+                    close();
+                }
+                isSending.set(false);
+            }
+        });
+    }
+
+    /**
+     * 关闭Socket连接
+     */
+    public void close() {
+        Log.d(TAG, "close");
+        try {
+            String mac = "";
+            isRead.set(false);
+            if (mSocket != null) {
+                mSocket.close();
+                mac = mSocket.getRemoteDevice().getAddress();
+            }
+            notifyUI(BtMsgListener.DISCONNECTED, mac);
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 无回调关闭Socket
+     */
+    public void closeSilence(){
+        Log.d(TAG, "closeSilence");
+        try {
+            isRead.set(false);
+            if (mSocket != null) {
+                mSocket.close();
+            }
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 当前设备与指定设备是否连接
+     *
+     * @param mac 设备MAC地址
+     * @return 是否已经和对应设备拦截
+     */
+    public boolean isConnected(String mac) {
+        BluetoothDevice dev = getBtDeviceByMac(mac);
+        boolean connected = (mSocket != null && mSocket.isConnected());
+        if (dev == null) {
+            return connected;
+        }
+        return connected && mSocket.getRemoteDevice().equals(dev);
+    }
+
+    /**
+     * 是否在发送中
+     *
+     * @return 是否发送中
+     */
+    private synchronized boolean checkSend() {
+        return isSending.get();
+    }
+
+    /**
+     * 通知外部接收信息
+     *
+     * @param state 消息类型
+     * @param msg   消息内容
+     */
+    protected void notifyUI(final int state, final String msg) {
+        if (mListener != null) {
+            mListener.socketNotify(state, msg);
+        }
+    }
+}
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicClient.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicClient.java
new file mode 100644
index 0000000..adb25b9
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicClient.java
@@ -0,0 +1,56 @@
+package com.common.bluetooth.service.bt;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.util.Log;
+
+import com.common.bluetooth.BtConstants;
+import com.common.bluetooth.callback.BtMsgListener;
+
+import java.util.concurrent.Executors;
+
+/**
+ * 经典蓝牙客户端,与服务端建立长连接
+ *
+ * @author wangym
+ * @since 2021-12-1
+ */
+public class BluetoothClassicClient extends BluetoothClassicBase {
+    private static final String TAG = "BtClient";
+
+    public BluetoothClassicClient(Context context) {
+        super(context);
+    }
+
+    /**
+     * 与远端设备建立长连接
+     *
+     * @param mac 设备MAC
+     */
+    public void connect(String mac) {
+        Log.d(TAG, "start connect mac:" + mac);
+        BluetoothDevice bluetoothDevice = getBtDeviceByMac(mac);
+        if (bluetoothDevice == null) {
+            Log.e(TAG, "connect got device is null : mac is " + mac);
+            notifyUI(BtMsgListener.DISCONNECTED, mac);
+            return;
+        }
+        if (isConnected(mac)) {
+            Log.i(TAG, "connected, no need to close socket");
+            return;
+        }
+        closeSilence();
+        try {
+//             final BluetoothSocket socket = dev.createRfcommSocketToServiceRecord(SPP_UUID); //加密传输,Android系统强制配对,弹窗显示配对码
+            final BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(
+                    BtConstants.INSTANCE.getCLASSIC_BT_UUID()); //明文传输(不安全),无需配对
+            // 开启子线程
+            Executors.newCachedThreadPool().execute(() -> {
+                loopRead(socket); //循环读取
+            });
+        } catch (Throwable e) {
+            close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothClassicSearcher.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicSearcher.java
similarity index 96%
rename from commonbt/src/main/java/com/common/bluetooth/service/BluetoothClassicSearcher.java
rename to commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicSearcher.java
index 2688e3e..cced34c 100644
--- a/commonbt/src/main/java/com/common/bluetooth/service/BluetoothClassicSearcher.java
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicSearcher.java
@@ -1,4 +1,4 @@
-package com.common.bluetooth.service;
+package com.common.bluetooth.service.bt;
 
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicServer.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicServer.java
new file mode 100644
index 0000000..6769ce2
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClassicServer.java
@@ -0,0 +1,59 @@
+package com.common.bluetooth.service.bt;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+
+import com.common.bluetooth.BtConstants;
+
+import java.util.concurrent.Executors;
+
+/**
+ * 服务端监听和连接线程,只连接一个设备
+ *
+ * @author wangym
+ * @version 2021-12-2
+ */
+public class BluetoothClassicServer extends BluetoothClassicBase {
+    private static final String TAG = BluetoothClassicServer.class.getSimpleName();
+    private BluetoothServerSocket mSSocket;
+
+    BluetoothClassicServer(Context context) {
+        super(context);
+    }
+
+    /**
+     * 监听客户端发起的连接
+     */
+    public void listen() {
+        try {
+            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+//            mSSocket = adapter.listenUsingRfcommWithServiceRecord(TAG, SPP_UUID); //加密传输,Android强制执行配对,弹窗显示配对码
+            mSSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(TAG,
+                    BtConstants.INSTANCE.getCLASSIC_BT_UUID()); //明文传输(不安全),无需配对
+            // 开启子线程
+            Executors.newCachedThreadPool().execute(() -> {
+                try {
+                    BluetoothSocket socket = mSSocket.accept(); // 监听连接
+                    mSSocket.close(); // 关闭监听,只连接一个设备
+                    loopRead(socket); // 循环读取
+                } catch (Throwable e) {
+                    close();
+                }
+            });
+        } catch (Throwable e) {
+            close();
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            mSSocket.close();
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        super.close();
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..076f227
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BluetoothClientClassicAdapter.kt
@@ -0,0 +1,98 @@
+package com.common.bluetooth.service.bt
+
+import android.bluetooth.BluetoothDevice
+import com.common.bluetooth.BtConstants
+import com.common.bluetooth.callback.BaseResultCallback
+import com.common.bluetooth.interfaces.IBluetoothClient
+import io.reactivex.rxjava3.core.Observable
+import java.util.UUID
+
+/**
+ * 经典蓝牙适配器
+ *
+ * @author wangym
+ * @since 2021-12-1
+ */
+class BluetoothClientClassicAdapter(private var mClient: BluetoothClassicClient) :
+    IBluetoothClient {
+    val TAG = "BluetoothClientAdapter"
+
+    override fun search(millis: Long, cancel: Boolean): Observable {
+        return Observable.create {
+            mClient.getBluetoothSearcher().startScan(millis, null)
+            it.onComplete()
+        }
+    }
+
+    override fun stopSearch() {
+        mClient.getBluetoothSearcher().stopScan()
+    }
+
+    override fun connect(mac: String): Observable {
+        return Observable.create {
+            if (!mClient.isConnected((mac))) {
+                mClient.connect(mac)
+            }
+            it.onNext(mac)
+            it.onComplete()
+        }
+    }
+
+    override fun disconnect(mac: String) {
+        mClient.close()
+    }
+
+    override fun write(
+        mac: String,
+        service: UUID,
+        characteristic: UUID,
+        values: ByteArray
+    ): Observable? {
+        return Observable.create {
+            if (!mClient.isConnected((mac))) {
+                mClient.sendMsg(values)
+            }
+            it.onNext(mac)
+            it.onComplete()
+        }
+    }
+
+    override fun checkBluetoothDevice(type: BtConstants.BLUETOOTH_TYPE): Boolean {
+        return mClient.checkBtDevice(type)
+    }
+
+    override fun openBluetooth() {
+        mClient.openBt()
+    }
+
+    override fun closeBluetooth(): Boolean {
+        return mClient.closeBt()
+    }
+
+    override fun getBondedDevices(): Set? {
+        return mClient.getBondedDevices()
+    }
+
+    override fun registerNotify(
+        mac: String,
+        service: UUID,
+        characteristic: UUID,
+        callback: BaseResultCallback?
+    ): Observable {
+        return Observable.create {}
+    }
+
+    override fun unRegisterNotify(
+        mac: String,
+        service: UUID,
+        characteristic: UUID
+    ): Observable? {
+        return null
+    }
+
+    override fun clean(mac: String) {
+    }
+
+    override fun cleanAll() {
+    }
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/service/bt/BtReceiver.java b/commonbt/src/main/java/com/common/bluetooth/service/bt/BtReceiver.java
new file mode 100644
index 0000000..b1fe75f
--- /dev/null
+++ b/commonbt/src/main/java/com/common/bluetooth/service/bt/BtReceiver.java
@@ -0,0 +1,94 @@
+package com.common.bluetooth.service.bt;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+/**
+ * 监听蓝牙广播-各种状态
+ */
+public class BtReceiver extends BroadcastReceiver {
+    private static final String TAG = BtReceiver.class.getSimpleName();
+    private final Listener mListener;
+
+    public BtReceiver(Context cxt, Listener listener) {
+        mListener = listener;
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙开关状态
+        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//蓝牙开始搜索
+        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//蓝牙搜索结束
+
+        filter.addAction(BluetoothDevice.ACTION_FOUND);//蓝牙发现新设备(未配对的设备)
+        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);//在系统弹出配对框之前(确认/输入配对码)
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//设备配对状态改变
+        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);//最底层连接建立
+        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);//最底层连接断开
+
+        filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); //BluetoothAdapter连接状态
+        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); //BluetoothHeadset连接状态
+        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); //BluetoothA2dp连接状态
+        cxt.registerReceiver(this, filter);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (action == null)
+            return;
+        Log.i(TAG, "===" + action);
+        BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+        if (dev != null)
+            Log.i(TAG, "BluetoothDevice: " + dev.getName() + ", " + dev.getAddress());
+        switch (action) {
+            case BluetoothAdapter.ACTION_STATE_CHANGED:
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
+                Log.i(TAG, "STATE: " + state);
+                break;
+            case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
+                break;
+            case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
+                break;
+
+            case BluetoothDevice.ACTION_FOUND:
+                short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MAX_VALUE);
+                Log.i(TAG, "EXTRA_RSSI:" + rssi);
+                mListener.foundDev(dev);
+                break;
+            case BluetoothDevice.ACTION_PAIRING_REQUEST: //在系统弹出配对框之前,实现自动配对,取消系统配对框
+                /*try {
+                    abortBroadcast();//终止配对广播,取消系统配对框
+                    boolean ret = dev.setPin("1234".getBytes()); //设置PIN配对码(必须是固定的)
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }*/
+                break;
+            case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
+                Log.i(TAG, "BOND_STATE: " + intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0));
+                break;
+            case BluetoothDevice.ACTION_ACL_CONNECTED:
+                break;
+            case BluetoothDevice.ACTION_ACL_DISCONNECTED:
+                break;
+
+            case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
+                Log.i(TAG, "CONN_STATE: " + intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, 0));
+                break;
+            case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+                Log.i(TAG, "CONN_STATE: " + intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0));
+                break;
+            case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+                Log.i(TAG, "CONN_STATE: " + intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, 0));
+                break;
+        }
+    }
+
+    public interface Listener {
+        void foundDev(BluetoothDevice dev);
+    }
+}
\ No newline at end of file
diff --git a/commonbt/src/main/java/com/common/bluetooth/BtUtils.kt b/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt
similarity index 99%
rename from commonbt/src/main/java/com/common/bluetooth/BtUtils.kt
rename to commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt
index e17ee9f..bc73922 100644
--- a/commonbt/src/main/java/com/common/bluetooth/BtUtils.kt
+++ b/commonbt/src/main/java/com/common/bluetooth/utils/BtUtils.kt
@@ -1,4 +1,4 @@
-package com.common.bluetooth
+package com.common.bluetooth.utils
 
 import android.content.Context
 import android.content.SharedPreferences
@@ -113,6 +113,11 @@ object BtUtils {
      */
     const val MOD_I_CN = "6"
 
+    /**
+     * 设置
+     */
+    const val MOD_S = "7"
+
     /**
      * 中间包
      */
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