É possível usar várias autoridades com o FileProvider?

fundo

Eu mantenho umbiblioteca cuja funcionalidade principal envolve o compartilhamento de capturas de tela capturadas programaticamente em aplicativos de email externos.

Eu uso umFileProvider para conseguir isso, o que significa que o manifesto da minha biblioteca contéma <provider> etiqueta, rótulo, palavra-chave:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.bugshaker.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
</provider>

filepaths.xml é definido da seguinte maneira:

<paths>
    <files-path path="bug-reports/" name="bug-reports" />
</paths>

Um consumidor da minha biblioteca possui um aplicativo que usa ele próprio umFileProvider para compartilhar arquivos. Minha expectativa era que fosse possível permitir que ambos os provedores compartilhassem arquivos se o aplicativo consumidor usasse o seguinte manifesto<provider> etiqueta, rótulo, palavra-chave:

<provider
    android:authorities="${applicationId}.fileprovider;${applicationId}.bugshaker.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true"
    android:name="android.support.v4.content.FileProvider"
    tools:replace="android:authorities">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"
        tools:replace="android:resource" />
</provider>

Esta entrada de manifesto:

especifica doisProvider autoridades${applicationId}.fileprovider (para compartilhamento de arquivos do aplicativo) e${applicationId}.bugshaker.fileprovider (para compartilhamento de arquivos de biblioteca);referencia uma atualizaçãofilepaths.xml, que contém definições de diretório separadas para arquivos gerados por aplicativo e arquivos gerados por biblioteca:
<paths>
    <external-path
        name="redacted"
        path="" />
    <files-path
        name="bug-reports"
        path="bug-reports/" />
</paths>

Após criar o aplicativo, confirmamos que o manifesto gerado teve os nós corretos substituídos por esses valores atualizados.

No entanto, quando o aplicativo que usa essa configuração é montado (com êxito) e executado, vemos uma falha no lançamento:

E: FATAL EXCEPTION: main
   Process: com.stkent.bugshakertest, PID: 11636
   java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
       at android.app.ActivityThread.installProvider(ActivityThread.java:5856)
       at android.app.ActivityThread.installContentProviders(ActivityThread.java:5445)
       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5384)
       at android.app.ActivityThread.-wrap2(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1545)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6119)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
       at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:583)
       at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:557)
       at android.support.v4.content.FileProvider.attachInfo(FileProvider.java:375)
       at android.app.ActivityThread.installProvider(ActivityThread.java:5853)
       at android.app.ActivityThread.installContentProviders(ActivityThread.java:5445) 
       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5384) 
       at android.app.ActivityThread.-wrap2(ActivityThread.java) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1545) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:154) 
       at android.app.ActivityThread.main(ActivityThread.java:6119) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

Usando o depurador, posso ver que o métodoFileProvider.parsePathStrategy invocaPackageManager.resolveContentProvider com a cadeia de autoridade"${applicationId}.fileprovider;${applicationId}.bugshaker.fileprovider". resolveContentProvider então retorna nulo, levando a esse NPE.

Se eu ligar manualmenteresolveContentProvider enquanto pausado nesta instrução e passar"${applicationId}.fileprovider" ou "${applicationId}.bugshaker.fileprovider", resolveContentProvider em vez disso, retorna um valor não nuloProviderInfo exemplo (que parece ser o resultado esperado).

Essa diferença me confunde porque o<provider> documentação do elemento afirma que várias autoridades são suportadas:

Uma lista de uma ou mais autoridades de URI que identificam os dados oferecidos pelo provedor de conteúdo. Várias autoridades são listadas, separando seus nomes com um ponto e vírgula. Para evitar conflitos, os nomes de autoridade devem usar uma convenção de nomenclatura no estilo Java (como com.example.provider.cartoonprovider). Normalmente, é o nome da subclasse ContentProvider que implementa o provedor

Não há padrão. Pelo menos uma autoridade deve ser especificada.

QuestõesÉ possível que um único aplicativo exponha umFileProvider com várias autoridades e caminhos de arquivo?Se sim, o que preciso alterar para que isso funcione?Caso contrário, existem outras maneiras de configurar o compartilhamento de arquivos na minha biblioteca que evitam conflitos como este?Links de suporteProblema original do GitHubAplicativo de amostra demonstrando a falha no lançamento

questionAnswers(2)

yourAnswerToTheQuestion