簡體   English   中英

BLE 掃描在 Android 12+ 上崩潰

[英]BLE Scan crash on Android 12+

問題

你好,我遇到了一個我自己無法解決的問題。 我是 Haia Consultancy 的實習生,我使用 Kotlin 為 Android 運行平台開發。 我無法在 Android 12 上的 S21+ android 手機上執行 BLE 掃描,無論是我的代碼還是來自 github 的代碼。 該應用程序一直運行,直到我按下執行 BLE 掃描的掃描按鈕。 應用程序崩潰。 這不會發生在較低版本的 Android 上。 能夠將 android 12 目標版本與低功耗藍牙結合使用非常重要。

    2022-12-07 16:01:45.692 28797-28797 AndroidRuntime          
    com...e.ultrawidebandproofofconcept  E  FATAL EXCEPTION: main
        Process: com.example.ultrawidebandproofofconcept, PID: 28797
        java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for AttributionSource { uid = 10366, packageName = com.example.ultrawidebandproofofconcept, attributionTag = null, token = android.os.BinderProxy@ff32c8f, next = null }: GattService registerScanner
            at android.os.Parcel.createExceptionOrNull(Parcel.java:2438)
            at android.os.Parcel.createException(Parcel.java:2422)
            at android.os.Parcel.readException(Parcel.java:2405)
            at android.os.Parcel.readException(Parcel.java:2347)
            at android.bluetooth.IBluetoothGatt$Stub$Proxy.registerScanner(IBluetoothGatt.java:1886)
            at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.startRegistration(BluetoothLeScanner.java:519)
            at android.bluetooth.le.BluetoothLeScanner.startScan(BluetoothLeScanner.java:305)
            at android.bluetooth.le.BluetoothLeScanner.startScan(BluetoothLeScanner.java:161)
            at com.example.ultrawidebandproofofconcept.MainActivity.startBleScan(MainActivity.kt:96)
            at com.example.ultrawidebandproofofconcept.MainActivity.onCreate$lambda-0(MainActivity.kt:80)
            at com.example.ultrawidebandproofofconcept.MainActivity.$r8$lambda$NQsLDkI5TsYB6INH-F0JwBK_SNM(Unknown Source:0)
            at com.example.ultrawidebandproofofconcept.MainActivity$$ExternalSyntheticLambda2.onClick(Unknown Source:2)
            at android.view.View.performClick(View.java:7792)
            at android.widget.TextView.performClick(TextView.java:16112)
            at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
            at android.view.View.performClickInternal(View.java:7769)
            at android.view.View.access$3800(View.java:910)
            at android.view.View$PerformClick.run(View.java:30218)
            at android.os.Handler.handleCallback(Handler.java:938)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loopOnce(Looper.java:226)
            at android.os.Looper.loop(Looper.java:313)
            at android.app.ActivityThread.main(ActivityThread.java:8751)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
                                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

我遵循的指南: https ://punchthrough.com/android-ble-guide/

我一直在遵循本指南,直到我遇到問題,在某個時候更新了網頁,通知讀者該指南是最新的 android 12+。 我去了本指南的 github 存儲庫並克隆了 android12+ 分支 ( https://github.com/PunchThrough/ble-starter-android/tree/feature/android-12-up )。 發生與上面提到的在我的項目中相同的錯誤。 我和我的同事懷疑我的筆記本電腦或公司提供的電話有問題。 如果targeted version設置為android 12+,IDE建議你加if語句,看你是否被用戶授予權限: IDE's suggestion to see if the user has granted the permission if I do not add the if statement由 IDE 生成,並在我請求用戶權限后嘗試執行 BLE 掃描,應用程序仍然崩潰。 我嘗試將結果打印到控制台以查看是否真的授予了權限。 我向用戶請求位置許可,並詢問用戶是否同意我啟用藍牙。 printout permissions 打印輸出的結果如您所見,當我檢查是否為藍牙掃描授予權限時,返回 -1。 我假設這是一個錯誤代碼,因為您應該只得到 true(1) 或 false(0)。

嘗試的解決方案

我嘗試不僅向用戶請求精細位置權限,還請求用戶提供粗略位置權限,因為這是 android 12 和更低版本在藍牙低功耗方面的主要區別。 然而,這並沒有什么不同。 由於我不將藍牙用於與位置相關的目的,因此我明確聲明我不會在清單文件中使用位置。 這也不起作用。 有誰知道如何解決這一問題? 您可以毫無問題地運行本文檔中提到的項目嗎? 有人知道線索嗎? 任何一點信息都有幫助!

SOFTWARE & HARDWARE SPECIFICATIONS
Run on s21+ Android phone with Android 11
Project specifications:
targetSDK: 32
MinSDK: 31
Manifest permissions:
<uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:remove="android:maxSdkVersion"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

項目 Github 存儲庫: https ://github.com/FedorTselishchev/UWB-POC-Stackoverflow

請幫忙,我想再次見到我的家人。

UPDATE 15/12/2022下面的代碼仍然崩潰

        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.BLUETOOTH_SCAN
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissionLauncher.launch(
                Manifest.permission.BLUETOOTH_SCAN
            )
            requestPermissionLauncher.launch(
                Manifest.permission.BLUETOOTH_CONNECT
            )
            return
        }
        bleScanner.startScan(null, scanSettings, scanCallback)

下面的代碼有效,我不明白如何或為什么,但我現在是自由人了。 謝謝好心的陌生人的幫助。

        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.BLUETOOTH_CONNECT
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissionLauncher.launch(
                Manifest.permission.BLUETOOTH_SCAN
            )
            requestPermissionLauncher.launch(
                Manifest.permission.BLUETOOTH_CONNECT
            )
            return
        }
        bleScanner.startScan(null, scanSettings, scanCallback)

Android 12 的更改似乎需要您的應用在清單文件中聲明它們:

如果您的應用以 Android 12(API 級別 31)或更高版本為目標平台,請在應用的清單文件中聲明以下權限:

如果您的應用程序尋找藍牙設備,例如 BLE 外圍設備,請聲明 BLUETOOTH_SCAN 權限。

來源: https ://developer.android.com/guide/topics/connectivity/bluetooth/permissions

由於您的 targetSdk 是 32 和 minimumSdk 31,您可能只需要聲明新的藍牙權限,因為您不需要從掃描結果中獲取用戶的位置,也不需要請求位置權限。 在清單文件中聲明以下權限:

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
        android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s" />

並請求運行時用戶權限為

requestMultiplePermissionLauncher.launch(arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT))

這將啟動附近設備的權限請求。

如果您的目標是較低的 SDK 版本或打算派生用戶位置,則只能聲明和請求位置權限。

點擊此 鏈接了解如何請求運行時權限。

編輯:如果您打算只掃描 ble 設備,而不是連接,則聲明並僅請求掃描權限,嘔吐連接權限。

您也可以使用請求代碼請求權限,點擊此鏈接

我的猜測是,當 if 語句觸發時,只會觸發一個請求權限,而不會觸發另一個。 第二次訪問相同的函數時,if 語句在獲得許可后不會觸發,但第二次許可未獲得,因此您仍然會崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM