< 查看以下重要的EDIT >
当我在我的应用程序中打开PDF时,提供的uri可以是2个方案:“file”和“content”:
使用Dropbox: file:///data/data/com.dropbox.android/global/external/docpreviews/test2.pdf
使用Google云端硬盘: content:// media / external / file / 142
对于“内容”,我的所有功能都按预期工作,但使用“文件”我遇到了一些麻烦:
一个可能的解决方案是将“文件”转换为“内容”,然后我会非常高兴。我一直在寻找它,但不知道如何,所以我想这是不可能的。那么如何解决这三个问题呢?
我的AndroidManifest:
<activity android:name=".activities.PdfActivity"
....
<intent-filter android:label="Open PDF">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/pdf"/>
</intent-filter>
</activity>
在PdfActivity中我收集了Uri:
uri = intent.getParcelableExtra(Intent.EXTRA_STREAM)
1)然后获取文件大小:
switch (uri.getScheme()) {
case "file":
// How to get the filesize here?
break;
case "content":
// Get filesize using cursor
Cursor cursor = getContentResolver().query(uri, new String[]{MediaColumns.SIZE}, null, null, null);
cursor.moveToFirst();
size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaColumns.SIZE));
cursor.close();
break;
}
2)使用以下代码在外部查看器中打开PDF:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Show dialog: no PDF viewer on device
}
3)使用inputstream将PDF转换为byte []:
public byte[] getByteArrayFromPdf(Uri uri) throws IOException {
InputStream inputStream = null;
try {
switch (uri.getScheme()) {
case "file":
// How to do this?
break;
case "content":
inputStream = getContentResolver().openInputStream(uri);
break;
default:
// Something going wrong...
}
return getByteArrayUsingInputStream(inputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
EDIT :我的文件保存在downloads文件夹中(因此来自Google云端硬盘的内容为uri)。
getContentResolver()。openInputStream(uri)导致方案“file”的 FileNotFoundException 。即使两个uri方案都源自同一个文件。这意味着 FileNotFoundException 应该由不存在的文件产生。
显然它是由 libcore.io.ErrnoException引起的:打开失败:EACCES(权限被拒绝),当我从Dropbox查看uri(文件)时更有意义:看来dropbox打开了将文件保存在 com.dropbox.android 中,我无权访问。我想这解释了所有的麻烦,我是对的吗?
最终编辑: 如上所述,由Dropbox PDF查看器应用程序制作的文件隐私可能存在问题,因为使用Adobe(和其他应用程序,这也导致带有“文件”的文件)我没有任何麻烦:< em> new File(uri.getPath())。length()给我文件大小,接收输入流与“content”uri相同。
但这给了我一个新问题:我可以:使用Dropbox应用程序打开外部PDF文件(例如下载地图),“发送PDF”以在我的打开它应用程序,然后以某种方式访问此文件,以便我可以读取大小,在另一个PDF查看器中打开它,并将其转换为输入流?
PS。以这种方式在我的应用程序中打开PDF时可能有其他的uri方案吗?
答案 0 :(得分:0)
我不知道如何获取PDF的文件大小
致电getPath()
上的Uri
。在File
对象中换行该路径,然后在length()
对象上调用File
。
或者,用DocumentFile
替换现有代码。对fromSingleUri()
方案使用content
,fromFile()
方案使用file
。然后,在getSize()
上调用DocumentFile
。
在外部PDF查看器中打开PDF会导致错误,例如&#34;无法打开文件&#34; (无论是Dropbox,Google云端硬盘还是其他任何应用)。
其他应用对该内容没有任何权利。您可以通过将FLAG_GRANT_READ_URI_PERMISSION
添加到Intent
来尝试转移权利。
打开输入流(将PDF转换为byte [])也会造成麻烦:FileNotFoundException。
您不会显示提供此异常的代码。 openInputStream()
支持file
和content
计划,因此请在两种情况下使用它。