仅适用于Android 8和9。
我这里有一个PDF文件管理器 -
String url = "file:///storage/emulated/0/Android/data/com.verna.poc/files/Download/mypdf.pdf";
我正在尝试使用此打开此文件进行查看 -
File file= new File(url);
file.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri pdfUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", file);
intent.setDataAndType(pdfUri, "application/pdf");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
List<ResolveInfo> resInfoList = getApplicationContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
getApplicationContext().grantUriPermission(packageName, pdfUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
Intent in = Intent.createChooser(intent, "Open File");
startActivity(in);
File chooser选项正在打开,当我使用Google PDF阅读器打开文件时,PDF阅读器会立即打开和关闭。我的代码有什么问题?
您正尝试与另一个应用程序共享内部存储中的文件。您需要创建一个文件提供程序才能使其正常工作。您需要指定希望文件提供程序为其生成Uris的目录
FileProvider是ContentProvider的一个特殊子类,它通过为文件而不是file:/// Uri创建内容:// Uri来促进与应用程序关联的文件的安全共享。
FileProvider只能为您事先指定的目录中的文件生成内容URI。要指定目录,请使用元素的子元素以XML格式指定其存储区域和路径。例如,以下paths元素告诉FileProvider您打算为私有文件区域的images /子目录请求内容URI。
这个答案就是一个很好的例子
这是FileProvider
的文档页面
我遇到了这个问题。当您使用File file = new File(path)创建新文件时,不会在路径前添加file://
。
这是对的 -
String url = "/storage/emulated/0/Android/data/com.verna.poc/files/Download/mypdf.pdf";
File file= new File(url);
这是错的 -
String url = "file:///storage/emulated/0/Android/data/com.verna.poc/files/Download/mypdf.pdf";
File file= new File(url);
在此我们首先将文件保存到内部存储,然后使用外部应用程序从中读取。
我使用以下方法将文件保存在内部存储中:
private void savePDFtoInternalStorage(byte[] pdfAsBytes){
//Save in internal memo cache
File directory = mFragmentActivity.getFilesDir();
//updating path for pdf to match with file_path.xml
mCardStmtFile = new File(directory.getAbsolutePath(), "sample.pdf");
OutputStream outputStream = null;
try {
PbLogger.e(TAG, "writing to mStmtFile");
outputStream = new FileOutputStream(mCardStmtFile, false);
outputStream.write(pdfAsBytes);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
PFB文件提供程序声明了file_path.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path path="/" name="secretpdf" />
</paths>
PFB文件提供程序的Android Manifest Entry:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.***.********.provider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
使用以下代码启动PDF:
Intent intentShareFile = new Intent(Intent.ACTION_VIEW);
if (mStmtFile.exists()) {
intentShareFile.setType("application/pdf");
Uri fileUri = FileProvider.getUriForFile(
mFragmentActivity,
"com.****.********.provider",
mCardStmtFile);
intentShareFile.putExtra(Intent.EXTRA_STREAM, fileUri);
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
getDescription());
//adding grant read permission to share internal file
intentShareFile.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intentShareFile, "Share File"));
}