O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Visibilidade do pacote no Android 11

O Android 11 muda a forma como os apps podem consultar e interagir com outros apps que o usuário instalou em um dispositivo. Com o novo elemento <queries>, os apps podem definir o conjunto de outros apps que podem acessar. Esse elemento ajuda a incentivar o princípio do menor privilégio informando ao sistema quais outros apps precisam ficar visíveis para seu app, além de ajudar as lojas de apps, como o Google Play, a avaliar a privacidade e a segurança que ele oferece aos usuários.

Caso o app seja voltado para o Android 11, talvez seja necessário adicionar o elemento <queries> ao arquivo de manifesto do app. No elemento <queries>, é possível especificar apps pelo nome do pacote, pela assinatura da intent ou pela autoridade do provedor.

O elemento <queries> permite que você descreva com que outros apps seu app pode precisar interagir. É possível especificar apps pelo nome do pacote ou pela assinatura da intent em um único elemento <queries>. Para informações sobre como consultar outros apps para atender a um caso de uso específico, consulte o guia de casos de uso de visibilidade do pacote.

Os métodos PackageManager que retornam resultados sobre outros apps, como queryIntentActivities(), são filtrados com base na declaração <queries> do app de chamada. Interações explícitas com outros apps, como startService(), também exigem que o app de destino corresponda a uma das declarações em <queries>.

Configurar o ambiente

Para criar um app que use o elemento <queries>, use as seguintes ferramentas:

Consultar e interagir com pacotes específicos

Se você conhece o conjunto específico de apps que quer consultar ou com os quais quer interagir, como apps que se integram ao seu ou apps cujos serviços você usa, inclua os nomes dos pacotes deles em um conjunto de elementos <package> dentro do elemento <queries>:

<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>

Consultar e interagir com apps que receberam um filtro de intent

Seu app pode precisar consultar ou interagir com um conjunto de apps que atendem a uma finalidade específica, mas você pode não saber os nomes de pacotes específicos a serem incluídos. Nessa situação, você pode listar as assinaturas de filtro de intent no elemento <queries>. Seu app pode descobrir apps que têm elementos <intent-filter> correspondentes.

O exemplo a seguir permite que seu app veja apps instalados compatíveis com o compartilhamento de imagens JPEG:

<manifest package="com.example.game">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    ...
</manifest>

O elemento <intent> tem algumas restrições:

  • É necessário incluir exatamente um elemento <action>.
  • Não é possível usar os atributos path, pathPrefix, pathPattern ou port em um elemento <data>. O sistema se comporta como se o valor de cada atributo fosse o valor do caractere curinga genérico (*).
  • Não é possível usar o atributo mimeGroup de um elemento <data>.
  • Nos elementos <data> de um único elemento <intent>, é possível usar cada um dos seguintes atributos no máximo uma vez:

    • mimeType
    • scheme
    • host

    É possível distribuir esses atributos em vários elementos <data> ou usá-los em um único elemento <data>.

O elemento <intent> aceita o caractere curinga genérico (*) como o valor de alguns atributos:

  • O atributo name do elemento <action>.
  • O subtipo do atributo mimeType de um elemento <data> (image/*).
  • O tipo e subtipo do atributo mimeType de um elemento <data> (*/*).
  • O atributo scheme de um elemento <data>.
  • O atributo host de um elemento <data>.

A menos que especificado de outra forma na lista anterior, o sistema não é compatível com uma combinação de caracteres curinga e de texto, como prefix*.

Consultar e interagir com apps que tenham uma autoridade do provedor

Nos casos em que é preciso consultar um provedor de conteúdo, mas você não sabe os nomes dos pacotes específicos, declare essa autoridade de provedor em um elemento <provider>, conforme demonstrado no snippet a seguir:

<manifest package="com.example.suite.enterprise">
    <queries>
        <provider android:authorities="com.example.settings.files" />
    </queries>
    ...
</manifest>

É possível declarar várias autoridades do provedor em um único elemento <queries>. Para fazer isso, conclua uma das seguintes etapas:

  • Em um único elemento <provider>, declare uma lista de autoridades delimitada por ponto e vírgula.
  • Inclua vários elementos <provider>, todos no mesmo elemento <queries>. Em cada elemento <provider>, declare uma única autoridade ou uma lista de autoridades delimitada por ponto e vírgula.

Consultar e interagir com todos os apps

Em casos raros, o app pode precisar consultar ou interagir com todos os apps instalados em um dispositivo, independentemente dos componentes que eles contenham. Para permitir que o app veja todos os outros apps instalados, o Android 11 introduz a permissão QUERY_ALL_PACKAGES.

A lista a seguir fornece alguns exemplos de casos de uso em que a permissão QUERY_ALL_PACKAGES é apropriada para incluir:

  • Apps da tela de início
  • Apps de acessibilidade
  • Navegadores
  • Apps de compartilhamento ponto a ponto (P2P)
  • Apps de gerenciamento de dispositivos
  • Apps de segurança

No entanto, na grande maioria dos casos, é possível atender aos casos de uso do app declarando o elemento <queries>. Para respeitar a privacidade do usuário, seu app precisa solicitar a menor quantidade de visibilidade do pacote necessária para que ele funcione.

Na próxima atualização da política, procure o Google Play para fornecer diretrizes para apps que precisam da permissão QUERY_ALL_PACKAGES.

Casos de uso que não são afetados pela mudança

A lista a seguir inclui vários exemplos de casos de uso que não exigem uma declaração <queries>:

  • O app de destino é o próprio app.
  • Você usa uma intent para iniciar uma atividade.
  • O app interage com determinados pacotes do sistema, como o provedor de mídia, que implementam funcionalidades essenciais do Android.
  • O app de destino instalou seu app. Você tem visibilidade dos apps retornados das chamadas para getInitiatingPackageName() e getInstallingPackageName() no objeto InstallSourceInfo do seu app.
  • Um app inicia seu app usando o método startActivityForResult(). Esse app se torna visível para ele automaticamente.
  • Um app é iniciado ou vinculado a um serviço no seu app. Esse app se torna visível para ele automaticamente.
  • Um app faz uma solicitação a um provedor de conteúdo no seu app. Esse app se torna visível para ele automaticamente.
  • Seu app é um editor de método de entrada (IME, na sigla em inglês) e está fornecendo entrada para outro app. Esse app se torna visível para ele automaticamente.

Mensagens de registro para filtragem de pacotes

Para ver mais detalhes sobre como as mudanças na visibilidade do pacote afetam seu app, ative as mensagens de registro para filtragem de pacotes. Se estiver desenvolvendo um app de teste ou depurável no Android Studio, esse recurso estará ativado. Caso contrário, será possível executar o seguinte comando em uma janela de terminal para ativá-lo manualmente:

adb shell pm log-visibility --enable PACKAGE_NAME

Em seguida, sempre que os pacotes forem filtrados dos valores de retorno de um objeto PackageManager, você verá uma mensagem semelhante à seguinte no Logcat:

I/AppsFilter: interaction: PackageSetting{7654321 \
  com.example.myapp/12345} -> PackageSetting{...} BLOCKED

Testar a mudança

Para testar se essa mudança de comportamento entrou em vigor no seu app, siga as seguintes etapas:

  1. Instale o Android Studio 3.6.1 ou uma versão mais recente.
  2. Instale a versão mais recente do Gradle compatível com o Android Studio.
  3. Defina a targetSdkVersion do app como 30.
  4. Não inclua o elemento <queries> no arquivo de manifesto do app.
  5. Chame getInstalledApplications() ou getInstalledPackages(). Os dois métodos retornarão uma lista filtrada.
  6. Veja quais recursos do app não estão funcionando.
  7. Introduza as entradas apropriadas <queries> para corrigir esses recursos.