java - 无法在存储android 10中打开PDF文件
问题描述
我在下载存储中有一个 pdf 文件,我尝试使用意图显示它,我已经有三个 PDF 查看器应用程序,但它们都没有成功显示该文件,但如果我直接通过文件资源管理器打开 pdf,它的显示就好了。
这是我的代码:
File kuda = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file1 = new File(kuda,"KK.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri= FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID+".provider",file1);
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
我的清单:
<provider
android:name="androidx.core.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>
提供者路径:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="Download/"/>
<files-path name="files" path="files/" />
</paths>
我正在使用安卓 10
请帮忙。谢谢
解决方案
是的,在 OS 10 之后情况发生了变化,你必须以新的方式编写逻辑。在我的应用程序中使用改造和使用那些字节 [] 得到一些响应的示例。将此代码放入您的 android 组件(例如活动)中。调用 viewModel.getPdfBytes() 是来自后端的响应!
private static final int CREATE_FILE = 23;
private void saveFileToStorageIntent() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf"));
intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.text_export_pdf_file_first) + getDateString() + getString(R.string.text_export_pdf_file));
startActivityForResult(intent, CREATE_FILE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CREATE_FILE) {
if (resultCode == Activity.RESULT_OK && data != null) {
writePDFToFile(data.getData(), viewModel.getPdfBytes());
}
}
}
private void writePDFToFile(Uri uri, ResponseBody body){
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = getContentResolver().openOutputStream(uri);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Logger.print(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
openFileWithIntent(uri,"pdf", getString(R.string.open_file));
} catch (Exception e) {
Logger.print(TAG, e.getMessage());
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void openFileWithIntent(Uri fileUri, String typeString, String openTitle) {
Intent target = new Intent(Intent.ACTION_VIEW);
target.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
target.setDataAndType(
fileUri,
MimeTypeMap.getSingleton().getMimeTypeFromExtension(typeString)
); // For now there is only type 1 (PDF).
Intent intent = Intent.createChooser(target, openTitle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
if (BuildConfig.DEBUG) e.printStackTrace();
Toast.makeText(context, getString(R.string.error_no_pdf_app), Toast.LENGTH_SHORT).show();
FirebaseCrashlytics.getInstance().log(getString(R.string.error_no_pdf_app));
FirebaseCrashlytics.getInstance().recordException(e);
}
}
推荐阅读
- android - 热敏打印机Android中的徽标图像中心对齐问题
- android - 合并的 AndroidManifest 仅包含库内容
- c++ - 如何为具有初始化列表构造函数以外的类成员设置默认值
- css - 仅 Iphone 无法渲染移动菜单 - 高度不同?
- azure-data-factory - 如何在 Azure 数据工厂中检查日期格式
- python - 如何从 Tensorflow 中的单个张量创建张量列表,反之亦然
- json - 将 json 键值(又是 dict)处理到列表中,xlsxwriter 不接受 dict
- spring-boot - java.library.path 中没有 mssql-jdbc_auth-8.4.1.x64
- server - 从开发人员的角度来看,后端究竟是如何工作的?
- node.js - 自定义 Keystonejs 服务器端函数:“没有名为‘public’的可执行架构”错误