Cómo declarar necesidades de visibilidad de paquetes

Cuando creas una app, es importante que consideres el conjunto de otras apps instaladas en el dispositivo al que deseas que la app acceda. 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, pero filtra otras de forma predeterminada. En esta guía, se describe cómo hacer que 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 correspondiente. 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 realizar consultas 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 aplicaciones con elementos <intent-filter> que coincidan.

En el siguiente ejemplo, la app puede ver las 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

En los casos en los que necesites consultar un proveedor de contenido, pero no conozcas 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 todas las autoridades de proveedores en un solo elemento <queries>. El formato depende de la cantidad de autoridades de proveedores que declares:

Elemento <provider> único
En el elemento, declara una lista de autoridades delimitada por punto y coma.
Varios elementos <provider>
En cada elemento, declara una única autoridad o una lista de autoridades delimitadas 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 demás, el sistema proporciona el permiso QUERY_ALL_PACKAGES.

En la siguiente lista, se muestran algunos 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, en la gran mayoría de los casos, puedes entregar los casos de uso de tu app cuando interactúas con el conjunto de apps que son visibles automáticamente y declaras las otras apps a las que necesita acceder la tuya en el archivo de manifiesto. A fin de respetar la privacidad del usuario, tu app debe solicitar la menor cantidad de visibilidad del 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.