Exceptions from PDF readers while previewing generated PDF file on Android/PDFBox
<p>I am currently working on an Android app which generated a PDF file from user input. The app basically takes an empty PDF form and fills it with user input using <em>PDFBox</em> and <em>PDFbox-android</em>.</p>

<p>The user is provided the option to preview the generated PDF file using a PDF reader installed on the device. For testing purposes, the Android Emulator with API23 is used, and both <em>Adobe Reader DC</em> and <em>DocsToGo</em> (with PDF) has been installed on the emulator. Both apps works normally on their own, however they fail to open the generated PDF file. My question is somewhat similar to <a href="https://stackoverflow.com/questions/7887843/problems-opening-pdf-in-android-invalid-file-path">Problems opening pdf in Android: Invalid file path</a>, but I would rather properly use <code>FileProvider</code> to restrict access to the file as needed rather than make it public using the SDCard (or assuming there is one).</p>

<p>Once the PDF file has been generated into the internal storage of the app, i.e. using <code>getFilesDir()</code>, the app generates an <code>Intent</code> object with PDF readers. See the code below:</p>

<pre><code>@Nullable
@CheckResult
public Intent createPdfIntent(@NonNull File _file,
                              @NonNull Activity _activity) {
...
pdfUri = FileProvider.getUriForFile(_activity, "com.tbdsoft.pass", _file);
pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(pdfUri, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

pkgManager = _activity.getPackageManager();
intentInfo = pkgManager.queryIntentActivities(pdfIntent, 0);

for (ResolveInfo resolveInfo : intentInfo) {
        packageName = resolveInfo.activityInfo.packageName;
    _activity.grantUriPermission(packageName, pdfUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

    if (intentInfo.size() &gt; 0) {
        return Intent.createChooser(pdfIntent, _activity.getString(R.string.select_app));
    } else {
        return null;
    }
}
</code></pre>

<p>As the code above shows, I'm using the <code>FileProvider</code> mechanism to give read access to the intent. As such, I have the following lines defined in the <code>AndroidManifest.xml</code> file, as indicated by the <code>FileProvider</code> <a href="https://developer.android.com/reference/android/support/v4/content/FileProvider.html" rel="nofollow">documentation</a></p>

<pre><code>&lt;application&gt;
    &lt;provider
        android:authorities="com.tbdsoft.pass"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true"&gt;
        &lt;meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" /&gt;
    &lt;/provider&gt;

&lt;/application&gt;
</code></pre>

<p>And the <code>file_paths</code> specifies the <code>paths</code> attribute:</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;paths&gt;
    &lt;files-path name="forms" path="forms/" /&gt;
&lt;/paths&gt;
</code></pre>

<p>When executing the app, I can confirm that the file is properly generated by verifying debug information within <em>logcat</em> and using the <em>Android Device Manager</em>. Downloading the generated PDF file from the emulator show no issue and actually opens properly in <em>Adobe Reader</em> and <em>FoxIt</em> on the host PC. The following log data shows the file and uri used for creating the <code>Intent</code>:</p>

<pre>
07-11 20:51:55.439 32653-32653/? D/com.tbdsoft.pass: Packing '/data/user/0/com.tbdsoft.pass.debug/files/forms/form_-1416209969.pdf' for PDF intent.
07-11 20:51:55.439 32653-32653/? D/com.tbdsoft.pass: Uri: content://com.tbdsoft.pass.debug/forms/form_-1416209969.pdf
</pre>

<p>However, both <em>Adobe Reader</em> and <em>DocsToGo</em> fails to open the generated PDF file. <em>Adobe</em> generates the following error:</p>

<pre>
   Process: com.adobe.reader, PID: 862
   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adobe.reader/com.adobe.reader.viewer.ARViewerActivity}: java.lang.IllegalArgumentException: Invalid path: /sdcard
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    Caused by: java.lang.IllegalArgumentException: Invalid path: /sdcard
       at android.os.StatFs.doStat(StatFs.java:46)
       at android.os.StatFs.(StatFs.java:39)
       at com.adobe.libs.buildingblocks.utils.a.h(Unknown Source)
       at com.adobe.libs.services.b.a.a(Unknown Source)
       at com.adobe.reader.viewer.ARViewerActivity.enterDocumentViewing(Unknown Source)
       at com.adobe.reader.viewer.ARViewerActivity.actOnIntent(Unknown Source)
       at com.adobe.reader.viewer.ARViewerActivity.onCreateRAW(Unknown Source)
       at com.adobe.libs.d.a.f.onCreate(Unknown Source)
       at android.app.Activity.performCreate(Activity.java:6237)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:148) 
       at android.app.ActivityThread.main(ActivityThread.java:5417) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Caused by: android.system.ErrnoException: statvfs failed: ENOENT (No such file or directory)
       at libcore.io.Posix.statvfs(Native Method)
       at libcore.io.BlockGuardOs.statvfs(BlockGuardOs.java:298)
       at android.system.Os.statvfs(Os.java:500)
       at android.os.StatFs.doStat(StatFs.java:44)
       at android.os.StatFs.(StatFs.java:39) 
       at com.adobe.libs.buildingblocks.utils.a.h(Unknown Source) 
       at com.adobe.libs.services.b.a.a(Unknown Source) 
       at com.adobe.reader.viewer.ARViewerActivity.enterDocumentViewing(Unknown Source) 
       at com.adobe.reader.viewer.ARViewerActivity.actOnIntent(Unknown Source) 
       at com.adobe.reader.viewer.ARViewerActivity.onCreateRAW(Unknown Source) 
       at com.adobe.libs.d.a.f.onCreate(Unknown Source) 
       at android.app.Activity.performCreate(Activity.java:6237) 
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:148) 
       at android.app.ActivityThread.main(ActivityThread.java:5417) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
</pre>

<p>While <em>DocsToGo</em> spits out the following error (via <em>logcat</em>):</p>

<pre>
07-11 21:34:18.227 31919-31919/? W/ContextImpl: Failed to ensure /sdcard/Android/data/com.dataviz.docstogo/files/Documents: java.lang.SecurityException: Invalid mkdirs path: /storage/self/primary/Android/data/com.dataviz.docstogo/files/Documents
...
07-11 21:34:16.560 1588-1611/? I/ActivityManager: Displayed android/com.android.internal.app.ChooserActivity: +340ms (total +42m18s386ms)
07-11 21:34:17.412 1588-2305/? I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.tbdsoft.pass.debug/forms/form_1209803383.pdf typ=application/pdf flg=0x3000001 cmp=com.dataviz.docstogo/com.dataviz.dxtg.ptg.android.PDFToGoActivity} from uid 10067 on display 0
07-11 21:34:17.436 1588-9331/? I/ActivityManager: Start proc 31919:com.dataviz.docstogo/u0a63 for activity com.dataviz.docstogo/com.dataviz.dxtg.ptg.android.PDFToGoActivity
...
W/System.err: java.io.FileNotFoundException: nullform_1209803383.pdf: open failed: EROFS (Read-only file system)
07-11 21:34:18.460 31919-31919/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:452)
07-11 21:34:18.460 31919-31919/? W/System.err:     at java.io.FileOutputStream.(FileOutputStream.java:87)
07-11 21:34:18.460 31919-31919/? W/System.err:     at java.io.FileOutputStream.(FileOutputStream.java:127)
07-11 21:34:18.460 31919-31919/? W/System.err:     at java.io.FileOutputStream.(FileOutputStream.java:116)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.g.b.d.(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.b(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.a(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.a(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.ptg.android.PDFToGoActivity.a(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.t(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.s(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.onCreate(Unknown Source)
07-11 21:34:18.461 31919-31919/? W/System.err:     at com.dataviz.dxtg.ptg.android.PDFToGoActivity.onCreate(Unknown Source)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.Activity.performCreate(Activity.java:6237)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.ActivityThread.-wrap11(ActivityThread.java)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
07-11 21:34:18.462 31919-31919/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
07-11 21:34:18.463 31919-31919/? W/System.err:     at android.os.Looper.loop(Looper.java:148)
07-11 21:34:18.463 31919-31919/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
07-11 21:34:18.463 31919-31919/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-11 21:34:18.463 31919-31919/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
07-11 21:34:18.463 31919-31919/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-11 21:34:18.471 31919-31919/? W/System.err: Caused by: android.system.ErrnoException: open failed: EROFS (Read-only file system)
07-11 21:34:18.487 31919-31919/? W/System.err:     at libcore.io.Posix.open(Native Method)
07-11 21:34:18.487 31919-31919/? W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
07-11 21:34:18.487 31919-31919/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:438)
07-11 21:34:18.487 31919-31919/? W/System.err:  ... 24 more
07-11 21:34:18.500 1588-1810/? W/MountService: No primary storage defined yet; hacking together a stub
07-11 21:34:18.503 1588-2322/? W/MountService: No primary storage defined yet; hacking together a stub
07-11 21:34:18.520 31919-31919/? W/System.err: java.io.FileNotFoundException: nullattachment.pdf: open failed: EROFS (Read-only file system)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.a(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.a(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.ptg.android.PDFToGoActivity.a(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.t(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.s(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.common.android.ToGoActivity.onCreate(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.dataviz.dxtg.ptg.android.PDFToGoActivity.onCreate(Unknown Source)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.Activity.performCreate(Activity.java:6237)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.ActivityThread.-wrap11(ActivityThread.java)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.os.Looper.loop(Looper.java:148)
07-11 21:34:18.521 31919-31919/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
07-11 21:34:18.521 31919-31919/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
07-11 21:34:18.521 31919-31919/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
</pre>

<p>The process used to work previously in the development stage (with other minor issues), but when implementing usage of <code>FileProvider</code> and creating a 'debug' build type, something appeared to have broken. Trying to restore things to a previous stable state didn't work out, but I might have missed some things. Adding write access (via <code>Intent.FLAG_GRANT_WRITE_URI_PERMISSION</code>) didn't help. Since the file is created, I do not seem to have other permission issue related to file system permission. The filenames of the forms are generated using <code>File.createTempFile</code>. Scanning the errors, its unclear to me if the apps have an issue with the <code>/sdcard</code> folder, or if somehow the uri provided is invalid.</p>

<p>Clearly I am doing something wrong either when creating my <code>Intent</code> or setting up my permissions. I'd like to have some pointers on things to check/try to fix this issue so I can resume testing. Any help appreciated.</p>

<p>Thanks</p>