Android: 我无法打开存储中的 PDF 文件

Android: I can't open a PDF file from storage

我正在尝试制作一个 PDF reader,允许用户从 phone 打开 PDF 文件。

我首先创建一个允许我浏览文件的意图

Intent openFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
openFileIntent.setType("*/*");
startActivityForResult(openFileIntent, FILE_OPEN_CODE);

这是 onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == FILE_OPEN_CODE && resultCode == RESULT_OK && data != null){
        Uri selectedFile = data.getData();
        try {
            openFile(selectedFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

获得 Uri 后,我将其发送到打开 PDF 的方法:

public void openFile(Uri fileUri) throws IOException {

    final int WIDTH = viewPDF.getWidth();
    final int HEIGHT = viewPDF.getHeight();
    String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + fileUri.getPath();
    Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444);
    File pdfFile = new File(filePath);
    Toast.makeText(getApplicationContext(), "Opened: " + filePath, Toast.LENGTH_LONG).show();
    PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY));
    currentPage = 0;
    Matrix matrix =  viewPDF.getImageMatrix();
    Rect rect = new Rect(0, 0, WIDTH, HEIGHT);
    renderer.openPage(currentPage).render(bitmap, rect, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    viewPDF.setImageMatrix(matrix);
    viewPDF.setImageBitmap(bitmap);
}

现在,问题是我收到以下错误:

W/System.err: java.io.FileNotFoundException: No such file or directory

我确定该文件存在,但我从 Uri 获得的路径如下

/storage/emulated/0/document/2443

2443 是我得到的文件名而不是 "MY_FILE.pdf" 我需要能够获取文件名才能在渲染器上打开 pdf

此外,我已经在清单中声明了权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

并且还手动提示权​​限 android M 及以上

您正在构建一个不存在且不可能的文件路径。

您应该打开一个 InputStream 来读取文件。

InputStream is  = getContentResolver().openInputStream(data.getData());