Quyền truy cập Bluetooth

Để sử dụng các tính năng Bluetooth trong ứng dụng, bạn phải khai báo một số quyền. Bạn cũng nên chỉ định xem ứng dụng của bạn có cần hỗ trợ Bluetooth thông thường hay Bluetooth năng lượng thấp (BLE) hay không. Nếu ứng dụng của bạn không yêu cầu Bluetooth phiên bản cũ hoặc BLE nhưng vẫn có thể hưởng lợi từ các công nghệ này, thì bạn có thể kiểm tra xem có sẵn hay không trong thời gian chạy.

Khai báo quyền

Tập hợp các quyền mà bạn khai báo trong ứng dụng phụ thuộc vào phiên bản SDK mục tiêu của ứng dụng.

Nhắm đến Android 12 trở lên

Lưu ý: Trên Android 8.0 (API cấp 26) trở lên, Trình quản lý thiết bị đồng hành (CDM) cung cấp một phương thức kết nối với các thiết bị đồng hành hiệu quả hơn so với các quyền được mô tả trong phần này. Hệ thống CDM cung cấp một giao diện người dùng ghép nối thay cho ứng dụng của bạn và không yêu cầu quyền truy cập thông tin vị trí.

Nếu bạn muốn có nhiều quyền kiểm soát hơn đối với trải nghiệm ghép nối và kết nối, hãy sử dụng các quyền được mô tả trong phần này.

Hộp thoại cấp quyền truy cập Bluetooth
Hộp thoại cấp quyền của hệ thống, yêu cầu người dùng cấp cho ứng dụng quyền khám phá, quảng cáo và kết nối với các thiết bị ở gần.

Nếu ứng dụng của bạn nhắm đến Android 12 (API cấp 31) trở lên, hãy khai báo các quyền sau đây trong tệp kê khai của ứng dụng:

  1. Nếu ứng dụng của bạn tìm kiếm các thiết bị Bluetooth, chẳng hạn như các thiết bị ngoại vi BLE, hãy khai báo quyền BLUETOOTH_SCAN.
  2. Nếu ứng dụng của bạn đặt thiết bị hiện tại ở chế độ có thể phát hiện đối với các thiết bị Bluetooth khác, hãy khai báo quyền BLUETOOTH_ADVERTISE.
  3. Nếu ứng dụng của bạn giao tiếp với các thiết bị Bluetooth đã được ghép nối, hãy khai báo quyền BLUETOOTH_CONNECT.
  4. Đối với các nội dung khai báo quyền cũ liên quan đến Bluetooth, hãy đặt android:maxSdkVersion thành 30. Bước tương thích ứng dụng này giúp hệ thống chỉ cấp cho ứng dụng của bạn những quyền Bluetooth cần thiết khi ứng dụng được cài đặt trên các thiết bị chạy Android 12 trở lên.
  5. Nếu ứng dụng của bạn sử dụng kết quả quét Bluetooth để xác định vị trí thực, hãy khai báo quyền ACCESS_FINE_LOCATION. Nếu không, bạn có thể khẳng định chắc chắn rằng ứng dụng của bạn không lấy thông tin vị trí thực tế và đặt android:maxSdkVersion thành 30 cho quyền ACCESS_FINE_LOCATION.

Các quyền BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECTBLUETOOTH_SCANquyền khi bắt đầu chạy. Do đó, bạn phải yêu cầu người dùng phê duyệt một cách rõ ràng trong ứng dụng của mình thì mới có thể tìm kiếm thiết bị Bluetooth, đặt thiết bị ở chế độ có thể phát hiện đối với các thiết bị khác hoặc giao tiếp với các thiết bị Bluetooth đã ghép nối. Khi ứng dụng của bạn yêu cầu ít nhất một trong các quyền này, hệ thống sẽ nhắc người dùng cho phép ứng dụng của bạn truy cập vào Thiết bị ở gần, như minh hoạ trong hình 1.

Đoạn mã sau đây minh hoạ cách khai báo các quyền liên quan đến Bluetooth trong ứng dụng nếu ứng dụng đó nhắm đến Android 12 trở lên:

<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>

Khẳng định chắc chắn rằng ứng dụng của bạn không lấy thông tin vị trí thực tế

Nếu ứng dụng của bạn không dùng kết quả quét Bluetooth để xác định vị trí thực, thì bạn có thể khẳng định chắc chắn rằng ứng dụng của bạn không bao giờ dùng quyền truy cập Bluetooth để xác định vị trí thực. Để thực hiện điều này, vui lòng hoàn thành các bước sau:

  1. Thêm thuộc tính android:usesPermissionFlags vào khai báo quyền BLUETOOTH_SCAN rồi đặt giá trị của thuộc tính này thành neverForLocation.

  2. Nếu ứng dụng của bạn không cần thông tin vị trí cho mục đích nào khác, hãy xoá quyền ACCESS_FINE_LOCATION khỏi tệp kê khai của ứng dụng.

Đoạn mã sau đây cho biết cách cập nhật tệp kê khai của ứng dụng:

<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" />

    <!-- Set maxSdkVersion to 30 if you can strongly assert that, on
         Android 12 and higher, your app never derives physical location from
         Bluetooth scan results and doesn't need location access for any other
         purpose. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="30" />
    ...
</manifest>

Nhắm đến Android 11 trở xuống

Nếu ứng dụng của bạn nhắm đến Android 11 (API cấp 30) trở xuống, hãy khai báo các quyền sau trong tệp kê khai của ứng dụng:

  • BLUETOOTH là cần thiết để thực hiện mọi hoạt động giao tiếp bằng Bluetooth phiên bản cũ hoặc BLE, chẳng hạn như yêu cầu kết nối, chấp nhận kết nối và truyền dữ liệu.
  • ACCESS_FINE_LOCATION là cần thiết vì trên Android 11 trở xuống, một quy trình quét Bluetooth có thể được dùng để thu thập thông tin về vị trí của người dùng.

Vì quyền truy cập thông tin vị trí là quyền khi bắt đầu chạy, nên bạn phải yêu cầu các quyền này khi bắt đầu chạy cùng với việc khai báo các quyền đó trong tệp kê khai.

Khám phá các thiết bị Bluetooth tại địa phương

Nếu muốn ứng dụng của mình bắt đầu phát hiện thiết bị hoặc điều chỉnh các chế độ cài đặt Bluetooth, bạn phải khai báo quyền BLUETOOTH_ADMIN. Hầu hết các ứng dụng chỉ cần quyền này để có thể phát hiện các thiết bị Bluetooth cục bộ. Không sử dụng các khả năng khác được cấp theo quyền này, trừ phi ứng dụng là "trình quản lý nguồn" sửa đổi chế độ cài đặt Bluetooth theo yêu cầu của người dùng. Khai báo quyền trong tệp kê khai ứng dụng. Ví dụ:

<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>

Nếu ứng dụng của bạn hỗ trợ một dịch vụ và có thể chạy trên Android 10 (API cấp 29) hoặc Android 11, bạn cũng phải khai báo quyền ACCESS_BACKGROUND_LOCATION để phát hiện các thiết bị Bluetooth. Để biết thêm thông tin về yêu cầu này, hãy xem phần Truy cập thông tin vị trí ở chế độ nền.

Đoạn mã sau đây cho biết cách khai báo quyền ACCESS_BACKGROUND_LOCATION:

<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>

Hãy xem tài liệu tham khảo về <uses-permission> để biết thêm thông tin về cách khai báo quyền cho ứng dụng.

Chỉ định cách sử dụng tính năng Bluetooth

Nếu Bluetooth là một phần quan trọng trong ứng dụng của bạn, thì bạn có thể thêm cờ vào tệp kê khai để cho biết yêu cầu này. Phần tử <uses-feature> cho phép bạn chỉ định loại phần cứng mà ứng dụng của bạn sử dụng và liệu phần cứng đó có bắt buộc hay không.

Ví dụ này cho biết cách chỉ ra rằng ứng dụng của bạn cần có Bluetooth truyền thống.

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

Nếu ứng dụng của bạn dựa vào Bluetooth năng lượng thấp, bạn có thể sử dụng những thông tin sau:

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

Nếu bạn cho biết ứng dụng của mình cần có tính năng này, thì Cửa hàng Google Play sẽ ẩn ứng dụng của bạn đối với người dùng trên các thiết bị thiếu những tính năng đó. Vì lý do này, bạn chỉ nên đặt thuộc tính bắt buộc thành true nếu ứng dụng của bạn không thể hoạt động mà không có tính năng này.

Kiểm tra phạm vi cung cấp của các tính năng trong thời gian chạy

Để cung cấp ứng dụng của bạn cho những thiết bị không hỗ trợ Bluetooth phiên bản cũ hoặc BLE, bạn vẫn nên thêm phần tử <uses-feature> vào tệp kê khai của ứng dụng, nhưng hãy đặt required="false". Sau đó, trong thời gian chạy, bạn có thể xác định tính năng có sẵn bằng cách sử dụng 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);