我正在尝试使用startScan(filters, settings, callbackIntent)扫描信标。我有一个适用于Sony Xperia XZ和Nexus 5X的实现。我唯一拥有Android O的其他设备是三星Galaxy S8,其他设备的功能在三星上什么都没有。 (蓝牙扫描实际上是嵌入在库模块中,但即使在创建虚拟应用程序时,三星也会失败,因此我将在此示例中使用它)。我删除了过滤器和用于s3-deploy
的设置,因为无论如何扫描都不起作用,这些都是可选的。
startScan
的PendingIntent:
MainActivity
- checks and asks for permissions (ACCESS_COARSE_LOCATION)
- simplified onStart
override fun onStart() {
super.onStart()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val startScan = bleScanner.startScan(null, null, getPendingIntent())
Log.d("testApp", "Start scan! ${startScan == 0}")
}
}
清单
权限:
private fun getPendingIntent(): PendingIntent {
return PendingIntent.getBroadcast(
this, REQ_CODE,
Intent(this.applicationContext, BleReceiver::class.java),
PendingIntent.FLAG_UPDATE_CURRENT)
}
接收器:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
接收者实施:
<receiver android:name="com.testapp.samsungoscan.BleReceiver" >
<intent-filter>
<action android:name="BluetoothDevice.ACTION_FOUND" />
<action android:name="BluetoothDevice.EXTRA_UUID" />
<action android:name="BluetoothDevice.EXTRA_RSSI" />
</intent-filter>
</receiver>
原来如此!为什么这不适用于三星,而它适用于索尼和Nexus?
注意:如果我将接收器class BleReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.e("testApp", "On Receive!")
}
}
更改为相对路径android:name
而不是.BleReceiver
,则Nexus会停止工作,但索尼仍然有效!
通过工作我的意思是所有类都被使用并且日志被触发。 有什么问题?
答案 0 :(得分:1)
您已使用意图过滤器名称在AndroidManifest.xml中注册了广播接收器
<action android:name="BluetoothDevice.ACTION_FOUND" />
首先,您可以在此处提供任何String。以上建议您使用this constant,但实际上您只是按原样使用String(BluetoothDevice.ACTION_FOUND
)。我建议将其更改为某些com.testapp.samsungoscan.ACTION_FOUND
。不需要附加功能,它们暗示它们实际上是附加功能,但它们只是名称为“ extra”的另一个动作名称。
我建议更改为:
<receiver android:name="com.testapp.samsungoscan.BleReceiver">
<intent-filter>
<action android:name="com.testapp.samsungoscan.ACTION_FOUND" />
</intent-filter>
</receiver>
第二,您必须使用以下操作名称创建PendingIntent:
private fun getPendingIntent(): PendingIntent {
return PendingIntent.getBroadcast(
this, REQ_CODE,
Intent(this.applicationContext, BleReceiver::class.java).setAction("com.testapp.samsungoscan.ACTION_FOUND"),
PendingIntent.FLAG_UPDATE_CURRENT)
}
需要创建一个提供组件名称的意图,因为Oreo能够获得任何广播。但是,我不确定在您的应用被系统杀死之后是否可以正常工作。
最后,我建议您请求FINE_LOCATION,因为:https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/848935的更改将来可能需要精确的位置许可才能扫描蓝牙设备。
答案 1 :(得分:0)
您需要将一个空的过滤器列表传递给startScan()调用,而不是null
DISTINCT
答案 2 :(得分:0)
啊,除了将空过滤器传递给startScan之外,您还需要最新Android版本的ACCESS_FINE_LOCATION权限。