繁体   English   中英

在 android 11 中下载 pdf

[英]Download pdf in android 11

我已升级到 android 11。我在下载 PDF 文件时遇到问题。

我用过这个代码:

private void createFile(Uri pickerInitialUri, String title) {
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("application/pdf");
    intent.putExtra(Intent.EXTRA_TITLE, title);

    // Optionally, specify a URI for the directory that should be opened in
    // the system file picker when your app creates the document.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
    }

    startActivityForResult(intent, CREATE_FILE);
}

文件已创建,但文件为空。 我仍然无法保存下载的pdf文件。

我曾经使用 DownloadManager 请求从网络下载 pdf 文件。

DownloadManager downloadManager = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(uri);

        if (SDK_INT > Build.VERSION_CODES.Q) {

         //   Uri uri1 = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), ""));  //before android 11 this was working fine

           // Uri uri1 = Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "")); 

            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
                    .setAllowedOverRoaming(true).setTitle(title + strDate + ".pdf")
                    .setDescription(description)
                    //.setDestinationUri(uri1) // before android 11 it was working fine.
                    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, title + strDate + ".pdf") // file is not saved on this directory.
                    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//to show the DOWNLOAD notification when completed

           // createFile(uri , title + strDate + ".pdf"); // for new scoped storage


        } else {
            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
                    .setAllowedOverRoaming(true).setTitle(title + strDate + ".pdf")
                    .setDescription(description)
                    .setDestinationInExternalPublicDir(FileUtils.downloadPdfDestination(), title + strDate + ".pdf")
                    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //to show the DOWNLOAD notification when completed
        }
       long PDF_DOWNLOAD_ID = downloadManager.enqueue(request);```

ACTION_CREATE_DOCUMENT 用于创建新文档。 如果一个已经存在,它将被覆盖。 如果要查看现有文档,请使用 ACTION_VIEW。

当然,您发布的任何代码实际上都不会下载 PDF。 如果您需要这方面的帮助,请发布您的 DownloadManager 代码。

检查此代码片段:

override fun startDownload(url: String, onError: (e: Exception) -> Unit) {
        try {
            val request = DownloadManager.Request(Uri.parse(url))
            request.setDestinationInExternalPublicDir(
                Environment.DIRECTORY_DOWNLOADS,
                UUID.randomUUID().toString()
            )
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)
            (context.getSystemService(DOWNLOAD_SERVICE) as DownloadManager).enqueue(request)
        } catch (e: Exception) {
            e.printStackTrace()
            onError.invoke(e)
        }
    }

通过使用DownloadManger API,它在Android 11上运行良好。

使用以下代码下载和查看 pdf。

首先,您需要为后台任务应用rxjava依赖项。

 implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

在调用以下方法之前不要忘记检查WRITE_EXTERNAL_STORAGE权限。 还要检查INTERNET权限。

然后使用下面的方法在后台执行操作。

private void downloadAndOpenInvoice() {
    mDialog.show();
    Observable.fromCallable(() -> {
        String pdfName = "Invoice_"+ Calendar.getInstance().getTimeInMillis() + ".pdf";
        
        String pdfUrl = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
        
        File file = CommonUtils.downloadFile(mActivity, pdfUrl, pdfName,mDialog);
        return file;
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(file -> {
                CommonUtils.viewPdf(file, mActivity, mDialog);
            });
}

要从 url 下载文件,请使用以下代码段

public static File downloadFile(Activity mActivity, String url, String fileName, CustomDialog mDialog) {
    // write the document content
    File fileDir = new File(CommonUtils.getAppDir(mActivity, "Invoice")); //Invoice folder inside your app directory 
    if (!fileDir.exists()) {
        boolean mkdirs = fileDir.mkdirs();
    }
    File pdfFile = new File(CommonUtils.getAppDir(mActivity, "Invoice"), fileName); //Invoice folder inside your app directory

    try {
        URL u = new URL(url);
        URLConnection conn = u.openConnection();
        int contentLength = conn.getContentLength();

        DataInputStream stream = new DataInputStream(u.openStream());

        byte[] buffer = new byte[contentLength];
        stream.readFully(buffer);
        stream.close();

        DataOutputStream fos = new DataOutputStream(new FileOutputStream(pdfFile));
        fos.write(buffer);
        fos.flush();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        if (mDialog.isShowing()) {
            mDialog.dismiss();
        }
        Toast.makeText(mActivity, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
    }
    return pdfFile;
}

对于应用程序目录

public static String getAppDir(Context context, String folderName) {
    return context.getExternalFilesDir(null).getAbsolutePath() + File.separator + folderName + File.separator;
}

使用以下代码查看pdf

public static void viewPdf(File pdfFile, Activity mActivity, CustomDialog mDialog) {

    Uri uri = FileProvider.getUriForFile(mActivity, mActivity.getApplicationContext().getPackageName() + ".provider", pdfFile);

    // Setting the intent for pdf reader
    Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
    pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    pdfIntent.setDataAndType(uri, "application/pdf");
    //pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    try {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mDialog.isShowing()) {
                    mDialog.dismiss();
                }
            }
        });
        mActivity.startActivity(pdfIntent);
        Log.e("Invoice - PDF", pdfFile.getPath());
    } catch (ActivityNotFoundException e) {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mDialog.isShowing()) {
                    mDialog.dismiss();
                }
            }
        });
        e.printStackTrace();
        Log.e("Invoice - PDF", "Can't read pdf file");
        Toast.makeText(mActivity, "Can't read pdf file", Toast.LENGTH_SHORT).show();
    }
}

暂无
暂无

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

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