Cuando creas una app, es importante que consideres el conjunto de paquetes, que representan 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 una versión posterior, el sistema hace que algunas apps sean visibles automáticamente, pero oculta otras de forma predeterminada. Al hacer que algunas aplicaciones no sean visibles de forma predeterminada, el sistema incentiva el principio de privilegio mínimo indicando qué otras apps debe mostrarle a la tuya y ayuda a que las tiendas de aplicaciones, como Google Play, evalúen la privacidad y la seguridad que la app proporciona a los usuarios.
Estas diferencias en cuanto a la visibilidad de las apps afecta los resultados que se muestran correspondientes a métodos que proporcionan información sobre otras aplicaciones, como queryIntentActivities()
.
Además, afectan las interacciones explícitas con otras apps, como cuando se pretende iniciar su servicio.
En esta guía, se menciona el conjunto de apps visible automáticamente para la tuya y se describe cómo hacer lo mismo con otras aplicaciones. También se ofrecen algunas sugerencias para configurar mensajes de registro a fin de determinar cómo la visibilidad de otras apps afecta la tuya.
Apps visibles automáticamente
El sistema hace que algunas aplicaciones sean visibles automáticamente para la tuya para que pueda interactuar con ellas sin necesidad de declarar el elemento <queries>
. Con este comportamiento, se brinda funcionalidad básica y casos de uso comunes.
En especial, los siguientes tipos de aplicaciones son siempre visibles para la tuya, incluso si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores:
- Tu propia app
- Determinados paquetes del sistema, como el proveedor de contenido multimedia, que implementan la funcionalidad principal de Android; obtén más información para determinar qué paquetes son visibles automáticamente en el dispositivo que ejecuta tu app
- La app que instaló la tuya
- Cualquier app que inicie una actividad en la tuya con el método
startActivityForResult()
, como se describe en la guía para obtener un resultado de una actividad - Cualquier app que se inicie o se vincule a un servicio de la tuya
- Cualquier app que acceda a un proveedor de contenido en la tuya
- Cualquier app que tenga un proveedor de contenido al que tu aplicación pueda acceder mediante los permisos de URI correspondientes
- Cualquier app que reciba entradas de tu app (este caso se aplica solo cuando tu aplicación proporciona entradas como un editor de método de entrada)
Además, puedes iniciar la actividad de otra app con un intent implícito o explícito, independientemente de si la otra aplicación es visible para la tuya.
Paquetes de sistema visibles automáticamente
Algunos de los paquetes del sistema que implementan funcionalidades principales de Android son visibles automáticamente para tu app, incluso cuando esta se orienta a Android 11 (nivel de API 30) o versiones posteriores. El conjunto específico de paquetes depende del dispositivo que ejecuta tu aplicación.
Para ver la lista completa de paquetes de un dispositivo específico, ejecuta el siguiente comando en una terminal de tu máquina de desarrollo:
adb shell dumpsys package queries
En el resultado del comando, busca la sección forceQueryable
. Allí, se incluye la lista de paquetes que el dispositivo hizo visible automáticamente para tu app.
Declara que tu app interactúa con un conjunto de aplicaciones específico
Si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores y necesita interactuar con aplicaciones 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.
Consulta a paquetes específicos e interactúa con ellos
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 realizar consultas a otras apps e interactuar con ellas según un 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
oport
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*
.
Cómo realizar consultas en apps e interactuar con ellas según una autoridad de proveedor
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 varias autoridades de proveedores en un solo elemento <queries>
.
Para hacerlo, completa uno de los siguientes pasos:
- En un solo elemento
<provider>
, declara una lista de autoridades delimitadas por punto y coma. - Incluye varios elementos
<provider>
, todos dentro del mismo elemento<queries>
. En cada elemento<provider>
, declara una sola autoridad o una lista de autoridades delimitadas por punto y coma.
Cómo realizar consultas en todas las apps e interactuar con ellas
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 lanzamiento
- Apps de accesibilidad
- Navegadores
- Apps de uso compartido entre pares (P2P)
- Apps de administración de dispositivos
- Apps de seguridad
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 aplicaciones 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.
En una próxima actualización de la política, busca en Google Play los lineamientos para las apps que necesitan el permiso QUERY_ALL_PACKAGES
.
Mensajes de registro para filtrar paquetes
A fin de descubrir más detalles sobre la manera en la que la visibilidad predeterminada de las apps afecta la tuya, puedes habilitar los mensajes de registro para filtrar paquetes. Si estás desarrollando una app de prueba o depurable en Android Studio, la función ya estará habilitada. De lo contrario, puedes ejecutar el siguiente comando en una ventana de terminal para habilitarla manualmente:
adb shell pm log-visibility --enable PACKAGE_NAME
Luego, cada vez que se filtran paquetes de los valores que se muestran de un objeto PackageManager
, aparece un mensaje similar al siguiente en Logcat:
I/AppsFilter: interaction: PackageSetting{7654321 \ com.example.myapp/12345} -> PackageSetting{...} BLOCKED