【问题标题】:altbeacon BluetoothMedic crashes with Android version 12 + 13altbeacon BluetoothMedic 在 Android 版本 12 + 13 中崩溃
【发布时间】:2022-12-13 09:57:19
【问题描述】:

当我将 Android 更新为目标 SDK 31 时,问题就开始了。

首先,我在清单中有错误,因为库中有一个没有设置 android:exported 的接收器。这原来是 org.altbeacon.android-beacon-library。通过更新到最新的非测试版 2.19.4 修复

接下来,我必须将蓝牙的新权限添加到我的清单中。

<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

并且还调整了旧的权限。

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

并添加了功能设置。

<uses-feature android:name="android.hardware.bluetooth"
        android:required="false"/>

    <uses-feature android:name="android.hardware.bluetooth_le"
        android:required="false"/>

在应用程序中,我要求用户提供权限。 (如果 android 发布版本为 12 或更高版本,则使用此版本)。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN)
                    != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADVERTISE)
                    != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
                    != PackageManager.PERMISSION_GRANTED) {
                FirebaseCrashlytics.getInstance().log("requesting permissions.");
                ActivityCompat.requestPermissions(this, new String[]
                        {Manifest.permission.BLUETOOTH_SCAN,
                                Manifest.permission.BLUETOOTH_CONNECT,
                                Manifest.permission.BLUETOOTH_ADVERTISE,
                        }, 22);
                } 

请注意,我在整个程序中有相当多的 Crashlytics 日志调试消息。

很快一些我在 altbeacon 库中遇到各种崩溃。例子:

Fatal Exception: java.lang.SecurityException: Need android.permission.BLUETOOTH_ADVERTISE permission for android.content.AttributionSource@881430fb: GattService startAdvertisingSet
       at com.android.bluetooth.Utils.checkPermissionForDataDelivery(Utils.java:482)
       at com.android.bluetooth.Utils.checkAdvertisePermissionForDataDelivery(Utils.java:570)
       at com.android.bluetooth.gatt.GattService.startAdvertisingSet(GattService.java:3252)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.startAdvertisingSet(GattService.java:1392)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.startAdvertisingSet(GattService.java:1376)
       at android.bluetooth.IBluetoothGatt$Stub.onTransact(IBluetoothGatt.java:362)
       at android.os.Binder.execTransactInternal(Binder.java:1285)
       at android.os.Binder.execTransact(Binder.java:1244)

还获得相同一般类型的 BLUETOOTH_SCAN 权限崩溃。

1:所有崩溃都发生在打开应用程序后的 1 到 5 秒内。

2:尽管设置了日志消息,但我在 Crashlytics 中没有收到任何日志。我想知道如果崩溃发生在库中,日志功能是否有效?

3:Crashlytics 控制台显示 99% 的崩溃发生在三星设备上。

4:我可以在安卓12的测试手机上运行这个,也就是不是一个三星,它工作正常。如果我进入应用程序的权限设置并在下次运行时关闭“附近的设备”,它会再次询问我的权限,如果我拒绝它们,它将在没有蓝牙功能的情况下运行。

【问题讨论】:

    标签: android bluetooth altbeacon


    【解决方案1】:

    对于以 SDK 31+ 为目标并在 Android 12+ 上运行的应用程序,新的Manifest.permission.BLUETOOTH_ADVERTISE 权限必须由用户授予,否则任何启动蓝牙广告的尝试(包括 AndroidBeaconLibrary 中的 BluetoothMedic)将导致致命的应用程序异常,java.lang.SecurityException: Need android.permission.BLUETOOTH_ADVERTISE permission .

    您可以通过以下两种方式之一防止这种情况发生:

    1. 在启用BluetoothMedic 进行如下所示的发射器测试之前,请确保用户已授予此权限。
      if (ContextCompat.checkSelfPermission(context, android.permission.BLUETOOTH_ADVERTISE) == 
          PackageManager.PERMISSION_GRANTED) {
        BluetoothMedic.getInstance().enablePeriodicTests(this, BluetoothMedic.TRANSMIT_TEST)`
      }
      else {
        BluetoothMedic.getInstance().enablePeriodicTests(this, BluetoothMedic.NO_TEST)
      }
      
      1. 您也可以在没有发射器测试的情况下使用BluetoothMedic——通常扫描测试是最重要的测试。您可以如下所示进行配置。但即使在这种情况下,如果您希望 Medic 能够正常工作,您也应该确保用户已授予 BLUETOOTH_SCAN 权限以及 BACKGROUND_LOCATION 权限。如果未授予这些权限,您可能不想启动它,因为扫描只会失败。
      if (ContextCompat.checkSelfPermission(context, Manifest.permission.BACKGROuND_LOCATION) == 
          PackageManager.PERMISSION_GRANTED && 
          ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == 
          PackageManager.PERMISSION_GRANTED) {
        BluetoothMedic.getInstance().enablePeriodicTests(this, BluetoothMedic.SCAN_TEST)`
      }
      else {
        BluetoothMedic.getInstance().enablePeriodicTests(this, BluetoothMedic.NO_TEST)
      }
      

      当然,以上检查仅适用于针对 Android 12 并在 Android 12 上运行的应用,因为添加了权限。如果您允许在较早的 Android 版本上运行,那么如果在较早的 Android 版本上运行,您不想检查 BLUETOOTH_SCAN 和 BLUETOOTH_ADVERTISE 权限。遗憾的是,跨多个操作系统版本的 Android 权限检查变得越来越复杂,需要大量代码才能正确处理。

      最后,请注意,如果未授予权限,上面的代码将禁用 BluetoothMedic。这很重要,因为用户可能会授予权限,然后又将其撤销,这可能会导致崩溃。要阻止此崩溃的发生,请将上面的代码(包括如果未授予权限则禁用 BluetoothMedic 的 else 语句)放在 Application.onCreate 调用链中的某个位置,因为在任何 Android 计划作业(包括 BluetoothMedic)运行之前调用此方法.如果已启用 BluetoothMedic 但未授予所需的权限,这样做将防止后台崩溃。

      对于 OP 描述的具体情况,我怀疑这是一个竞争条件。 BluetoothMedic 设置是持久的,所以如果你打开它,它会保持打开状态。它依赖于 Android JobScheduler,它会每隔约 15 分钟尝试运行一次。如果应用程序尚未运行,它将启动您的应用程序,因此如果它启动并且权限被拒绝,它将崩溃。因此,如果权限被拒绝,您应该明确禁用 BluetoothMedic。我建议将启用/禁用 BluetoothMedic 的代码移动到 Application.onCreate 调用链以在崩溃前停止它。

    【讨论】:

    • 嗨大卫。在我的 OP 中,我已经表明我正在请求广告许可(您必须滚动代码窗口才能看到它)。由于缺少日志,我的应用程序似乎甚至没有达到要求崩溃设备的程度。此外,该应用程序在不同的手机上运行良好并获得成功运行的所有权限这一事实表明该代码在这些情况下确实有效。这似乎真的与三星型手机有关。
    • 我怀疑你描述的是竞争条件。 BluetoothMedic 设置是持久的,所以如果你打开它,它会保持打开状态。它依赖于 Android JobScheduler,它会每隔约 15 分钟尝试运行一次。如果应用程序尚未运行,它将启动您的应用程序,因此如果它启动并且权限被拒绝,它将崩溃。出于这个原因,如果权限被拒绝,您可能应该明确禁用 BluetoothMedic——我更新了我的答案以显示这一点。我建议将启用/禁用 BluetoothMedic 的代码移动到 Application.onCreate 调用链以在崩溃前停止它
    • 请记住,只是请求权限并不意味着用户会授予它。如果代码运行并且用户未授予权限,则会发生崩溃。如果未授予所需的权限,您必须明确禁用 BluetoothMedic,并且在授予这些权限之前不要启用它。
    • 你好。在运行 BTM 之前,我确实设置了权限检查,但可能所有这些用户都是在 SDK 更改和随后的新权限之前运行过应用程序的用户。如果我对你的理解是正确的,你是说即使我的应用程序关闭,BTM 也会继续运行,下次应用程序启动时,BTM 会在我的应用程序启动之前自动运行扫描。因为这些用户从来没有达到允许权限的地步,所以它几乎立即死亡。我会检查一下并通知您。
    • 我认为这是完全正确的。可以理解,这是一个棘手的案例。
    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 2020-11-04
    • 2022-01-18
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-07-09
    相关资源
    最近更新 更多