【问题标题】:Oreo, BLE scanner startScan with PendingIntent not working on Samsung deviceOreo,带有 PendingIntent 的 BLE 扫描仪 startScan 无法在三星设备上运行
【发布时间】:2018-05-09 07:49:44
【问题描述】:

我正在尝试使用startScan(filters, settings, callbackIntent) 扫描信标。我有一个适用于 Sony Xperia XZ 和 Nexus 5X 的实现。我唯一可用的其他带有 Android O 的设备是三星 Galaxy S8,适用于其他设备的设备在三星上没有任何效果。 (蓝牙扫描确实嵌入在库模块中,但即使在创建虚拟应用程序时,三星也会失败,因此我将在此示例中使用它)。我已经删除了过滤器和用于startScan 的设置,因为没有它们扫描就无法工作,这些都是可选的。

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>

接收器实现:

class BleReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.e("testApp", "On Receive!")
    }
}

所以!为什么这不适用于三星,而它适用于索尼和 Nexus? 注意:如果我将接收器 android:name 更改为相对路径 .BleReceiver 而不是 com.testapp.samsungoscan.BleReceiver,则 Nexus 停止工作,但 Sony 仍然工作!

工作是指所有类都被使用并触发日志。 怎么了?

【问题讨论】:

  • 你有哪个targetSdkVersion?
  • startScan() 返回什么值?
  • minSdkVersion 21targetSdkVersion 27startScan() 返回 0,所以 success
  • 只是想说我也看到了这个。其他人也一样:developer.samsung.com/forum/thread/…
  • 谢谢@PeteDoyle 很高兴知道这是一件事,而不仅仅是我;)

标签: android bluetooth bluetooth-lowenergy android-8.0-oreo samsung-galaxy


【解决方案1】:

您已在 AndroidManifest.xml 中使用 Intent Filter 名称注册了广播接收器

&lt;action android:name="BluetoothDevice.ACTION_FOUND" /&gt;

首先,您可以提供任何字符串。以上建议您使用this constant,但实际上您只是按原样使用字符串(BluetoothDevice.ACTION_FOUND)。我建议将其更改为 com.testapp.samsungoscan.ACTION_FOUND。 Extras 不是必需的,它们表明它们实际上是 extras,但它们只是另一个名为“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 将来更改可能需要精细位置权限才能扫描蓝牙设备。

【讨论】:

    【解决方案2】:

    您需要将一个空的过滤器列表传递给 startScan() 调用而不是 null

    List<ScanFilter> listOfFiters = new ArrayList<>();
    ScanFilter.Builder builder = new ScanFilter.Builder();
    ScanFilter filter = builder.build();
    listOfFiters.add(filter);
    
    bleScanner.startScan(listOfFilters, null, getPendingIntent())
    

    【讨论】:

      【解决方案3】:

      啊,除了将空过滤器传递给 startScan,您还需要最新 Android 版本的 ACCESS_FINE_LOCATION 权限。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-29
        • 2016-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-18
        相关资源
        最近更新 更多