如要在應用程式中使用藍牙功能,您必須宣告多項權限。建議您同時指定應用程式是否需要支援經典藍牙或藍牙低功耗 (BLE)。如果您的應用程式不需要經典藍牙或 BLE,但仍可使用這些技術,您可以在執行階段檢查可用性。
宣告權限
您在應用程式宣告的權限組合取決於應用程式的目標 SDK 版本。
指定 Android 12 以上版本
注意: 相較於本節所述的權限,在 Android 8.0 (API 級別 26) 以上版本中,隨附裝置管理工具 (CDM) 可讓您以更簡便的方式連線至隨附裝置。CDM 系統會代表您的應用程式提供配對 UI,不需要位置存取權。
如要進一步控管配對和連線體驗,請使用本節所述的權限。
如果應用程式指定 Android 12 (API 級別 31) 以上版本,請在應用程式的資訊清單檔案中宣告下列權限:
- 如果應用程式會尋找藍牙裝置 (例如 BLE 週邊裝置),請宣告
BLUETOOTH_SCAN
權限。 - 如果應用程式開放其他藍牙裝置偵測目前裝置,請宣告
BLUETOOTH_ADVERTISE
權限。 - 如果應用程式與已配對的藍牙裝置通訊,請宣告
BLUETOOTH_CONNECT
權限。 - 如果是舊版藍牙相關權限宣告,請將
android:maxSdkVersion
設為30
。在搭載 Android 12 以上版本的裝置上,這個應用程式相容性步驟可協助系統僅授予應用程式所需的藍牙權限。 - 如果應用程式使用藍牙掃描結果導出實際位置,請宣告
ACCESS_FINE_LOCATION
權限。否則,您可以明確宣告應用程式不會衍生實體位置。
BLUETOOTH_ADVERTISE
、BLUETOOTH_CONNECT
和 BLUETOOTH_SCAN
權限為執行階段權限。因此,您必須先在應用程式中明確要求使用者核准,才能尋找藍牙裝置、讓其他裝置可偵測其他裝置,或是與已經配對的藍牙裝置通訊。當應用程式要求至少其中一項權限時,系統會提示使用者允許應用程式存取鄰近裝置,如圖 1 所示。
下列程式碼片段示範如何在指定 Android 12 以上版本的情況下,在應用程式中宣告藍牙相關權限:
<manifest>
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can
<a href="#assert-never-for-location">strongly assert that your app
doesn't derive physical location</a>. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
嚴格宣告應用程式不會衍生實體位置
如果應用程式未使用藍牙掃描結果產生實體位置,您可以做出更強的斷言,讓應用程式絕對不會使用藍牙權限取得實體位置。若要這樣做,請完成下列步驟:
將
android:usesPermissionFlags
屬性新增至BLUETOOTH_SCAN
權限宣告,並將此屬性的值設為neverForLocation
。如果應用程式不需要位置,請從應用程式資訊清單中移除
ACCESS_FINE_LOCATION
權限。
下列程式碼片段說明如何更新應用程式的資訊清單檔案:
<manifest>
<!-- Include "neverForLocation" only if you can strongly assert that
your app never derives physical location from Bluetooth scan results. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!-- Not needed if you can strongly assert that your app never derives
physical location from Bluetooth scan results and doesn't need location
access for any other purpose. -->
<strike><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></strike>
...
</manifest>
指定 Android 11 以下版本
如果應用程式指定 Android 11 (API 級別 30) 以下版本,請在應用程式的資訊清單檔案中宣告下列權限:
- 執行任何經典藍牙或 BLE 通訊時,必須使用
BLUETOOTH
,例如要求連線、接受連線,以及傳輸資料。 ACCESS_FINE_LOCATION
為必要項目,因為在 Android 11 以下版本中,藍牙掃描可能會用來收集使用者位置的相關資訊。
由於位置存取權屬於執行階段權限,因此您必須在執行階段要求這些權限,並在資訊清單中宣告這些權限。
尋找本機藍牙裝置
如要讓應用程式啟動探索裝置功能或操控藍牙設定,您必須宣告 BLUETOOTH_ADMIN
權限。大多數應用程式都需要取得此權限才能尋找本機藍牙裝置。除非應用程式屬於會在使用者要求後修改藍牙設定的「電源管理員」,否則請勿使用這項權限授予的其他功能。在應用程式資訊清單檔案中宣告權限。例如:
<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>
如果您的應用程式支援某項服務,且可在 Android 10 (API 級別 29) 或 Android 11 上執行,您也必須宣告 ACCESS_BACKGROUND_LOCATION
權限以尋找藍牙裝置。如要進一步瞭解這項規定,請參閱「在背景存取位置資訊」。
下列程式碼片段說明如何宣告 ACCESS_BACKGROUND_LOCATION
權限:
<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>
如要進一步瞭解如何宣告應用程式權限,請參閱 <uses-permission>
參考資料。
指定藍牙功能使用情形
如果藍牙是應用程式的重要部分,您可以在資訊清單檔案中加入標記,指明這項需求。<uses-feature>
元素可讓您指定應用程式使用的硬體類型,以及是否必要。
本範例說明如何表明應用程式需要經典藍牙。
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
如果您的應用程式需要藍牙低功耗,您可以使用下列服務:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
如果您表示應用程式需要這項功能,Google Play 商店會在缺少這些功能的裝置上隱藏應用程式,不向使用者顯示。因此,只有在應用程式無法在沒有該功能的情況下正常運作時,才需要將必要屬性設為 true
。
在執行階段查看功能可用性
如要讓不支援傳統版藍牙或 BLE 的裝置使用您的應用程式,您仍應在應用程式的資訊清單中加入 <uses-feature>
元素,但請設定 required="false"
。而在執行階段,您可以使用 PackageManager.hasSystemFeature()
判斷功能的可用性:
Kotlin
// Check to see if the Bluetooth classic feature is available. val bluetoothAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) // Check to see if the BLE feature is available. val bluetoothLEAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
Java
// Use this check to determine whether Bluetooth classic is supported on the device. // Then you can selectively disable BLE-related features. boolean bluetoothAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); // Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. boolean bluetoothLEAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);