首页 > 解决方案 > 如何在 Kotlin 的 onResume 函数中启用/禁用蓝牙?

问题描述

我正在编写一个 android 应用程序来管理和控制我自己的智能设备,这些设备将通过 BLE 连接到该应用程序。

我对此真的很陌生,到目前为止,我设法创建了一个名为“ADD DEVICE”的按钮,它将我重定向到 ScanningForDevicesActivity,这是一个负责扫描 BLE 设备并显示已发现设备列表的活动(尚未完成)。

这是我想要实现的响应流程: -> 按添加设备并转到 ScanningForDevicesActivity -> 如果未启用蓝牙 -> ACTION_REQUEST_ENABLE -> 如果请求被拒绝(结果代码:RESULT_CANCELED)然后返回 MainActivity -> 如果蓝牙已启用,然后在应用程序处于活动状态时从外部禁用(从手机),然后提示意图 ACTION_REQUEST_ENABLE

假设我根据请求启用了蓝牙,然后我禁用了它,但是如果我在 ScanningForDevicesActivity 上,我希望应用程序再次请求 REQUEST_BLUETOOTH_ENABLE 从手机(不是我的应用程序)。

问题是,如果我将此代码放在此当前活动的 onResume 函数上,由于此函数会定期运行,因此会重复启用蓝牙的请求,这意味着在请求启用蓝牙时我必须按两次 DENY 或 ACCEPT。但是,这在外部禁用蓝牙时不起作用。当我这样做时,活动什么也不做,即使我在 onResume 函数中编写了这种情况。

我尝试使用布尔值来管理这些情况,但 onResume 函数非常快,以至于它在设置任何布尔值之前运行。

这是我的 ScanningForDevicesActivity 的 Kotlin 代码:

class ScanningForDevicesActivity : AppCompatActivity() {
    private lateinit var binding: ActivityScanningForDevicesBinding

    private var bluetoothWasDenied: Boolean = false

    companion object{
        val BLUETOOTH_REQUEST_CODE = 1
    }

    private val bluetoothAdapter: BluetoothAdapter by lazy {
        val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothManager.adapter
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scanning_for_devices)

        bluetoothWasDenied = false

        binding = ActivityScanningForDevicesBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        if(!bluetoothAdapter.isEnabled){
            promptEnableBluetooth()
        }

    }

    override fun onResume() {
        super.onResume()
        if(!bluetoothAdapter.isEnabled){
            promptEnableBluetooth()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == BLUETOOTH_REQUEST_CODE){
            if (resultCode == Activity.RESULT_CANCELED){
                bluetoothWasDenied = true
                val goMainActivityIntent = Intent(this, MainActivity::class.java)
                startActivity(goMainActivityIntent)
            }
        }
    }

    private fun promptEnableBluetooth(){
        if(!bluetoothAdapter.isEnabled){
            val enableBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableBluetoothIntent, BLUETOOTH_REQUEST_CODE)
        }
    }
}

PS:不要介意 bluetoothWasDenied var,我尝试使用它,但它没有达到我想要的效果。

标签: androidkotlinbluetoothbluetooth-lowenergy

解决方案


您必须在清单文件中添加权限

 <uses-permission android:name="android.permission.BLUETOOTH" />

之后,您必须在广播接收器打开和关闭时收听更改

  private val bluetoothReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val action = intent?.action
        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
            val state = intent?.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
            when (state) {
                BluetoothAdapter.STATE_OFF -> {
                }
                BluetoothAdapter.STATE_TURNING_OFF -> {
                }
                BluetoothAdapter.STATE_ON -> {
                }
                BluetoothAdapter.STATE_TURNING_ON -> {
                }
            }

        }

    }
}

注册它 onCreate 方法

 fun registerBroadCast(){
    val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
    registerReceiver(bluetoothReceiver, filter)
}

最后在 onDestroy 中取消注册

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(bluetoothReceiver)
}

推荐阅读