Esta página descreve como funciona a combinação de manifestos e como aplicar preferências para resolver conflitos. Para saber mais sobre esses arquivos, consulte a visão geral do manifesto do app.
Combinar vários arquivos de manifesto
O arquivo APK ou Android App Bundle pode conter apenas um
arquivo AndroidManifest.xml
, mas o projeto do Android Studio pode conter
vários, disponibilizados pelo conjunto de origem principal ou por variantes de build e bibliotecas
importadas. Ao criar o app, o build do Gradle combina
todos os arquivos de manifesto em um único arquivo, empacotado
no seu app.
A ferramenta de combinação de manifestos combina todos os elementos XML de cada arquivo seguindo heurísticas de combinação e obedecendo a preferências definidas com atributos XML especiais.
Dica: use a visualização Merged Manifest , descrita na seção a seguir, para conferir os resultados do processo e encontrar erros de conflito.
Prioridades de combinação
A ferramenta de combinação mescla todos os arquivos de manifesto em um único arquivo de forma sequencial e de acordo com a prioridade de cada um deles. Por exemplo, se você tem três arquivos de manifesto, o de prioridade mais baixa é integrado ao próximo manifesto de maior prioridade. Por sua vez, esse resultado é combinado ao próximo manifesto de maior prioridade, como mostrado na Figura 1.
Há três tipos básicos de arquivos de manifesto que podem ser combinados entre si, com as seguintes prioridades de combinação (prioridade mais alta primeiro):
- Arquivo de manifesto para a
variante de build
Se você tiver vários conjuntos de origem para sua variante, estas vão ser as prioridades dos manifestos:
- Manifesto de variante de build (como
src/demoDebug/
) - Manifesto de tipo de build (como
src/debug/
) - Manifesto de variação de produto (como
src/demo/
)Se você estiver usando dimensões de variações, as prioridades dos manifestos corresponderão à ordem em que cada dimensão é listada na propriedade
flavorDimensions
(a primeira é a mais alta).
- Manifesto de variante de build (como
- Arquivo de manifesto principal para o módulo de app
- Arquivo de manifesto de uma biblioteca incluída
Se você tiver várias bibliotecas, as prioridades dos manifestos vão corresponder à ordem em que aparecem no bloco
dependencies
do Gradle.
Por exemplo, um manifesto de biblioteca é combinado ao manifesto principal. Em seguida, o manifesto principal é combinado ao manifesto da variante de build. Todos os conjuntos de origem têm as mesmas prioridades de combinação, conforme descrito em Criar com conjuntos de origem.
Importante: as configurações do build do
arquivo build.gradle
modificam todos os atributos correspondentes no
arquivo de manifesto integrado. Por exemplo, o
minSdk
do arquivo build.gradle
ou
build.gradle.kts
modifica o atributo correspondente no
elemento de manifesto
<uses-sdk>
. Para evitar confusão, basta não usar o elemento
<uses-sdk>
e definir essas propriedades apenas no
arquivo build.gradle
. Para saber mais, consulte
Configurar seu build.
Heurística de conflitos de combinação
A ferramenta de combinação pode associar logicamente cada elemento XML de um manifesto a um elemento correspondente em outro manifesto. Para saber mais sobre como a correspondência funciona, consulte as prioridades de combinação na seção anterior.
Se um elemento do manifesto de menor prioridade não corresponder a nenhum elemento no manifesto de maior prioridade, ele será adicionado ao manifesto integrado. No entanto, se houver um elemento correspondente, a ferramenta de combinação vai tentar combinar todos os atributos de cada um deles no mesmo elemento. Se a ferramenta constatar que os dois manifestos contêm o mesmo atributo com valores diferentes, ocorrerá um conflito de combinação.
A tabela 1 mostra os resultados possíveis quando a ferramenta de combinação tenta combinar todos os atributos no mesmo elemento.
Atributo de alta prioridade | Atributo de baixa prioridade | Resultado combinado do atributo |
---|---|---|
Nenhum valor | Nenhum valor | Nenhum valor (usar o valor padrão) |
Valor B | Valor B | |
Valor A | Nenhum valor | Valor A |
Valor A | Valor A | |
Valor B | Erro de conflito: adicione um marcador de regra de combinação. |
No entanto, há algumas situações em que a ferramenta de combinação se comporta de maneira diferente para evitar conflitos:
- Atributos no elemento
<manifest>
nunca são combinados. Somente os atributos do manifesto de maior prioridade são usados. - O atributo
android:required
nos elementos<uses-feature>
e<uses-library>
usa uma combinação OR. Se houver algum conflito,"true"
será aplicado, e a biblioteca ou o recurso exigido por um manifesto sempre será incluído. - Atributos no elemento
<uses-sdk>
sempre usam o valor do manifesto de maior prioridade, exceto nas seguintes situações:- Quando o manifesto de menor prioridade tem um valor de
minSdk
maior, ocorre um erro, a menos que você aplique a regra de combinaçãooverrideLibrary
. - Quando o manifesto de menor prioridade tem um valor de
targetSdkVersion
menor, a ferramenta de combinação usa o valor do manifesto de maior prioridade, mas também adiciona as permissões de sistema necessárias para o funcionamento correto da biblioteca importada (para casos em que a versão mais recente do Android tenha restrições de permissão mais rígidas). Para saber mais sobre esse comportamento, consulte a seção sobre permissões de sistema implícitas.
- Quando o manifesto de menor prioridade tem um valor de
- O elemento
<intent-filter>
nunca é correspondido entre manifestos. Cada elemento é tratado como único e adicionado ao elemento pai comum no manifesto integrado.
Para todos os outros conflitos entre atributos, você vai receber um erro e precisará instruir a ferramenta de combinação sobre a resolução. Para isso, adicione um atributo especial no arquivo de manifesto de maior prioridade. Consulte a próxima seção sobre marcadores de regra de combinação.
Não confie nos valores padrão dos atributos. Como todos os
atributos únicos são combinados no mesmo elemento, isso poderá gerar
resultados inesperados se o manifesto de maior prioridade depender do
valor padrão de um atributo sem declará-lo. Por exemplo, se o manifesto de
maior prioridade não declarar o atributo android:launchMode
,
ele vai usar o valor padrão de "standard"
. No entanto, se o manifesto
de menor prioridade declarar com um valor diferente, esse
valor é aplicado ao manifesto integrado, que substitui o valor padrão. É necessário
definir explicitamente cada atributo com o valor adequado. Os valores padrão
de cada atributo estão documentados na
Referência de manifestos.
Marcadores de regra de combinação
Um marcador de regra de combinação é um atributo XML que pode ser usado para indicar sua preferência sobre como resolver conflitos ou remover elementos e atributos inadequados. O marcador pode ser aplicado a todo um elemento ou apenas a atributos específicos de um elemento.
Na combinação de dois arquivos de manifesto, a ferramenta de combinação procura esses marcadores nos arquivos de manifesto de maior prioridade.
Todos os marcadores pertencem ao namespace tools
do Android. Portanto, é necessário declarar
primeiro esse namespace no elemento <manifest>
da seguinte forma:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" xmlns:tools="http://schemas.android.com/tools">
Marcadores de nó
Para aplicar uma regra de combinação a todo um elemento XML (a todos os atributos de determinado elemento de manifesto e a todas as tags filhas correspondentes), use os seguintes atributos:
tools:node="merge"
- Combinar todos os atributos nessa tag e todos os elementos aninhados quando
não há conflitos usando a heurística
de conflitos de combinação. Esse é o comportamento padrão para elementos.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:windowSoftInputMode="stateUnchanged"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="merge"> </activity>
Resultado do manifesto integrado:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" android:windowSoftInputMode="stateUnchanged"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
tools:node="merge-only-attributes"
- Combinar atributos somente nessa tag. Não combinar elementos aninhados.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:windowSoftInputMode="stateUnchanged"> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="image/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="merge-only-attributes"> </activity>
Resultado do manifesto integrado:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" android:windowSoftInputMode="stateUnchanged"> </activity>
tools:node="remove"
- Remover este elemento do manifesto combinado. Usado ao
descobrir um elemento desnecessário no manifesto integrado,
disponibilizado por um arquivo de manifesto de menor prioridade que está fora do seu controle
(como uma biblioteca importada).
Manifesto de baixa prioridade:
<activity-alias android:name="com.example.alias"> <meta-data android:name="cow" android:value="@string/moo"/> <meta-data android:name="duck" android:value="@string/quack"/> </activity-alias>
Manifesto de alta prioridade:
<activity-alias android:name="com.example.alias"> <meta-data android:name="cow" tools:node="remove"/> </activity-alias>
Resultado do manifesto integrado:
<activity-alias android:name="com.example.alias"> <meta-data android:name="duck" android:value="@string/quack"/> </activity-alias>
tools:node="removeAll"
- Semelhante a
tools:node="remove"
, mas remove todos os elementos que correspondem a esse tipo de elemento (dentro do mesmo elemento pai).Manifesto de baixa prioridade:
<activity-alias android:name="com.example.alias"> <meta-data android:name="cow" android:value="@string/moo"/> <meta-data android:name="duck" android:value="@string/quack"/> </activity-alias>
Manifesto de alta prioridade:
<activity-alias android:name="com.example.alias"> <meta-data tools:node="removeAll"/> </activity-alias>
Resultado do manifesto integrado:
<activity-alias android:name="com.example.alias"> </activity-alias>
tools:node="replace"
- Substituir completamente o elemento de menor prioridade. Ou seja, se existir
um elemento correspondente no manifesto de menor prioridade, ele será ignorado e o elemento será usado
exatamente como aparece neste manifesto.
Manifesto de baixa prioridade:
<activity-alias android:name="com.example.alias"> <meta-data android:name="cow" android:value="@string/moo"/> <meta-data android:name="duck" android:value="@string/quack"/> </activity-alias>
Manifesto de alta prioridade:
<activity-alias android:name="com.example.alias" tools:node="replace"> <meta-data android:name="fox" android:value="@string/dingeringeding"/> </activity-alias>
Resultado do manifesto integrado:
<activity-alias android:name="com.example.alias"> <meta-data android:name="fox" android:value="@string/dingeringeding"/> </activity-alias>
tools:node="strict"
- Gerar um erro de build sempre que este elemento no manifesto de menor prioridade
não corresponder exatamente ao elemento no manifesto de maior prioridade, a menos
que resolvido por outros marcadores de regra de combinação. Isso modifica a heurística de conflitos de combinação. Por
exemplo, se o manifesto de menor prioridade incluir um atributo extra,
a criação vai falhar. Por outro lado, o comportamento padrão adiciona o atributo extra
ao manifesto integrado.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:windowSoftInputMode="stateUnchanged"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="strict"> </activity>
Isso cria um erro de combinação de manifesto. No modo rígido, os dois elementos de manifesto não podem ter qualquer diferença. É necessário aplicar outros marcadores de regra de combinação para resolver essas diferenças. Sem
tools:node="strict"
, esses dois arquivos podem ser combinados sem erros, como mostrado no exemplo detools:node="merge"
.
Marcadores de atributo
Para aplicar uma regra de combinação apenas a atributos específicos de uma tag de manifesto, use os atributos a seguir. Cada atributo aceita um ou mais nomes (incluindo o namespace do atributo), separados por vírgulas.
tools:remove="attr, ..."
- Remover os atributos especificados do manifesto integrado.
Usado quando o arquivo de manifesto de menor prioridade inclui esses
atributos e você quer garantir que eles não sejam incluídos no manifesto
integrado.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:windowSoftInputMode="stateUnchanged">
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:remove="android:windowSoftInputMode">
Resultado do manifesto integrado:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait">
tools:replace="attr, ..."
- Substituir os atributos especificados no manifesto de menor prioridade por
aqueles deste manifesto. Em outras palavras, manter sempre os valores do
manifesto de maior prioridade.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:theme="@oldtheme" android:exported="false" android:windowSoftInputMode="stateUnchanged">
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:screenOrientation="portrait" tools:replace="android:theme,android:exported">
Resultado do manifesto integrado:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:screenOrientation="portrait" android:windowSoftInputMode="stateUnchanged">
tools:strict="attr, ..."
- Gerar um erro de build todas as vezes que esses atributos no
manifesto de menor prioridade não corresponderem exatamente aos atributos no manifesto
de maior prioridade. Esse é o comportamento padrão para todos os atributos, exceto os
que têm comportamentos especiais, como definidos na heurística de conflitos de combinação.
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="landscape"> </activity>
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:strict="android:screenOrientation"> </activity>
Isso cria um erro de combinação de manifesto. Aplique outros marcadores de regra de combinação para resolver o conflito. Esse é o comportamento padrão, portanto, o mesmo resultado ocorre ao adicionar explicitamente
tools:strict="screenOrientation"
.
Também é possível aplicar vários marcadores a um elemento, conforme mostrado neste exemplo:
Manifesto de baixa prioridade:
<activity android:name="com.example.ActivityOne" android:theme="@oldtheme" android:exported="false" android:allowTaskReparenting="true" android:windowSoftInputMode="stateUnchanged">
Manifesto de alta prioridade:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:screenOrientation="portrait" tools:replace="android:theme,android:exported" tools:remove="android:windowSoftInputMode">
Resultado do manifesto integrado:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:allowTaskReparenting="true" android:screenOrientation="portrait">
Seletor de marcadores
Se você quiser aplicar os marcadores de regra de combinação apenas
a uma biblioteca importada específica, adicione o atributo tools:selector
com
o nome do pacote da biblioteca.
Por exemplo, com o manifesto a seguir, a regra de combinação
remove
será aplicada apenas quando o arquivo de manifesto de menor prioridade for da
biblioteca com.example.lib1
.
<permission android:name="permissionOne" tools:node="remove" tools:selector="com.example.lib1">
Se o manifesto de menor prioridade tiver qualquer outra origem, a
regra de combinação remove
será ignorada.
Observação: se você usar esse atributo com um dos marcadores de atributo, ele será aplicado a todos os atributos especificados no marcador.
Modificar <uses-sdk> para bibliotecas importadas
Por padrão, na importação de uma biblioteca com um valor de minSdk
maior que o arquivo de manifesto principal, ocorre um erro e
não é possível importar a biblioteca.
Para fazer com que a ferramenta de combinação ignore esse conflito e
importe a biblioteca, mantendo o valor menor de minSdk
do app, adicione o atributo overrideLibrary
à tag <uses-sdk>
.
O valor do atributo pode ser um ou mais nomes de pacotes de biblioteca,
separados por vírgulas, indicando as bibliotecas que podem modificar a minSdk
do manifesto principal.
Por exemplo, se o manifesto principal do app aplicar overrideLibrary
desta forma:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app" xmlns:tools="http://schemas.android.com/tools"> <uses-sdk tools:overrideLibrary="com.example.lib1, com.example.lib2"/> ...
O manifesto a seguir poderá ser integrado sem gerar erro relacionado à tag <uses-sdk>
, e o manifesto integrado manterá o minSdk="2"
do manifesto do app.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.lib1"> <uses-sdk android:minSdk="4" /> ...
Permissões de sistema implícitas
Algumas APIs do Android que antes eram acessadas livremente por apps passaram a ser restringidas por permissões de sistema em versões mais recentes do Android.
Para evitar o cancelamento de apps que precisam de acesso a essas
APIs, as versões recentes do Android permitem que os apps continuem acessando essas APIs
sem permissão se o targetSdkVersion
estiver definido como um valor inferior
à versão em que a restrição foi adicionada. Na prática,
esse comportamento concede ao app uma permissão implícita para acessar as APIs. Os manifestos
integrados que têm valores diferentes para
targetSdkVersion
podem ser afetados.
Se o arquivo de manifesto de menor prioridade tiver um valor menor de
targetSdkVersion
que forneça uma permissão implícita
e o manifesto de maior prioridade não tiver a mesma permissão implícita
(porque targetSdkVersion
é maior ou igual
à versão em que a restrição foi implementada), a ferramenta de combinação
vai adicionar explicitamente a permissão de sistema ao manifesto integrado.
Por exemplo, se o aplicativo definir targetSdkVersion
como 4 ou maior e importar uma
biblioteca com targetSdkVersion
definido como 3 ou menor, a ferramenta de combinação vai adicionar a permissão WRITE_EXTERNAL_STORAGE
ao manifesto integrado.
A Tabela 2 lista todas as permissões possíveis que podem ser adicionadas ao manifesto integrado.
Declaração do manifesto de menor prioridade | Permissões adicionadas ao manifesto combinado |
---|---|
targetSdkVersion é 3 ou menor |
WRITE_EXTERNAL_STORAGE , READ_PHONE_STATE |
targetSdkVersion é 15 ou menor e usa READ_CONTACTS |
READ_CALL_LOG |
targetSdkVersion é 15 ou menor e usa WRITE_CONTACTS |
WRITE_CALL_LOG |
Inspecionar o manifesto integrado e encontrar conflitos
Você pode ver o manifesto integrado mesmo antes de criar o app. Para conferir uma prévia, siga estas etapas:
- No Android Studio, abra o arquivo
AndroidManifest.xml
. - Clique na guia Merged Manifest na parte de baixo do editor.
A visualização "Merged Manifest" mostra os resultados do manifesto integrado à esquerda e as informações sobre cada arquivo dele à direita, conforme apresentado na Figura 2.
Os elementos combinados dos arquivos de manifesto de menor prioridade são destacados em cores diferentes à esquerda. O significado de cada cor é especificado em Manifest Sources.
Arquivos de manifesto que eram parte do build, mas não contribuíram com elementos ou atributos, são listados em Other Manifest Files.
Para ver informações sobre a origem de um elemento, clique nele no painel à esquerda. Os detalhes vão aparecer em Merging Log.
Se ocorrer um conflito, ele vai aparecer em Merging errors, com uma recomendação sobre como resolver o conflito usando marcadores de regra de combinação.
Os erros também são exibidos na janela Event Log. Para vê-los, selecione View > Tool Windows > Event Log.
Acesse um registro completo da árvore de decisões de combinação, o arquivo de registros
no diretório build/outputs/logs/
do módulo com o nome
manifest-merger-buildVariant-report.txt
.
Políticas de combinação
A ferramenta de combinação de manifestos pode associar logicamente cada elemento XML de um arquivo
de manifesto a um elemento correspondente em outro arquivo. A ferramenta de combinação corresponde cada documento
usando uma chave de correspondência: um valor de atributo único (como android:name
) ou
a unicidade natural da própria tag (por exemplo, somente pode existir um único
elemento <supports-screen>
).
Se dois manifestos tiverem o mesmo elemento XML, a ferramenta vai combinar os dois elementos usando uma das três políticas de combinação a seguir:
- Combinar
- Combinar todos os atributos não conflitantes na mesma tag e integrar elementos filhos de acordo com a respectiva política de combinação. Se houver um conflito entre atributos, eles devem ser combinados usando os marcadores de regra de combinação.
- Combinar apenas filhos
- Não combinar ou integrar atributos (manter apenas os atributos disponibilizados pelo arquivo de manifesto de maior prioridade) e integrar elementos filhos de acordo com a política de combinação deles.
- Manter
- Deixar o elemento "como está" e adicioná-lo ao elemento pai comum no arquivo combinado. Usado apenas quando a existência de várias declarações para o mesmo elemento é aceitável.
A Tabela 3 lista cada tipo de elemento, o tipo de política de combinação usada e a chave usada para determinar uma correspondência de elemento entre dois manifestos.
Elemento | Política de combinação | Chave de correspondência |
---|---|---|
<action>
|
Combinar | Atributo android:name
|
<activity>
|
Combinar | Atributo android:name
|
<application>
|
Combinar | Há apenas um por <manifest> .
|
<category>
|
Combinar | Atributo android:name
|
<data>
|
Combinar | Há apenas um por <intent-filter> .
|
<grant-uri-permission>
|
Combinar | Há apenas um por <provider> .
|
<instrumentation>
|
Combinar | Atributo android:name
|
<intent-filter>
|
Manter | Sem correspondência. São permitidas várias declarações dentro do mesmo elemento pai. |
<manifest>
|
Combinar apenas filhos | Há apenas um por arquivo. |
<meta-data>
|
Combinar | Atributo android:name
|
<path-permission>
|
Combinar | Há apenas um por <provider> .
|
<permission-group>
|
Combinar | Atributo android:name
|
<permission>
|
Combinar | Atributo android:name
|
<permission-tree>
|
Combinar | Atributo android:name
|
<provider>
|
Combinar | Atributo android:name
|
<receiver>
|
Combinar | Atributo android:name
|
<screen>
|
Combinar | Atributo android:screenSize
|
<service>
|
Combinar | Atributo android:name
|
<supports-gl-texture>
|
Combinar | Atributo android:name
|
<supports-screen>
|
Combinar | Há apenas um por <manifest> .
|
<uses-configuration>
|
Combinar | Há apenas um por <manifest> .
|
<uses-feature>
|
Combinar | Atributo android:name (se ausente, o atributo android:glEsVersion )
|
<uses-library>
|
Combinar | Atributo android:name
|
<uses-permission>
|
Combinar | Atributo android:name
|
<uses-sdk>
|
Combinar | Há apenas um por <manifest> .
|
Elementos personalizados | Combinar | Sem correspondência. Eles são desconhecidos para a ferramenta de combinação e estão sempre incluídos no manifesto integrado. |
Injetar variáveis de build no manifesto
Caso você precise inserir variáveis no arquivo AndroidManifest.xml
que estão
definidas no arquivo build.gradle
, isso pode ser feito com a
propriedade manifestPlaceholders
. Essa propriedade usa um mapa de pares de chave-valor,
conforme mostrado aqui:
Groovy
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] } ... }
Kotlin
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" } ... }
Você pode inserir um dos marcadores no arquivo de manifesto como um valor de atributo:
<intent-filter ... >
<data android:scheme="https" android:host="${hostName}" ... />
...
</intent-filter>
Por padrão, as ferramentas de build também fornecem o
ID do aplicativo
no marcador ${applicationId}
. O valor sempre corresponde ao ID
do aplicativo final para o build atual, incluindo
mudanças por variantes de build.
Isso é útil quando você quer usar um namespace exclusivo para identificadores,
como uma ação da intent, mesmo entre suas variantes de build.
Por exemplo, se o arquivo build.gradle
tiver esta aparência:
Groovy
android { defaultConfig { applicationId "com.example.myapp" } flavorDimensions "type" productFlavors { free { applicationIdSuffix ".free" dimension "type" } pro { applicationIdSuffix ".pro" dimension "type" } } }
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } flavorDimensions += "type" productFlavors { create("free") { applicationIdSuffix = ".free" dimension = "type" } create("pro") { applicationIdSuffix = ".pro" dimension = "type" } } }
Então, você poderá inserir o ID do aplicativo no manifesto da seguinte forma:
<intent-filter ... >
<action android:name="${applicationId}.TRANSMOGRIFY" />
...
</intent-filter>
E o resultado do manifesto quando você criar a variação "sem custo" do produto será este:
<intent-filter ... >
<action android:name="com.example.myapp.free.TRANSMOGRIFY" />
...
</intent-filter>
Encontre mais informações no artigo Definir o ID do aplicativo.