O arquivo APK 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 variações de compilação e bibliotecas
importadas. Ao compilar o aplicativo, a compilação do Gradle combina
todos os arquivos de manifesto em um único arquivo de manifesto, empacotado
com o APK.
A ferramenta de combinação de manifestos combina todos os elementos XML de cada arquivo seguindo algumas heurísticas de combinação e obedecendo preferências de combinação definidas com atributos XML especiais. Esta página descreve como funciona a combinação de manifestos e como é possível aplicar preferências de combinação para resolver conflitos.
Dica: Use a visualização Merged Manifest para visualizar os resultados do manifesto combinado e encontrar erros de conflito.
Prioridades de combinação
A ferramenta de combinação reúne todos os arquivos de manifesto em um único arquivo, combinando-os sequencialmente de acordo com a prioridade de cada arquivo de manifesto. Por exemplo, se você tiver três arquivos de manifesto, o manifesto de menor prioridade será combinado ao próximo manifesto de maior prioridade. Por sua vez, o resultado dessa combinação será combinado ao próximo manifesto de maior prioridade, como mostrado na figura 1.
Figura 1. Processo de combinação de três arquivos de manifesto, da menor prioridade (esquerda) para a maior prioridade (direita)
Há três tipos básicos de arquivos de manifesto que podem ser combinados entre si, com as seguintes prioridades de combinação (maior prioridade antes):
- Arquivo de manifesto para a variação de compilação
Se você tiver vários conjuntos de origem para a variação, as prioridades dos manifestos serão as seguintes:
- Manifesto da variação de compilação (como
src/demoDebug/) - Manifesto do tipo de compilação (como
src/debug/) - Manifesto do tipo de produto (como
src/demo/)Se você estiver usando dimensões de tipo, as prioridades do manifesto corresponderão à ordem em que cada dimensão está listada na propriedade
flavorDimensions(a primeira tem a maior prioridade).
- Manifesto da variação de compilação (como
- Arquivo de manifesto principal para o módulo de aplicativo
- Arquivo de manifesto de uma biblioteca incluída
Se você tiver várias bibliotecas, as prioridades do manifesto corresponderão à ordem das dependências (a ordem em que aparecem no bloco
dependenciesdo Gradle).
Por exemplo, um manifesto de biblioteca é combinado ao manifesto principal. Em seguida, o manifesto principal é combinado ao manifesto da variação de compilação.
Observação: Essas são as mesmas prioridades de combinação para todos os conjuntos de origem, como descritos em Compile com conjuntos de origem.
Importante: As configurações de compilação do
arquivo build.gradle modificam todos os atributos correspondentes no
arquivo de manifesto combinado. Por exemplo, a minSdkVersion do arquivo build.gradle
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 obter mais
detalhes, consulte Configurar sua compilação.
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 obter detalhes sobre como essa correspondência funciona, consulte o apêndice sobre políticas de combinação).
Se um elemento do manifesto de menor prioridade não corresponder a nenhum elemento no manifesto de maior prioridade, ele será adicionado ao manifesto combinado. No entanto, se houver um elemento correspondente, a ferramenta de combinação tentará combinar todos os atributos de cada elemento 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.
Tabela 1. Comportamento padrão de combinação para valores de atributo
| Atributo de alta prioridade | Atributo de baixa prioridade | Resultado combinado do atributo |
|---|---|---|
| Sem valor | Sem valor | Sem valor (usar valor padrão) |
| Valor B | Valor B | |
| Valor A | Sem valor | Valor A |
| Valor A | Valor A | |
| Valor B | Erro de conflito– é necessário adicionar 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 juntos. Somente os atributos do manifesto de maior prioridade são usados. - O atributo
android:requirednos elementos<uses-feature>e<uses-library>usam uma combinação OR. Ou seja, se houver um conflito, será aplicado"true"e o recurso ou biblioteca exigido por um manifesto será sempre incluído. - Os atributos no elemento
<uses-sdk>usam sempre o valor do manifesto de maior prioridade, exceto nos seguintes casos:- Quando o manifesto de menor prioridade tiver um
minSdkVersionvalor maior, ocorrerá um erro, a menos que você aplique a regra de combinaçãooverrideLibrary. - Quando o manifesto de menor prioridade tiver um
targetSdkVersionvalor menor, a ferramenta de combinação usará o valor do manifesto de maior prioridade, mas também adicionará todas as permissões de sistema necessárias para garantir que a biblioteca importada continue a funcionar corretamente (para quando a versão maior do Android tiver permissões mais rígidas). Para obter mais informações sobre esse comportamento, consulte a seção sobre permissões de sistema implícitas.
- Quando o manifesto de menor prioridade tiver um
- O elemento
<intent-filter>nunca é correspondido entre manifestos. Cada elemento é tratado como único e adicionado ao elemento pai comum no manifesto combinado.
Para todos os outros conflitos entre atributos, você receberá um erro e deverá mostrar à ferramenta de combinação como resolvê-lo, adicionando 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 pode gerar
resultados inesperados se o manifesto de maior prioridade depender realmente 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,
usará o valor de "standard". No entanto, se o
atributo de menor prioridade declarar esse atributo com um valor diferente, esse
valor será aplicado ao manifesto combinado (modificando o valor padrão). Portanto,
defina explicitamente cada atributo com o valor desejado. (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 de combinação ou remover elementos e atributos indesejados. 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 antes
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 um determinado elemento de manifesto e a todas as suas tags filhas), 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 combinado:
<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 nesta 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 combinado:
<activity android:name=”com.example.ActivityOne” android:screenOrientation=”portrait” android:windowSoftInputMode=”stateUnchanged”> </activity> tools:node="remove"- Remover este elemento do manifesto combinado. Embora possa parecer que
deveria simplesmente excluir esse elemento, é necessário usar esse atributo quando
você descobre um elemento desnecessário no manifesto combinado,
fornecido por um arquivo de manifesto de menor prioridade sobre o qual não tem 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 combinado:
<activity-alias android:name=”com.example.alias”> <meta-data android:name=”duck” android:value=”@string/quack”/> </activity-alias> tools:node="removeAll"- Como
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 combinado:
<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 combinado:
<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 compilação todas as vezes 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 simplesmente incluir um atributo extra,
a compilação falhará (enquanto que o comportamento padrão adicionará o atributo extra
ao manifesto combinado).
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. Portanto, é necessário aplicar outros marcadores de regra de combinação para resolver essas diferenças. (Normalmente, os dois elementos serão combinados sem problemas, como mostrado nos exemplos de
tools:node="merge"acima.)
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 de atributo (incluindo o namespace do atributo), separados por vírgulas.
tools:remove="attr, ..."- Remover os atributos especificados do manifesto combinado. Embora possa
parecer que seja possível excluir esses atributos, é necessário
usar esse atributo quando o arquivo de manifesto de menor prioridade inclui esses
atributos e você quer garantir que eles não sejam incluídos no
manifesto combinado.
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 combinado:
<activity android:name=”com.example.ActivityOne” android:screenOrientation=”portrait”> tools:replace="attr, ..."- Substituir os atributos especificados no manifesto de menor prioridade com
os 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 combinado:
<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 compilação sempre que esses atributos do
manifesto de menor prioridade não corresponderem exatamente aos
do 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 mesclagem de manifesto. É necessário aplicar outros marcadores de regra de combinação para resolver o conflito. (Lembre-se: esse é o comportamento padrão. Portanto, o exemplo acima terá o mesmo resultado se você remover
tools:strict="screenOrientation”.)
Também é possível aplicar vários marcadores a um elemento da forma a seguir.
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 mesclado:
<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 for de 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 minSdkVersion
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 minSdkVersion do aplicativo,
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 minSdkVersion
do manifesto principal.
Por exemplo, se o manifesto principal do aplicativo 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 android:targetSdkVersion="22" android:minSdkVersion="2"
tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
...
O manifesto a seguir poderá ser combinado sem gerar erro relacionado
à tag <uses-sdk> e o manifesto combinado manterá
minSdkVersion="2" do manifesto do aplicativo.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lib1">
<uses-sdk android:minSdkVersion="4" />
...
Permissões de sistema implícitas
Algumas APIs do Android que antes eram acessadas livremente por aplicativos passaram a ser
restringidas por permissões
de sistema em versões recentes do Android. Para evitar o cancelamento de aplicativos que
contam com o acesso a essas APIs, as versões recentes do Android permitem que os aplicativos
continuem a acessar essas APIs sem a permissão, desde que definam
targetSdkVersion para um valor inferior à versão em que a restrição
foi adicionada. Na prática, esse comportamento concede ao aplicativo uma permissão
implícita para acessar as APIs. Portanto, isso pode afetar manifestos
combinados com valores diferentes de targetSdkVersion da seguinte
forma.
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 adicionada), a ferramenta de combinação
adicionará explicitamente a permissão de sistema ao manifesto combinado.
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 adicionará a permissão
WRITE_EXTERNAL_STORAGE
ao manifesto combinado. A tabela 2 lista todas as permissões possíveis
que podem ser adicionadas ao manifesto combinado.
Observação: se você definiu targetSdkVersion do aplicativo como 23 ou posterior, deverá
executar solicitações de permissão em tempo de execução para todas as permissões perigosas quando o aplicativo
tentar acessar as APIs protegidas por essas permissões. Para obter mais orientações,
consulte Trabalho com permissões do sistema.
Tabela 2. Lista de permissões que podem ser adicionadas pela ferramenta de combinação ao manifesto combinado
| 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 combinado e encontrar conflitos
Você pode visualizar o manifesto combinado mesmo antes de criar o APK
abrindo o arquivo AndroidManifest.xml no
Android Studio e clicando na guia Merged Manifest na parte inferior
do editor.
A visualização Merged Manifest mostra os resultados do manifesto combinado à esquerda e informações sobre cada arquivo de manifesto combinado à direita, como mostrado na figura 2. Os elementos combinados dos arquivos de manifesto de menor prioridade são realçados em cores diferentes à esquerda. O significado de cada cor é especificado em Manifest Sources, à direita.
Figura 2. A visualização Merged Manifest
Arquivos de manifesto que eram parte da compilação, mas não contribuíram com elementos ou atributos, são listados em Other Manifest Files à direita.
Para ver informações sobre a origem de um elemento, clique nele à esquerda e os detalhes serão exibidos em Merging Log à direita.
Se ocorrer um conflito, ele será exibido em Merging Errors no lado direito, com uma recomendação sobre como resolver o conflito usando marcadores de regra de combinação. Os erros também são impressos na janela Event Log (selecione View > Tool Windows > Event Log).
Se você quiser ver um registro completo da árvore de decisões da combinação, o
arquivo de registros está no diretório build/outputs/logs/ do módulo e é denominado
manifest-merger-buildVariant-report.txt.
Apêndice: 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 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 combinar elementos filhos de acordo com a respectiva política de combinação. Se houver um conflito entre atributos, combiná-los com os marcadores de regra de combinação.
- Combinar somente filhos
- Não combinar atributos (manter apenas os atributos fornecidos pelo arquivo de manifesto de maior prioridade) e combinar elementos filhos de acordo com sua política de combinação.
- 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 for aceitável.
A tabela 1 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.
Tabela 3. Políticas e chaves de correspondência de combinação de elementos de manifesto
| Elemento | Política de combinação | Chave de correspondência |
|---|---|---|
<action>
|
Mesclar | Atributo android:name
|
<activity>
|
Mesclar | 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 somente 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; são desconhecidos para a ferramenta de combinação e, portanto, são sempre incluídos no manifesto combinado |