2017-01-02 43 views
3

我在Android中使用DownloadManager服务通过https URL下载文件,例如https://www.antennahouse.com/XSLsample/pdf/sample-link_1.pdf。这些文件没有(当前)密码保护,以防有什么区别。为什么https下载暂停PAUSED_WAITING_TO_RETRY?

一旦我排队下载请求,下载管理器开始下载,但它似乎挂起。当我检查状态,我得到

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监视器的相关警告和错误,但什么都没发现。

我已经尝试过使用多个不同的服务器,无论是在公司内部还是在公共场合,都有相同的结果。

没有明显的网络问题:在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); 

摘要:一个HTTPS下载通过下载管理器开始无限期挂起,而相同的HTTPS下载在浏览器中正常工作,并且普通HTTP下载使用做工精细用相同的应用程序下载管理器。我有最好的线索是PAUSED_WAITING_TO_RETRY表示“发生了一些网络错误。”我如何确定网络错误是什么?

+2

您确定URL的SSL证书是由Android所信任的CA颁发的吗? –

+1

在Android上,实际下载的组件[似乎使用'HttpURLConnection'](https://android.googlesource.com/platform/packages/providers/DownloadProvider/+/master/src/com/android/providers /downloads/DownloadThread.java)。您可以使用'HttpURLConnection'(或修改[我的一个]](https://github.com/commonsguy/cw-omnibus/tree/v8.1/Service/Downloader)将一个快速和肮脏的应用程序混合在一起)以及看看你得到了什么。我同意Prera​​k,这感觉就像一个SSL握手问题。 – CommonsWare

+0

@Prera​​kSola:好问题。我会研究它。 – LarsH

回答

0

最近的原因似乎是一个CertificateException:CertPathValidatorException:Trust anchor for certification path not found.我发现了这个出来using an HttpURLConnection directly(感谢@CommonsWare的建议),而不是DownloadManager,它允许更直接的访问异常。 (对于我们的内部服务器,情况是这样的,似乎并不是我提到的示例URL,它似乎与DownloadManager有同样的问题......但也许同样的问题有一个不同的问题原因。)

根CA(在所有情况下)是“AddTrust External CA Root”,它位于设备的可信CA列表中,位于设置>安全性>可信凭证下。因此,如果这是一个可信CA根,为什么会出现“找不到证书路径的信任锚”异常?

看起来有一个中间CA没有被包含在服务器所提供的链中,如described here。实际上,使用openssl s_client -connect来检查CA链确认不包含中间CA.Android doc article提出了两种可能的解决方案:将中间CA包含在服务器链中,或通过创建特殊的TrustManager在应用程序中明确信任它们。我希望做前者。

+0

P.S.确认诊断和修复(包括服务证书链中的中间CA)。在服务器上进行更改后,问题消失了。 – LarsH