web-dev-qa-db-fra.com

FileProvider ne fonctionne pas avec Impossible de trouver la racine configurée qui contient

J'essaie d'implémenter le téléchargement et le partage PDF fichier à lire par un autre PDF applications de lecture (DropBox, Drive PDF Reader) ou Adobe Reader) sur Android en utilisant la méthode FileProvider.

Cependant, je reçois toujours l'exception suivante:

Failed to find configured root that contains /storage/emulated/0/Android/data/com.my.app/files/docs/my_file_name.pdf

J'envoie d'abord l'URL à Android DownloadManager pour effectuer le téléchargement, puis je reçois le résultat en utilisant BroadcastReceiver

Ma mise en œuvre comme suit:

file_paths.xml

<paths>

    <external-files-path
        name="my_docs"
        path="docs" />

</paths>

AndroidManifest.xml

<provider
    Android:name="Android.support.v4.content.FileProvider"
    Android:authorities="${applicationId}.fileprovider"
    Android:exported="false"
    Android:grantUriPermissions="true">

    <meta-data
        Android:name="Android.support.FILE_PROVIDER_PATHS"
        Android:resource="@xml/file_paths" />

</provider>

Et de MainActivity:

public void downloadFile(String urlString) {
    Uri uri = Uri.parse(urlString);

    String filename = "my_file_name.pdf";

    DownloadManager.Request request = new DownloadManager.Request(uri);
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);

    request.setTitle("App is Downloading a File");
    request.setDescription("Downloading PDF File For App");

    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalFilesDir(mContext, "docs", filename);

    request.allowScanningByMediaScanner();

    mDownloadManager.enqueue(request);
}

Et enfin de mon BroadcastReceiver personnalisé:

uriString est extrait d'une cursor.getString(uriIndex) en utilisant downloadManager.query(myQuery) de la manière habituelle.

private void startDocumentReaderUsingFileProvider(Context context, String uriString) {
    Uri parsedUri = Uri.parse(uriString);

    File file = new File(parsedUri.getPath());
    String packageName = context.getApplicationContext().getPackageName();

    // Exception thrown from the following line.
    Uri uri = FileProvider.getUriForFile(context, packageName + ".fileprovider", file);

    startActivity(context, uri);
}

private void startActivity(Context context, Uri uri) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "application/pdf");
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    Intent chooser = Intent.createChooser(intent, "Display PDF Reader");

    context.startActivity(chooser);
}

Trace de pile d'exceptions:

FATAL EXCEPTION: main
    Process: com.my.app, PID: 8972
    Java.lang.RuntimeException: Error receiving broadcast Intent { act=Android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.my.app bqHint=4 (has extras) } in com.my.app.FileBroadcastReceiver@82a2a7
        at Android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.Java:1003)
        at Android.os.Handler.handleCallback(Handler.Java:739)
        at Android.os.Handler.dispatchMessage(Handler.Java:95)
        at Android.os.Looper.loop(Looper.Java:158)
        at Android.app.ActivityThread.main(ActivityThread.Java:7229)
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1230)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1120)
     Caused by: Java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.my.app/files/docs/my_file_name.pdf
        at Android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.Java:678)
        at Android.support.v4.content.FileProvider.getUriForFile(FileProvider.Java:377)
        at com.my.app.FileBroadcastReceiver.startDocumentReaderUsingFileProvider(FileBroadcastReceiver.Java:85)
        at com.my.app.FileBroadcastReceiver.startDocumentReader(FileBroadcastReceiver.Java:69)
        at com.my.app.FileBroadcastReceiver.onReceive(FileBroadcastReceiver.Java:43)
        at Android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.Java:993)
        at Android.os.Handler.handleCallback(Handler.Java:739) 
        at Android.os.Handler.dispatchMessage(Handler.Java:95) 
        at Android.os.Looper.loop(Looper.Java:158) 
        at Android.app.ActivityThread.main(ActivityThread.Java:7229) 
        at Java.lang.reflect.Method.invoke(Native Method) 
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1230) 
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1120) 
06-07 12:56:50.981 8972-9463/com.my.app E/com.worklight.common.Logger$UncaughtExceptionHandler: Logger$UncaughtExceptionHandler.uncaughtException in Logger.Java:442 :: Uncaught Exception
    Java.lang.RuntimeException: Error receiving broadcast Intent { act=Android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.my.app bqHint=4 (has extras) } in com.my.app.FileBroadcastReceiver@82a2a7
        at Android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.Java:1003)
        at Android.os.Handler.handleCallback(Handler.Java:739)
        at Android.os.Handler.dispatchMessage(Handler.Java:95)
        at Android.os.Looper.loop(Looper.Java:158)
        at Android.app.ActivityThread.main(ActivityThread.Java:7229)
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1230)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1120)
     Caused by: Java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.my.app/files/docs/my_file_name.pdf
        at Android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.Java:678)
        at Android.support.v4.content.FileProvider.getUriForFile(FileProvider.Java:377)
        at com.my.app.FileBroadcastReceiver.startDocumentReaderUsingFileProvider(FileBroadcastReceiver.Java:85)
        at com.my.app.FileBroadcastReceiver.startDocumentReader(FileBroadcastReceiver.Java:69)
        at com.my.app.FileBroadcastReceiver.onReceive(FileBroadcastReceiver.Java:43)
        at Android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.Java:993)
        at Android.os.Handler.handleCallback(Handler.Java:739) 
        at Android.os.Handler.dispatchMessage(Handler.Java:95) 
        at Android.os.Looper.loop(Looper.Java:158) 
        at Android.app.ActivityThread.main(ActivityThread.Java:7229) 
        at Java.lang.reflect.Method.invoke(Native Method) 
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1230) 
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1120) 
12
malhobayyeb
<paths>

    <external-files-path
        name="my_docs"
        path="docs" />

</paths>

Lorsque vous spécifiez le chemin comme docs, les sous-répertoires ne sont pas inclus. Vous obtenez l'exception car il ne s'attend pas à partager les sous-répertoires. Pour les inclure, ajoutez / à la fin comme suit:

<paths>

    <external-files-path name="my_docs" path="docs/" />

</paths>
2
Sagar