我目前正在开发一款Android应用,可根据用户输入生成PDF文件。该应用程序基本上采用一个空的PDF表单,并使用 PDFBox 和 PDFbox-android 填写用户输入。
为用户提供了使用设备上安装的PDF阅读器预览生成的PDF文件的选项。出于测试目的,使用了带有API23的Android模拟器,并且模拟器上已安装 Adobe Reader DC 和 DocsToGo (带PDF)。这两个应用程序都可以自行运行,但无法打开生成的PDF文件。我的问题有点类似于Problems opening pdf in Android: Invalid file path,但我宁愿正确使用FileProvider
来限制对文件的访问,而不是使用SDCard公开(或假设有一个)。
将PDF文件生成到应用程序的内部存储中后,即使用getFilesDir()
,该应用程序会生成一个带有PDF阅读器的Intent
对象。请参阅以下代码:
@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() > 0) {
return Intent.createChooser(pdfIntent, _activity.getString(R.string.select_app));
} else {
return null;
}
}
如上面的代码所示,我正在使用FileProvider
机制来提供对intent的读访问权。因此,我在AndroidManifest.xml
文件中定义了以下行,如FileProvider
documentation
<application>
<provider
android:authorities="com.tbdsoft.pass"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
file_paths
指定paths
属性:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="forms" path="forms/" />
</paths>
执行应用程序时,我可以通过验证 logcat 中的调试信息并使用 Android设备管理器来确认文件是否正确生成。从模拟器下载生成的PDF文件显示没有问题,并且实际上在主机PC上的 Adobe Reader 和 FoxIt 中正确打开。以下日志数据显示用于创建Intent
的文件和uri:
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
但是, Adobe Reader 和 DocsToGo 都无法打开生成的PDF文件。 Adobe 会生成以下错误:
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)
当 DocsToGo 吐出以下错误时(通过 logcat ):
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)
此过程以前在开发阶段工作(有其他小问题),但在实现FileProvider
的使用并创建'debug'构建类型时,似乎已经破坏了某些东西。试图将事情恢复到以前的稳定状态并没有成功,但我可能错过了一些事情。添加写访问权限(通过Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)没有帮助。由于文件已创建,我似乎没有与文件系统权限相关的其他权限问题。表单的文件名是使用File.createTempFile
生成的。扫描错误,我不清楚应用程序是否存在/sdcard
文件夹的问题,或者提供的uri是否无效。
显然,我在创建Intent
或设置权限时做错了。我想对要检查/尝试修复此问题的事项有一些指示,以便我可以继续测试。任何帮助表示赞赏。
由于