|
@@ -1,32 +1,32 @@
|
|
|
package com.luojigou.xiaodou
|
|
|
|
|
|
import android.Manifest
|
|
|
-import android.annotation.SuppressLint
|
|
|
import android.bluetooth.BluetoothAdapter
|
|
|
import android.bluetooth.BluetoothManager
|
|
|
-import android.bluetooth.le.ScanCallback
|
|
|
-import android.bluetooth.le.ScanFilter
|
|
|
-import android.bluetooth.le.ScanResult
|
|
|
-import android.bluetooth.le.ScanSettings
|
|
|
import android.content.BroadcastReceiver
|
|
|
+import android.content.ComponentName
|
|
|
import android.content.Context
|
|
|
import android.content.Intent
|
|
|
import android.content.IntentFilter
|
|
|
+import android.content.ServiceConnection
|
|
|
import android.content.pm.PackageManager
|
|
|
import android.os.Build
|
|
|
import android.os.Bundle
|
|
|
+import android.os.IBinder
|
|
|
import android.util.Log
|
|
|
-import android.view.View
|
|
|
-import android.widget.Button
|
|
|
-import android.widget.ProgressBar
|
|
|
-import android.widget.TextView
|
|
|
-import androidx.activity.result.contract.ActivityResultContracts
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
|
+import androidx.bluetooth.BluetoothDevice
|
|
|
+import androidx.bluetooth.BluetoothLe
|
|
|
import androidx.core.app.ActivityCompat
|
|
|
-import androidx.recyclerview.widget.RecyclerView
|
|
|
+import androidx.fragment.app.Fragment
|
|
|
+import com.luojigou.xiaodou.ble.XDScanBLEDisableFragment
|
|
|
+import com.luojigou.xiaodou.ble.XDScanBLENormalFragment
|
|
|
+import com.luojigou.xiaodou.ble.XDScanBLENotSupportFragment
|
|
|
+import com.luojigou.xiaodou.ble.XDScanBLEPermissionFragment
|
|
|
+import com.luojigou.xiaodou.ble.XDScanBLEStatus
|
|
|
|
|
|
|
|
|
-class XDScanBLEActivity : AppCompatActivity() {
|
|
|
+class XDScanBLEActivity : AppCompatActivity(), XDScanBLEStatus.Host {
|
|
|
private val permissions: Array<String> by lazy {
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
|
arrayOf(
|
|
@@ -41,10 +41,17 @@ class XDScanBLEActivity : AppCompatActivity() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private lateinit var txtMsg: TextView
|
|
|
- private lateinit var btnScan: Button
|
|
|
- private lateinit var listview: RecyclerView
|
|
|
- private lateinit var progress: ProgressBar
|
|
|
+ private val disableFragment = XDScanBLEDisableFragment(this)
|
|
|
+ private val normalFragment = XDScanBLENormalFragment(this)
|
|
|
+ private val permissionFragment = XDScanBLEPermissionFragment(this)
|
|
|
+ private val notsupportFragment = XDScanBLENotSupportFragment(this)
|
|
|
+
|
|
|
+
|
|
|
+ private val bluetoothManager: BluetoothManager by lazy {
|
|
|
+ getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
|
|
|
+ }
|
|
|
+
|
|
|
+ private var bluetoothBinder: XDScanBLEService.XDScanBLEBinder? = null
|
|
|
|
|
|
private val broadcastReceiver by lazy {
|
|
|
object : BroadcastReceiver() {
|
|
@@ -58,12 +65,12 @@ class XDScanBLEActivity : AppCompatActivity() {
|
|
|
|
|
|
when (currentState) {
|
|
|
BluetoothAdapter.STATE_OFF -> { // 蓝牙已关闭
|
|
|
- maybeSetupBluetooth()
|
|
|
+ checkBluetoothPermissionAndEnable()
|
|
|
Log.d("BLEStateBroadcastReceiver", "onReceive: Bluetooth is off")
|
|
|
}
|
|
|
|
|
|
BluetoothAdapter.STATE_ON -> { // 蓝牙已打开
|
|
|
- maybeSetupBluetooth()
|
|
|
+ checkBluetoothPermissionAndEnable()
|
|
|
Log.d("BLEStateBroadcastReceiver", "onReceive: Bluetooth is on")
|
|
|
}
|
|
|
|
|
@@ -79,52 +86,13 @@ class XDScanBLEActivity : AppCompatActivity() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private val bluetoothManager: BluetoothManager by lazy {
|
|
|
- getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
|
|
|
- }
|
|
|
-
|
|
|
- private var bluetoothAdapter: BluetoothAdapter? = null
|
|
|
-
|
|
|
- private val requestMultiplePermissionLauncher by lazy {
|
|
|
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
|
|
|
- if (it.all { permission -> permission.value }) {
|
|
|
- maybeSetupBluetooth()
|
|
|
- } else {
|
|
|
- setStatus(XDScanBLEStatus.Permission)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private val scanCallback = object : ScanCallback() {
|
|
|
- override fun onScanResult(callbackType: Int, result: ScanResult) {
|
|
|
- super.onScanResult(callbackType, result)
|
|
|
- logScanResult(result)
|
|
|
+ private val bleConnection = object : ServiceConnection {
|
|
|
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
|
|
+ bluetoothBinder = service as XDScanBLEService.XDScanBLEBinder?
|
|
|
}
|
|
|
|
|
|
- override fun onBatchScanResults(results: MutableList<ScanResult>) {
|
|
|
- super.onBatchScanResults(results) // 如果需要处理批量扫描结果,可以在此处进行
|
|
|
-
|
|
|
- results.forEach { result -> logScanResult(result) }
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressLint("MissingPermission")
|
|
|
- private fun logScanResult(result: ScanResult) {
|
|
|
- val device = result.device
|
|
|
- val deviceName = device.name ?: "Unknown"
|
|
|
- val deviceAddress = device.address
|
|
|
- val rssi = result.rssi
|
|
|
-
|
|
|
- // Log.d(
|
|
|
- // "XDScanBLEService",
|
|
|
- // "发现BLE设备: 名称 - $deviceName, 地址 - $deviceAddress, 信号强度 - $rssi"
|
|
|
- // )
|
|
|
- adapter.addValue(result)
|
|
|
- }
|
|
|
-
|
|
|
- override fun onScanFailed(errorCode: Int) {
|
|
|
- super.onScanFailed(errorCode)
|
|
|
- Log.w("XDScanBLEService", "BLE扫描失败,错误代码: $errorCode") // 根据错误码处理扫描失败情况
|
|
|
+ override fun onServiceDisconnected(name: ComponentName?) {
|
|
|
+ bluetoothBinder = null
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -133,112 +101,64 @@ class XDScanBLEActivity : AppCompatActivity() {
|
|
|
super.onCreate(savedInstanceState)
|
|
|
setContentView(R.layout.activity_scanble)
|
|
|
|
|
|
+ checkBluetoothPermissionAndEnable()
|
|
|
+ bindService(Intent(this, XDScanBLEService::class.java), bleConnection, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onResume() {
|
|
|
+ super.onResume()
|
|
|
registerReceiver(broadcastReceiver, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
|
|
|
+ checkBluetoothPermissionAndEnable()
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onPause() {
|
|
|
+ unregisterReceiver(broadcastReceiver)
|
|
|
+ super.onPause()
|
|
|
}
|
|
|
|
|
|
- private fun checkBluetoothPermission() {
|
|
|
+ private fun checkBluetoothPermissionAndEnable() {
|
|
|
val bluetoothAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
|
|
|
val bluetoothLEAvailable =
|
|
|
packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
|
|
|
|
|
|
if (!bluetoothAvailable || !bluetoothLEAvailable) {
|
|
|
- setStatus(XDScanBLEStatus.NotSupported)
|
|
|
+ setFragment(notsupportFragment)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- val checkResult = permissions.find {
|
|
|
- ActivityCompat.checkSelfPermission(
|
|
|
- this, it
|
|
|
- ) != PackageManager.PERMISSION_GRANTED
|
|
|
+ if (permissions.find {
|
|
|
+ ActivityCompat.checkSelfPermission(
|
|
|
+ this, it
|
|
|
+ ) != PackageManager.PERMISSION_GRANTED
|
|
|
+ } != null) {
|
|
|
+ setFragment(permissionFragment)
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
- if (checkResult != null) {
|
|
|
- requestMultiplePermissionLauncher.launch(permissions)
|
|
|
- } else {
|
|
|
- maybeSetupBluetooth()
|
|
|
+ if (bluetoothManager.adapter == null || !bluetoothManager.adapter.isEnabled) {
|
|
|
+ setFragment(disableFragment)
|
|
|
+ return
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- @SuppressLint("MissingPermission")
|
|
|
- private fun maybeSetupBluetooth() {
|
|
|
- bluetoothAdapter = bluetoothManager.adapter
|
|
|
-
|
|
|
- if (bluetoothAdapter == null || !bluetoothAdapter!!.isEnabled) {
|
|
|
- setStatus(XDScanBLEStatus.Disabled)
|
|
|
- val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
|
|
|
- startActivity(enableBtIntent)
|
|
|
- } else {
|
|
|
- setStatus(XDScanBLEStatus.Waiting)
|
|
|
- }
|
|
|
+ setFragment(normalFragment)
|
|
|
}
|
|
|
|
|
|
- @SuppressLint("MissingPermission")
|
|
|
- private fun startScanBle() {
|
|
|
- val settings =
|
|
|
- ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // 或选择其他适合的扫描模式
|
|
|
- .build()
|
|
|
-
|
|
|
- val filters = mutableListOf<ScanFilter>() // 可以添加过滤条件,如特定的服务UUID等
|
|
|
-
|
|
|
- try {
|
|
|
- bluetoothAdapter?.bluetoothLeScanner?.startScan(filters, settings, scanCallback)
|
|
|
- } catch (e: Exception) {
|
|
|
- Log.e("XDScanBLEService", "startScanBle error: ${e.message}")
|
|
|
+ private fun setFragment(fragment: Fragment) {
|
|
|
+ val fragmentManager = supportFragmentManager;
|
|
|
+ val beginTransaction = fragmentManager.beginTransaction()
|
|
|
+ if (fragmentManager.findFragmentById(R.id.fragment_container) == null) {
|
|
|
+ beginTransaction.add(R.id.fragment_container, fragment)
|
|
|
+ } else {
|
|
|
+ beginTransaction.replace(R.id.fragment_container, fragment)
|
|
|
}
|
|
|
+ beginTransaction.commit()
|
|
|
}
|
|
|
|
|
|
+ override fun onStatusChanged(status: XDScanBLEStatus) = checkBluetoothPermissionAndEnable()
|
|
|
+ override fun getBluetooth(): BluetoothLe =
|
|
|
+ bluetoothBinder?.getBluetooth() ?: throw IllegalStateException("蓝牙初始化失败")
|
|
|
|
|
|
- override fun onDestroy() {
|
|
|
- unregisterReceiver(broadcastReceiver)
|
|
|
- super.onDestroy()
|
|
|
- }
|
|
|
-
|
|
|
- private fun setStatus(status: XDScanBLEStatus) {
|
|
|
- when (status) {
|
|
|
- XDScanBLEStatus.Idle -> {
|
|
|
- btnScan.visibility = View.GONE
|
|
|
- listview.visibility = View.GONE
|
|
|
- progress.visibility = View.GONE
|
|
|
- txtMsg.visibility = View.GONE
|
|
|
- }
|
|
|
-
|
|
|
- XDScanBLEStatus.Permission -> {
|
|
|
- btnScan.visibility = View.GONE
|
|
|
- listview.visibility = View.GONE
|
|
|
- progress.visibility = View.GONE
|
|
|
- txtMsg.visibility = View.VISIBLE
|
|
|
- txtMsg.text = "蓝牙权限申请失败,请手动设置权限"
|
|
|
- }
|
|
|
-
|
|
|
- XDScanBLEStatus.Disabled -> {
|
|
|
- btnScan.visibility = View.GONE
|
|
|
- listview.visibility = View.GONE
|
|
|
- progress.visibility = View.GONE
|
|
|
- txtMsg.visibility = View.VISIBLE
|
|
|
- txtMsg.text = "蓝牙未开启,请开启蓝牙"
|
|
|
- }
|
|
|
-
|
|
|
- XDScanBLEStatus.NotSupported -> {
|
|
|
- btnScan.visibility = View.GONE
|
|
|
- listview.visibility = View.GONE
|
|
|
- progress.visibility = View.GONE
|
|
|
- txtMsg.visibility = View.VISIBLE
|
|
|
- txtMsg.text = "当前设备不支持蓝牙配对"
|
|
|
- }
|
|
|
-
|
|
|
- XDScanBLEStatus.Waiting -> {
|
|
|
- btnScan.visibility = View.VISIBLE
|
|
|
- listview.visibility = View.GONE
|
|
|
- progress.visibility = View.GONE
|
|
|
- txtMsg.visibility = View.GONE
|
|
|
- }
|
|
|
-
|
|
|
- XDScanBLEStatus.Scanning -> {
|
|
|
- btnScan.visibility = View.GONE
|
|
|
- listview.visibility = View.VISIBLE
|
|
|
- progress.visibility = View.VISIBLE
|
|
|
- txtMsg.visibility = View.GONE
|
|
|
- }
|
|
|
- }
|
|
|
+ override suspend fun connectBluetooth(device: BluetoothDevice): Boolean {
|
|
|
+ bluetoothBinder?.connectGatt(device)
|
|
|
}
|
|
|
}
|