Android 7 - 无法显示PDF(pdf_name格式无效)

时间:2016-12-06 13:49:09

标签: java android pdf

我有一个适用于Android 4,5和6的应用程序。该应用程序列出服务器中的远程文件,并允许您从服务器下载它们(PDF文件)。点击某个文件后,会将其下载到" Android下载文件夹"当它完成时,它会使用默认的PDF阅读器打开它。

问题是Android 7中的相同代码无法提供下一个错误:"无法显示PDF(pdf_name格式无效)"。

这很有趣,因为:

  • 如果我访问“下载”文件夹并单击下载的文件,则会正常打开。
  • 完成下载后,会显示通知,点击它会正确打开。

因此,只有当同一个应用程序在下载后尝试自动打开文件时才会出现问题。

我如何进行下载:

fileName="file.pdf";
request = new DownloadManager.Request(Uri.parse(Constants.GetURL()));
request.setMimeType(mime)
    .setTitle(fileName).setVisibleInDownloadsUi(true)
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
    .setDescription(mContext.getString(R.string.app_name))
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
enqueue = dm.enqueue(request);

下载一次:

    Uri path = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
//path contains the route where file was downloaded. Something like: file:///storage/emulated/0/Download/file.pdf
    Intent pdfOpenintent = IntentHelper.getViewPDFIntent(path);                                            
    mContext.startActivity(pdfOpenintent);

我如何打开它:

public static Intent getViewPDFIntent(Uri path){
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    pdfOpenintent.setDataAndType(path, "application/pdf");
    return i;
}

关于FileProvider :  我已经使用FileProvider实现了,问题是一样的。它与权限无关,“下载文件夹”是公用文件夹,没有SecurityException引发或与权限相关的任何其他异常。

它与任何PDF应用程序无关,因为它与Gmail共享用于发送文档的内容。

外部行为:当我逐步调试App时,它可以完美地运行。当我执行正常时,它会失败。如果我把睡眠或延迟5秒,不起作用。所以只能调试。

关于Android 7 :阅读Android 7(https://developer.android.com/about/versions/nougat/android-7.0-changes.html)的官方更改,它说应该可以使用,但不要再这样推荐了。否则,它不起作用。

有任何新想法吗?

2 个答案:

答案 0 :(得分:2)

经过几天的研究和一些人参与后,我们得出的结论是Android改变了Android 7上DownloadManager的行为以添加FileProvider的权限。 (在他们解释的Android 7 Changelog中)

我的感觉是Android自Android 7(和7.1)以来,可能是将文件保存在临时文件夹中,然后发送Broadcast FileDownloaded成功,然后将文件移动到最终目标文件夹。

因为FileDownloaded Broadcast在文件移动之前跳转,所以无法打开它。这就是为什么在调试或放置10秒的睡眠时,它会起作用。

没有找到任何解决此问题的方法,而是停止使用DownloaderManager进行下载并打开并实现我自己的。 (仅用于下载文件,不涉及任何其他操作)。

希望下一个发现此问题的人有所帮助。

答案 1 :(得分:-2)

修改:
修复发现 更多的挖掘表明这似乎是一个许可问题。设置此权限解决了这个问题,它非常奇怪,它完全没有用。

“android.permission.READ_EXTERNAL_STORAGE”

虽然这不是一个真正回答它的更多信息来帮助识别并提供可怕的工作,但我还是无法发表评论。

使用AsyncTask下载PDF后,我遇到了同样的问题。

doInBackground()正确完成,所有读/写流都关闭,使用此代码调用onPostExecute()。

		    Intent target = new Intent(Intent.ACTION_VIEW);
		    target.setDataAndType(Uri.fromFile(file), "application/pdf");
		    target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            Intent intent = Intent.createChooser(target, "View PDF Bill...");

并且无法使用无效的格式错误启动PDF。

第二次加载(加载到现有PDF的顶部),PDF查看器的启动大部分时间都能正常工作,但仍偶尔会失败。

如果我调试它打开正常(我假设由于它需要的时间),如果我添加10秒睡眠它工作正常,如果我添加9秒睡眠它不会。它几乎就像关闭文件或操作系统中的其他终止调用失败一样,它超时但没有抛出异常。

即使我尝试从ES文件资源管理器中打开PDF,也会应用10秒延迟

该代码在低于Android 7.0的所有设备上都能正常运行。