我正在Android中使用DownloadManager服务通过https URL(例如https://www.antennahouse.com/XSLsample/pdf/sample-link_1.pdf)下载文件。这些文件没有(当前)受密码保护,以防万一。
排队下载请求后,DownloadManager开始下载,但似乎挂起。当我检查状态时,我得到
COLUMN_BYTES_DOWNLOADED_SO_FAR: 0
COLUMN_STATUS: 4
COLUMN_REASON: 1
COLUMN_STATUS 4是STATUS_PAUSED,“当下载正在等待重试或继续下载时”。
COLUMN_REASON 1为PAUSED_WAITING_TO_RETRY,“由于某些网络错误导致下载暂停,并且下载管理器正在等待重试请求时,暂停下载。”但是似乎没有办法确定发生了什么网络错误。下载永远不会成功完成。
我检查了logcat监视器是否有相关的警告和错误,但未发现任何问题。
我已经在内部和公共(public)的多个不同服务器上尝试过此方法,并且结果相同。
没有明显的网络问题:Wi-Fi连接已建立,并且使用http://可以下载正常工作:该文件会立即下载并出现在指定目标的文件系统中。
对于https下载,我们的服务器日志显示,从服务器的角度来看,文件已成功提供给。在便携式计算机上的浏览器中测试相同的https URL,可以成功下载文件,而在开发人员工具网络面板中不会出现任何明显的问题或进行额外的协商。
我的代码(摘要):
sManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request req = new DownloadManager.Request(sourceURI);
final Uri destinationUri = Uri.fromFile(destinationFile);
req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setDestinationUri(destinationUri)
.setMimeType(...);
long id = sManager.enqueue(req);
摘要:通过DownloadManager启动的https下载会无限期挂起,而相同的https下载在浏览器中可以正常运行,而普通的http下载对于使用DownloadManager的同一应用程序也可以正常运行。我最好的线索是
PAUSED_WAITING_TO_RETRY
指示“发生了某些网络错误”。如何确定网络错误是什么? 最佳答案
最直接的原因似乎是CertificateException:CertPathValidatorException:Trust anchor for certification path not found.
我是通过using an HttpURLConnection directly(感谢@CommonsWare的建议)而不是DownloadManager来发现的,后者提供了直接访问异常的权限。 (对于我们的内部服务器而言,这是正确的。我提到的示例URL似乎并非如此,DownloadManager似乎有相同的问题……但也许相同的问题有所不同。原因。)
根CA(在所有情况下)是“AddTrust外部CA根”,它位于设备上“设置”>“安全性”>“受信任的凭据”下的受信任CA列表中。因此,如果这是受信任的CA根,为什么会有“找不到证书路径的信任 anchor ”异常?
看起来在服务器提供的链中没有包含中间CA,称为described here。实际上,使用openssl s_client -connect
检查CA链可确认不包括中间CA。 Android doc article建议了两种可能的解决方案:在服务器链中包括中间CA,或者通过创建特殊的TrustManager在应用程序中显式信任它们。我希望做前者。