Error de Android Studio: "Falló la fusión del manifiesto: aplicaciones orientadas a Android 12" [duplicado]
Actualicé mi versión del emulador y la versión del SDK de Android a Android S ( Android 12 ). Después de la actualización, no puedo ejecutar el proyecto. No puedo ejecutar un ¡Hola, mundo! proyecto (proyecto vacío), pero puedo construir Gradle también, pero no puedo ejecutar el proyecto. Siempre recibí el error:
Error en la fusión del manifiesto: las aplicaciones destinadas a Android 12 y versiones posteriores deben especificar un valor explícito para
android: exported
cuando el componente correspondiente tenga definido un filtro de intención. Consulte https://developer.android.com/guide/topics/manifest/activity-element#exported para obtener más detalles.
¿Cómo puedo arreglarlo?
Aquí hay una captura de pantalla:
¿Cómo puedo resolver este problema al utilizar el SDK de Android 12?
Esta pregunta trata sobre el problema después de aplicar la solución y es diferente a esta pregunta. Además, esta pregunta es más antigua que esta .
Es necesario especificar android:exported="false"
oandroid:exported="true"
Manifiesto:
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.MyApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
como se menciona en el documento :
Si su aplicación está orientada a Android 12 y contiene actividades, servicios o receptores de transmisión que usan filtros de intención, debe declarar explícitamente el atributo exportado android: para estos componentes de la aplicación.
Advertencia : si una actividad, servicio o receptor de transmisión utiliza filtros de intención y no tiene un valor declarado explícitamente para android: exportado, su aplicación no se puede instalar en un dispositivo que ejecute Android 12.
También verifique cuándo usar verdadero/falso para el valor 'android:exportado'.
En su manifiesto, agregue android:exported="true" o android:exported="false " en su atributo de actividad de inicio predeterminado.
¡Hecho! Está bien ejecutar sus aplicaciones en Android 12 .
<manifest ... >
<activity
android:name=".ui.dashboard.DashboardActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</manifest>
Establezca Android: valor exportado según sus necesidades.
Si el receptor de transmisión puede recibir mensajes de fuentes ajenas al sistema fuera de su aplicación: "verdadero" si puede y "falso" si no. Si es "falso", los únicos mensajes que el receptor de transmisión puede recibir son los enviados por el sistema, los componentes de la misma aplicación o las aplicaciones con el mismo ID de usuario.
Si no se especifica, el valor predeterminado depende de si el receptor de transmisión contiene filtros de intención. Si el receptor contiene al menos un filtro de intención, entonces el valor predeterminado es "verdadero". De lo contrario, el valor predeterminado es "falso".
Este atributo no es la única forma de limitar la exposición externa de un receptor de radiodifusión. También puede utilizar el permiso para limitar las entidades externas que pueden enviar mensajes (consulte el atributo de permiso).
De la documentación de Android
Si no encontró en su manifiesto el lugar donde hay una actividad sin la etiqueta "android: exported = false", entonces es probable que esté en sus dependencias... para poder identificar dónde exactamente, primero baje a "compileSdkVersion" a 30 y "targetSdkVersion" a 30 para que se construya.
android {
compileSdkVersion("android-S")
buildToolsVersion "30.0.3"
defaultConfig {
...
minSdkVersion 23
targetSdkVersion("S")
...
}
Después de eso, en la ventana principal de manifest.xml hay una pestaña con "manifiesto combinado". Allí puedes inspeccionar qué actividad exactamente no tenía el atributo "android: exported = false".
En mi caso fue por herramientas de terceros:
Archivo build.gradle (: aplicación):
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
//and
debugImplementation "com.github.markzhai:blockcanary-android:1.5.0"
releaseImplementation "com.github.markzhai:blockcanary-no-op:1.5.0"
Además, para los servicios tuve que agregar el atributo:
<service
android:name=".autofillservice.MyAutofillService"
android:exported="true"
android:permission="android.permission.BIND_AUTOFILL">
y
<service
android:name="com.demo.myApp.my_access.MyAccessService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
Como mi problema estaba en una dependencia de terceros y no se actualizará pronto, simplemente agregué una declaración <actividad> con la bandera android:exported="true" y exported="false" donde era necesario para anular la declaración inicial. , además, como necesito esta dependencia solo en Debug, agregué un nuevo archivo AndroidManifest.xml en src/debug:
Para fuga_canario:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name="leakcanary.internal.activity.LeakActivity"
android:exported="true"
android:icon="@mipmap/leak_canary_icon"
android:label="@string/leak_canary_display_activity_label"
android:taskAffinity="com.squareup.leakcanary.${applicationId}"
android:theme="@style/leak_canary_LeakCanary.Base">
<intent-filter android:label="@string/leak_canary_import_hprof_file">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="*/*" />
<data android:host="*" />
<data android:pathPattern=".*\\.hprof" />
<data android:pathPattern=".*\\..*\\.hprof" />
<data android:pathPattern=".*\\..*\\..*\\.hprof" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.hprof" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.hprof" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.hprof" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.hprof" />
</intent-filter>
</activity>
<activity
android:name="leakcanary.internal.RequestStoragePermissionActivity"
android:excludeFromRecents="true"
android:exported="false"
android:icon="@mipmap/leak_canary_icon"
android:label="@string/leak_canary_storage_permission_activity_label"
android:taskAffinity="com.squareup.leakcanary.${applicationId}"
android:theme="@style/leak_canary_Theme.Transparent" />
<receiver
android:name="leakcanary.internal.NotificationReceiver"
android:exported="false" />
</application>
</manifest>
También puede utilizar el atributo tools:node="merge" y declarar android:exported=true|false como amablemente sugirió LeoFarage .