Como resolvo “Arquivos duplicados copiados no APK META-INF / *”

91

Estou trabalhando em um aplicativo comercial para Android. Também estou usando algumas bibliotecas licenciadas sob diferentes tipos de licença, algumas delas declarando o seguinte:

Se a biblioteca tiver um arquivo de "AVISO" com notas de atribuição, você deve incluir esse AVISO ao distribuir

(Um deles está licenciado sob a Licença Apache 2.0, por exemplo).

Existe mais de uma biblioteca. Quando faço a compilação com o gradle ou com o Android Studio , obtenho o seguinte erro de compilação:

* What went wrong:
Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/license.txt

As respostas que encontrei até agora na internet e stackoverflow sugerem remover o license.txt (notice.txt ou outros arquivos que possam interferir assim) da embalagem, adicionando ao build.gradlearquivo o seguinte:

packagingOptions {
    exclude 'META-INF/DEPENDENCIES.txt'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/dependencies.txt'
    exclude 'META-INF/LGPL2.1'
}

Veja, por exemplo: Android Studio 0.4 arquivos duplicados copiados no APK META-INF / LICENSE.txt

De acordo com a licença dessas bibliotecas ( Licença Apache 2.0 por exemplo), os arquivos de licença e aviso devem ser incluídos .

Minha pergunta: Como posso adicionar vários arquivos relacionados ao licenciamento (como license.txt , notice.txt etc.) do gradle em meu projeto para estar em conformidade com as licenças ( detalhes técnicos: os textos das licenças serão concatenados)?

Flowryn
fonte
2
Em um POV técnico, você não pode empacotar coisas de forma que todos os arquivos "obrigatórios" de cada biblioteca estejam em seu próprio diretório? Uma alternativa que tenho visto com alguns aplicativos é que você (manualmente) combine todos os respectivos arquivos de licença / aviso em um recurso e inclua / exiba (onde duas ou mais bibliotecas compartilham a mesma versão de licença, você deve ser capaz de agrupá-los , "A Biblioteca A e a Biblioteca B estão incluídas, sujeitas à seguinte licença: ...").
TripeHound
@TripeHound é isso que eu faço atualmente como uma solução alternativa, enquanto no processo de desenvolvimento eu os excluo e quando se trata de lançar: comente todas as 'exclusões' e resolva as licenças manualmente.
Flowryn
1
pesquisar a resposta "packagingOptions - exclude" merece um voto positivo
Ahmed Adel Ismail

Respostas:

47

Existe uma solução se você tiver apenas uma licença usando o nome license.txt(leia: todas as license.txtcópias são idênticas):

packagingOptions {
   pickFirst  'META-INF/license.txt'
}

Caso contrário, o Google também lançou um plug-in Gradle para gerenciar licenças de dependências. Veja aqui . Não tentei, mas parece que é capaz de agregar todas as dependências e até gerar uma atividade exibindo todas essas licenças.

Marc Plano-Lesay
fonte
1
Tenho 2 licenças neste momento, uma é do Apache 2.0 e a outra GPL 3.0. Minha solução alternativa atual é excluí-los durante a fase de desenvolvimento e incluí-los manualmente quando lançarmos. Todo o license.txt será concatenado. O mesmo para Notice.txt De qualquer forma, gosto da sua abordagem com pickFirst no caso de a licença ser idêntica!
Flowryn
3
Se você encontrar uma maneira de concatenar licenças automaticamente, sou todo ouvidos!
Marc Plano-Lesay
Isso é o que estou investigando agora. Primeiro, preciso descobrir o que (e como) está executando a tarefa gradle que gerou o conflito (para isso, fiz esta pergunta: stackoverflow.com/questions/34287701/… ) E, em seguida, substituí-lo
Flowryn
@Flowryn como você inclui todos os Notice.txt manualmente, apenas copie-os em um Notice.txt? não pode modificá-lo que no jararquivo
chinaanihchen
você mencionou que o problema está nas bibliotecas que estão sendo usadas ... no meu caso, sou responsável por criar as bibliotecas que estou usando ... o que posso estar fazendo de errado ao fazê-las? Obrigado
Eric
32

Adicione o seguinte ao respectivo arquivo build.gradle

packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/MANIFEST.MF'
    }
Max Droid
fonte
1
Isso exclui licenças que, para a maioria deles, é explicitamente contra suas condições.
Marc Plano-Lesay
1
Isso deve estar no fechamento {} do Android para as versões atuais (2. *) do Gradle
mijiturka de
4

Eu enfrentei o mesmo problema com meu aplicativo. Você precisa se certificar de que não adicionou nenhuma biblioteca duas vezes. Se você seguiu a documentação do firebase https://firebase.google.com/docs/android/setup

Então você não deve adicionar a biblioteca do firebase dentro do android studio, ou seja, arquivo-> estrutura do projeto-> nuvem-> firebase

Você precisa fazer apenas um dos dois para usar o firebase em seu aplicativo Android.

No final, limpe e execute novamente seu aplicativo.

poderoso
fonte
2
Se você usar o jackson-databind, terá o problema ao adicioná-lo uma vez.
O incrível janeiro
0

Você pode adicionar várias licenças no gradle, veja isto

Akhil Jayakumar
fonte
0

Acho que você precisa incluir apenas estas opções no build.gradle:

android {
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
    }
}
S.sadham hussain
fonte
-2

Com certeza vai funcionar

packagingOptions {
 exclude 'META-INF/LICENSE.txt'
 exclude 'META-INF/NOTICE.txt'   }
Doces Mahendran
fonte
1
Não, não vai: isso exclui as licenças. É ilegal de acordo com os referidos termos de licença.
Marc Plano-Lesay
Não, é uma solução tmp para compilação instantânea de um projeto
Mahendran Candy
1
Qualquer que seja o uso, leia as licenças: para a grande maioria deles, o que você está conseguindo com sua regra de exclusão é ilegal.
Marc Plano-Lesay