android - 如何在 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,我尝试使用它,但它没有达到我想要的效果。
解决方案
您必须在清单文件中添加权限
<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)
}
推荐阅读
- google-chrome - 检查中的控制台是否危险?
- php - 使一维数组多维
- python - 为数据的唯一组合生成日期
- angular - 为 API 请求设置标头时遇到问题,设置为接受 'application/json',但发送 'application/json, text/plain, */*'
- azure - Azure 函数是否支持 Cosmos DB 与 Mongo Api 的绑定?除了使用 MongoClient 是否有任何解决方法
- jquery - 日期格式不起作用或无法在网站上加载
- javascript - 使用 JavaScript 和 asp.net 核心从数据库中删除现有图像
- sql - 根据组内连续两天将指标列添加到表中
- python - Python 中的 % 或 .format 运算符的 C++ 等价物是什么?
- go - 如何获取 go 包的实际存储库 url