android - 使用 startDiscovery 扫描蓝牙设备但未找到设备
问题描述
我在 Kotlin 中编写并能够设置一个接收器来处理由 startDiscovery 引起的 ACTION_DISCOVERY_STARTED 和 ACTION_DISCOVERY_FINISHED 事件(我将消息打印到文本视图并查看它们是否有效)。
但是,ACTION_FOUND 永远不会在接收器中被调用(当应该找到设备时,我从未看到我在该例程中更新的文本视图更改)。
我拥有清单中的所有权限(以及更多权限):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test_ble">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Test_BLE">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
我有两个文本视图。text_view1 用于报告扫描状态,text_view2 用于放置扫描设备列表。这些设备(目前很粗略)只是连接到一个字符串,然后分配给 text_view2.text。但是,我从未看到该列表得到更新。
我知道房间里还有其他蓝牙设备在做广告,因为我可以在华硕 Nexus 7 平板电脑(Android 6.1)上看到它们,我用它来测试蓝牙设备设置下的代码。
minSdk 在 21 时应该足够低。这是 buildgradle 模块脚本:
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.test_ble"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures{
viewBinding = true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
这是 MainActivity.kt 文件。
package com.example.test_ble
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.test_ble.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var btAdapter: BluetoothAdapter
private var deviceList: String = ""
// *****************************************************
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Get the BluetoothAdapter
btAdapter = BluetoothAdapter.getDefaultAdapter()
if (btAdapter == null) {
binding.textView1.text = "No Bt Adapter!"
} else if (!btAdapter.isEnabled) {
binding.textView1.text = "Bt Adapter is NOT ENABLED!"
} else {
binding.textView1.text = "Bt Adapter is ENABLED!"
// Build receiver for Device Discovery
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
BluetoothAdapter.ACTION_DISCOVERY_STARTED -> {
// Device discovery started, show loading indication
binding.textView1.text = "Device discovery started"
}
BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
// unregister receiver and hide loading indication
binding.textView1.text = "Device discovery finished"
}
BluetoothDevice.ACTION_FOUND -> {
binding.textView1.text = "ACTION_FOUND" // I never see this message
val device: BluetoothDevice? =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
val deviceName = device?.name
val deviceHardwareAddress = device?.address // MAC address
deviceList =
deviceList + "\n" + deviceName.toString() + " " + deviceHardwareAddress.toString()
binding.textView2.text = deviceList // The device list is never updated
}
}
}
}
// Register for broadcasts when a device is discovered.
val intentFilter = IntentFilter().apply {
addAction(BluetoothDevice.ACTION_FOUND)
addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
}
if (btAdapter.isDiscovering()) {
btAdapter.cancelDiscovery();
}
registerReceiver(receiver, intentFilter)
btAdapter.startDiscovery()
}
}
}
谁能看到我错过了什么或做错了什么?当我确实看到发现的开始和结束确实发生时,我不明白为什么我没有检测到任何设备。在搜索并尝试了我在网上可以找到的所有内容后,我没有想法。非常感谢帮助。
吉姆
解决方案
您已在中声明了权限,Manifest
但您是否要求用户允许ACCESS_FINE_LOCATION
&ACCESS_COARSE_LOCATION
权限?或者您可以通过转到设置中的应用信息然后尝试发现设备来允许这些权限。如果您的应用能够发现,那么您可能需要询问runtime permissions
用户。
推荐阅读
- gitlab - gitlab-runner 在哪里下载作业工件 zip 文件?
- android - 如何在 Kony 应用程序中执行逻辑,具体取决于它是在 iOS、Android 还是 Web 浏览器上运行
- r - plot_ly 曲面图轴不涵盖所有值范围
- r - R中马尔可夫链的手动模拟
- r - How to sum specific rows in a dataframe using R?
- java - checking name in list it is there than update client table else category and client table
- c# - Is there any alternative to DragOver to suppress glyph on drag drop?
- python - How can i break a for-loop with an key event?
- rust - 包 XXX 链接到本机库 YYY,但它与之前也链接到 YYY 的包冲突:package ZZZ
- php - 为多个时间范围设置 PHP cronjob