Cómo declarar necesidades de visibilidad de paquetes

Cuando creas una app, es importante que consideres las otras apps en el dispositivo con las que necesita interactuar. Si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores, el sistema hace que algunas apps sean visibles automáticamente para tu app, pero filtra otras de forma predeterminada. En esta guía, se describe cómo hacer que esas otras apps sean visibles para la tuya.

Si tu app se orienta a Android 11 o versiones posteriores y necesita interactuar con apps que no son visibles automáticamente, agrega el elemento <queries> en el archivo de manifiesto de tu app. Dentro del elemento <queries>, especifica las otras apps por nombre de paquete, firma de intent o autoridad del proveedor, como se describe en las siguientes secciones.

Nombres de paquetes específicos

Si conoces el conjunto específico de apps a las que quieres buscar o con las que quieres interactuar (como las que se integran con tu app o aquellas cuyos servicios usas), incluye los nombres en un conjunto de elementos <package> dentro del elemento <queries>:

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

Cómo comunicarse con una app host en una biblioteca

Si desarrollas una biblioteca de Android, puedes declarar las necesidades de visibilidad de tu paquete agregando un elemento <queries> en tu archivo de manifiesto AAR. Este elemento <queries> tiene la misma función que el elemento que las apps pueden declarar en sus propios manifiestos.

Si tu biblioteca se comunica con una app host, como cuando se usa un servicio vinculado, incluye un elemento <package> que especifique el nombre del paquete de la app host:

<!-- Place inside the <queries> element. -->
<package android:name=PACKAGE_NAME />

Si incluyes esta declaración, puedes verificar si la app host está instalada e interactuar con ella, por ejemplo, llamando a bindService(). Como resultado de esta interacción, la app que realiza la llamada y usa tu biblioteca se hace visible automáticamente.

Paquetes que coinciden con una firma de filtro de intents

Es posible que tu app necesite realizar consultas en un conjunto de apps que cumplen con un propósito determinado o interactuar con ese conjunto, pero quizás no conozcas los nombres de los paquetes específicos que debes incluir. En esta situación, puedes mostrar las firmas de filtros de intents en el elemento <queries>. Luego, tu app puede descubrir otras con elementos <intent-filter> que coincidan.

En el siguiente ejemplo de código, se muestra un elemento <intent> que permitiría a la app ver otras apps instaladas que admiten el uso compartido de imágenes JPEG:

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

El elemento <intent> tiene algunas restricciones:

  • Debes incluir exactamente un elemento <action>.
  • No puedes usar los atributos path, pathPrefix, pathPattern o port en un elemento <data>. El sistema se comporta como si configuraras el valor de cada atributo para el carácter comodín genérico (*).
  • No puedes usar el atributo mimeGroup de un elemento <data>.
  • Dentro de los elementos <data> de un solo elemento <intent>, puedes usar cada uno de los siguientes atributos una vez como máximo:

    • mimeType
    • scheme
    • host

    Puedes distribuir esos atributos en varios elementos <data> o usarlos en un elemento <data> único.

El elemento <intent> admite el carácter comodín genérico (*) como valor para algunos atributos:

  • El atributo name del elemento <action>
  • El subtipo del atributo mimeType de un elemento <data> (image/*)
  • El tipo y el subtipo del atributo mimeType de un elemento <data> (*/*)
  • El atributo scheme de un elemento <data>
  • El atributo host de un elemento <data>

A menos que se especifique lo contrario en la lista anterior, el sistema no admite una combinación de caracteres de texto y comodín, como prefix*.

Paquetes que usan una autoridad específica

Si necesitas buscar un proveedor de contenido, pero no conoces los nombres de paquetes específicos, puedes declarar la autoridad del proveedor en un elemento <provider>, como se muestra en el siguiente fragmento:

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

Puedes declarar autoridades de proveedores en un solo elemento <queries>. Puedes declarar uno o más elementos <provider> dentro del elemento <queries>. Un elemento <provider> puede incluir una sola autoridad del proveedor o una lista de autoridades del proveedor delimitada por punto y coma.

Todas las apps (no recomendado)

En pocas ocasiones, es posible que la app necesite realizar consultas en todas las apps instaladas en un dispositivo o interactuar con ellas, independientemente de los componentes que incluyan. Para permitir que tu app vea todas las otras instaladas, el sistema proporciona el permiso QUERY_ALL_PACKAGES.

Estos son algunos ejemplos de casos de uso en los que es apropiado incluir el permiso QUERY_ALL_PACKAGES:

  • Apps de accesibilidad
  • Navegadores
  • Apps de administración de dispositivos
  • Apps de seguridad
  • Apps de antivirus

Sin embargo, suele ser posible cumplir con los casos de uso de tu app mediante la interacción con el conjunto de apps que son visibles automáticamente y la declaración de las otras apps a las que necesita acceder en tu archivo de manifiesto. Para respetar la privacidad del usuario, tu app debe solicitar la menor cantidad de visibilidad de paquete necesaria para funcionar.

Esta actualización en las políticas de Google Play proporciona lineamientos para las apps que necesitan el permiso del elemento QUERY_ALL_PACKAGES.