Novas permissões do Bluetooth no Android 12

O Android 12 introduz as permissões BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE e BLUETOOTH_CONNECT, que autorizam o app a procurar dispositivos por perto sem precisar pedir a permissão de localização. O app precisa ser direcionado ao Android 12 para declarar essas permissões.

Se você quiser ter mais controle sobre a experiência de pareamento e conexão, use as permissões descritas nesta página.

Declarar novas permissões

Se o app interagir com dispositivos Bluetooth, é altamente recomendável que você faça o seguinte:

  1. Se o app procurar dispositivos Bluetooth, como periféricos de Bluetooth de baixa energia (BLE), adicione a permissão BLUETOOTH_SCAN ao manifesto do app.
  2. Se o app tornar o dispositivo atual detectável para outros dispositivos Bluetooth, adicione a permissão BLUETOOTH_ADVERTISE ao manifesto do app.
  3. Se o app se comunicar com dispositivos Bluetooth já pareados, adicione a permissão BLUETOOTH_CONNECT ao manifesto do app.
  4. Para as declarações de permissões legadas relacionadas ao Bluetooth, defina android:maxSdkVersion como 30. Essa etapa de compatibilidade do app ajuda o sistema a conceder ao app apenas as permissões de Bluetooth necessárias no momento da instalação em dispositivos com o Android 12.

O snippet de código a seguir demonstra como declarar essas novas permissões no app:

<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.
         You must add an attribute to this permission, or declare the
         ACCESS_FINE_LOCATION permission, depending on the results when you
         check location usage in your app. -->
    <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" />
    ...
</manifest>
Figura 1. Permissões do sistema, solicitando que o usuário conceda a um app permissão para descobrir, anunciar e se conectar a dispositivos próximos.

Caixa de diálogo voltada ao usuário

As permissões BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE e BLUETOOTH_CONNECT são permissões de execução. Portanto, você precisa solicitar a aprovação do usuário explicitamente no seu app para poder procurar dispositivos Bluetooth, tornar um dispositivo detectável para outros ou se comunicar com dispositivos já pareados.

Quando o app solicitar pelo menos uma das novas permissões do Bluetooth, o sistema solicitará que o usuário acesse os Dispositivos por perto, conforme mostrado na Figura 1.

Considerar como os resultados da verificação são usados

Analise com cuidado se o app usa resultados da verificação Bluetooth para determinar a localização do dispositivo. Dependendo da resposta, siga as etapas de uma das seções a seguir.

O app não determina a localização física

Se o app não acessa a localização física, é possível afirmar que o app nunca usará as permissões Bluetooth para determinar a localização física. Para isso, siga os passos a seguir:

  1. Adicione o atributo android:usesPermissionFlags à declaração de permissão BLUETOOTH_SCAN e defina o valor dele como neverForLocation.

  2. Se a localização não for necessária para o app, remova a permissão ACCESS_FINE_LOCATION do manifesto.

O snippet de código a seguir mostra como atualizar o arquivo de manifesto do app.

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

    <!-- 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" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- 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. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
</manifest>

O app determina a localização física

Se o app determinar a localização física, será necessário continuar declarando a permissão ACCESS_FINE_LOCATION no manifesto do app, conforme mostrado no snippet de código a seguir:

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

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

    <!-- Required if your app derives physical location from Bluetooth
         scan results. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
</manifest>