Para usar las funciones de Bluetooth en tu app, debes declarar varios permisos. También debes especificar si tu app requiere compatibilidad con Bluetooth clásico o Bluetooth de bajo consumo (BLE). Si tu app no requiere Bluetooth clásico ni BLE, pero puede beneficiarse de estas tecnologías, puedes verificar la disponibilidad en el tiempo de ejecución.
Cómo declarar permisos
El conjunto de permisos que declaras en tu app depende de la versión del SDK de destino de la app.
Cómo orientar la app a Android 12 o versiones posteriores
Nota: En Android 8.0 (nivel de API 26) y versiones posteriores, el administrador de dispositivo complementario (CDM) brinda un método más optimizado para conectarse a dispositivos complementarios, en comparación con los permisos que se describen en esta sección. El sistema del CDM ofrece una IU de vinculación en nombre de la app y no requiere permisos de ubicación.
Si deseas tener más control sobre la experiencia de vinculación y conexión, usa los permisos que se describen en esta sección.
Si tu app se orienta a Android 12 (nivel de API 31) o versiones posteriores, declara los siguientes permisos en el archivo de manifiesto de la app:
- Si la app busca dispositivos Bluetooth, como
periféricos BLE, declara el
BLUETOOTH_SCANpermiso. - Si la app permite que el dispositivo actual sea detectable para otros dispositivos Bluetooth, declara el
BLUETOOTH_ADVERTISEpermiso. - Si la app se comunica con dispositivos Bluetooth ya vinculados, declara el
BLUETOOTH_CONNECTpermiso. - Para las declaraciones heredadas de permiso que se relacionan con Bluetooth, configura
android:maxSdkVersionen 30. Con este paso de compatibilidad de la app, se permite que el sistema le otorgue a esta solo los permisos de Bluetooth que necesita cuando se instala en dispositivos que ejecutan Android 12 o versiones posteriores. - Si la app usa los resultados de la búsqueda de Bluetooth para obtener la ubicación física, declara
el
ACCESS_FINE_LOCATIONpermiso. De lo contrario, puedes afirmar con seguridad que la app no obtiene la ubicación física y configurarandroid:maxSdkVersionen 30 para elACCESS_FINE_LOCATIONpermiso.
Los permisos BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT y BLUETOOTH_SCAN
son permisos de tiempo de ejecución.
Por lo tanto, debes solicitar explícitamente la aprobación del usuario en tu app antes de poder buscar
dispositivos Bluetooth, hacer que un dispositivo sea detectable para otros dispositivos o comunicarte
con dispositivos Bluetooth ya vinculados. Cuando tu app solicita al menos uno de
estos permisos, el sistema le solicita al usuario que permita que la app acceda a
Dispositivos cercanos, como se muestra en la Figura 1.
En el siguiente fragmento de código, se muestra cómo declarar permisos relacionados con Bluetooth en tu app si se orienta a Android 12 o versiones posteriores:
<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>
Declara que la app no obtiene ubicación física
Si la app no usa los resultados de la búsqueda de Bluetooth para obtener la ubicación física, puedes afirmar con seguridad que la app nunca usa los permisos de Bluetooth para obtenerla. Para ello, completa los siguientes pasos:
Agrega el atributo
android:usesPermissionFlagsa la declaración de permisosBLUETOOTH_SCANy configura el valor de este atributo enneverForLocation.De lo contrario, si no se necesita otra ubicación para la app, quita el permiso
ACCESS_FINE_LOCATIONdel manifiesto de esta.
En el siguiente fragmento de código, se muestra cómo actualizar el archivo de manifiesto de la app:
<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>
Cómo orientar la app a Android 11 o versiones anteriores
Si tu app se orienta a Android 11 (nivel de API 30) o versiones anteriores, declara los siguientes permisos en el archivo de manifiesto de la app:
BLUETOOTHes necesario para realizar cualquier comunicación de Bluetooth clásico o BLE, como solicitar una conexión, aceptar una conexión y transferir datos.ACCESS_FINE_LOCATIONes necesario porque, en Android 11 y versiones anteriores, una búsqueda de Bluetooth podría usarse para recopilar información sobre la ubicación del usuario.
Debido a que los permisos de ubicación son permisos de tiempo de ejecución, debes solicitarlos en el tiempo de ejecución además de declararlos en el manifiesto.
Cómo descubrir dispositivos Bluetooth locales
Si quieres que tu app inicie el descubrimiento de dispositivos o manipule la configuración de Bluetooth, debes declarar el
BLUETOOTH_ADMIN
permiso. La mayoría de las apps necesitan este permiso solo para poder descubrir dispositivos Bluetooth locales. No uses las otras capacidades que otorga este permiso, a menos que la app sea un "administrador de energía" que modifique la configuración de Bluetooth a solicitud del usuario. Declara el permiso en el archivo de manifiesto de la app. Por ejemplo:
<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>
Si tu app admite un servicio y se puede ejecutar en Android 10 (nivel de API 29) o
Android 11, también debes declarar el
ACCESS_BACKGROUND_LOCATION
permiso para descubrir dispositivos Bluetooth. Para obtener más información sobre este
requisito, consulta Cómo acceder a la ubicación en segundo
plano.
En el siguiente fragmento de código, se muestra cómo declarar el permiso ACCESS_BACKGROUND_LOCATION:
<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>
Consulta la <uses-permission>
referencia para obtener más información sobre la declaración de permisos de la app.
Cómo especificar el uso de la función de Bluetooth
Si Bluetooth es una parte fundamental de tu app, puedes agregar marcas a tu archivo de manifiesto para indicar este requisito. El
<uses-feature> elemento te permite especificar el tipo de hardware que usa tu app y si es
obligatorio o no.
En este ejemplo, se muestra cómo indicar que se requiere Bluetooth clásico para tu app.
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
Si tu app depende de Bluetooth de bajo consumo, puedes usar lo siguiente:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
Si indicas que la función es obligatoria para tu app, Google Play Store ocultará tu app a los usuarios en dispositivos que no tengan esas funciones. Por este motivo, solo debes configurar el atributo required como true si tu app no puede funcionar sin la función.
Cómo verificar la disponibilidad de funciones en el tiempo de ejecución
Para que tu app esté disponible en dispositivos que no admiten Bluetooth clásico ni
BLE, debes incluir el <uses-feature> elemento en el
manifiesto de la app, pero configurar required="false". Luego, en el tiempo de ejecución, puedes determinar
la disponibilidad de la función con
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);