繁体   English   中英

无法打开从 InputStream 生成的 pdf 文件

[英]Cannot open pdf file that was generated from an InputStream

我有一个 API,它为我提供了一个 pdf 文件的InputStream 我的目标是允许用户使用另一个 pdf 查看器应用程序查看此文件。

为了实现这一点,我将 InputStream 复制到以编程方式创建的 pdf 文件中。 然后我试图打开那个 pdf 文件。

但是,我无法通过我的应用程序或文件资源管理器打开 pdf 文件。 Drive PDF reader 在 toast 中提示无法打开 pdf 文件,Adobe Acrobat 提示无法访问 pdf 文件,Mi PDF reader 提示 pdf 格式无效。

这是 OkHttpClient 调用的onResponse()中的代码:

                if (response.isSuccessful()) {
                    InputStream inputStream = responseBody.byteStream();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            File file = null;
                            try {
                                file = MyFileUtils.createPdfFile(PdfViewActivity.this);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            MyFileUtils.copyInputStreamToFile(inputStream, file);
                            String pdfFilePath = file.getAbsolutePath();
                            openPdf(pdfFilePath);
                        }
                    });
                }

这是负责打开 pdf 的方法:

    private void openPdf(String pdfFilePath) {
        Intent pdfViewIntent = new Intent(Intent.ACTION_VIEW);
        pdfViewIntent.setDataAndType(Uri.parse(pdfFilePath), "application/pdf");
        Intent chooser = Intent.createChooser(pdfViewIntent, "Open this note with");
        startActivity(chooser);
        finish();
    }

我使用MyFileUtils.createPdfFile()方法创建了 pdf。 这是我的实现方式:

    public static File createPdfFile(Activity associatedActivity) throws IOException {
        String timeStamp = new SimpleDateFormat("HHmmss").format(new Date());
        String pdfFileName = "PDF_" + timeStamp + "_";

        File storageDir = associatedActivity.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        Log.d(TAG, "createPdfFile: storageDir: " + storageDir.getAbsolutePath());

        return File.createTempFile(
                pdfFileName,  /* prefix */
                ".pdf",         /* suffix */
                storageDir      /* directory */
        );
    }

我在MyFileUtils class 中使用以下方法将 InputStream 复制到该文件:

    // Copy an InputStream to a File.
    public static void copyInputStreamToFile(InputStream in, File file) {
        OutputStream out = null;

        try {
            out = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Ensure that the InputStreams are closed even if there's an exception.
            try {
                if (out != null) {
                    out.close();
                }

                // If you want to close the "in" InputStream yourself then remove this
                // from here but ensure that you close it yourself eventually.
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

我已经通过以下方式实现了提供者:

安卓清单.xml:

    <application>
        ...
        ...
        ...
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.xyz.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

文件路径.xml:

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

笔记:

  • 该应用程序具有必要的读写权限。 我已经以编程方式对其进行了测试。 我没有在此处包含这些代码,因为它可能不相关。
  • 创建的 pdf 文件的绝对路径是这样的: /storage/emulated/0/Android/data/<package name>/files/Documents/PDF_164257_4832620770047519807.pdf

您需要在设备下载目录中下载。 您的目录对其他未打开的应用程序不可见。 只有您的应用程序可以使用此目录。

由于声誉较低而无法发表评论

我不确定这是否有帮助,但我看到您将 InputStream 复制到的file在您调用openPdf(pdfFilePath); 这意味着 pdf 的观众无法打开它,因为它被阻止或并非所有内容都已写入文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM