使用Android Intent打开PDF文件

4

以下是情景描述:

我正在从网络上下载一个PDF文件,并将其保存在/0/Download/NSIT - Notices/"fileName".pdf中。

现在像这样发送Intent:

private void openPDF(String fileName) {
    Log.d(TAG, "openPDF: called");
    Intent intent = new Intent(Intent.ACTION_VIEW);File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download", "NSIT - Notices");
    File myPDF = new File(Environment.getExternalStorageDirectory() + "/Download/NSIT - Notices", fileName + ".pdf");
    Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", myPDF);
    Log.d(TAG, "openPDF: intent with uri: " + uri);
    intent.setDataAndType(uri, "application/pdf");
    context.startActivity(Intent.createChooser(intent, "Open with..."));
}

现在任何PDF阅读器(如Google Drive PDF Reader、系统PDF Viewer)都会提示:
The File Does Not Exist

图片: 在此输入图片描述

谷歌的那个没有做任何事情(所以没有包含它的图像)。

Mainfest.xml

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

Provider_path.xml

    <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

我在AsyncTask中创建了一个文件,但是从该AsyncTask的postExecute中打开它。
File myDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download", "NSIT - Notices");
            File myPDF = new File(myDir, params[1] + ".pdf");
            if (!myDir.exists())
                myDir.mkdirs();
            try {
                fileOutputStream = new FileOutputStream(myPDF);
                fileOutputStream.write(response.bodyAsBytes());
                fileOutputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "doInBackground: Download complete");

日志记录

enter image description here

之前它会抛出FileUriExposedException,然后我用这个FileProvider修复了。问题是我的应用程序下载的pdf文件已经成功创建,并且我能够从任何文件管理器(现在是ES文件浏览器)成功打开它,但无法从我的应用程序打开 :(。我对FileProvider很陌生。需要帮忙!

PS: 这也不是我的设备问题。已在两个其他具有不同ROM和API >= 23的手机上进行测试。


我认为它与FileProvider有关。 - Ishaan Kumar
在启动活动之前设置以下内容:intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - Sunny
我在实现FileProvider以解决FileUriExposedException之前尝试过这个方法,但没有帮助。但是现在我已经实现了File Provider并添加了这个意图标志。现在可以工作了。谢谢伙计。 - Ishaan Kumar
@Sunny 发布答案,我会接受它。谢谢! :) - Ishaan Kumar
欢迎,很高兴看到它能正常工作 :) - Sunny
请不要忘记捕获ActivityNotFoundException,如果没有找到打开PDF的应用程序,则会抛出该异常。 - Kathir
2个回答

7
请设置 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);,这将授予其他提供者访问您的文件的权限。

-1

请参阅文件提供程序的文档。

内容提供程序是否可供其他应用程序使用:

true:提供程序可供其他应用程序使用。任何应用程序都可以使用提供程序的内容URI来访问它,但必须遵守为提供程序指定的权限。

false:提供程序不可供其他应用程序使用。只有与提供程序具有相同用户ID(UID)的应用程序才能访问它。

尝试更改android:exported="true"


java.lang.RuntimeException: 无法获取提供程序android.support.v4.content.FileProvider:java.lang.SecurityException:提供程序不得导出 - Ishaan Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接