使用 DownloadManager 从 S3 下载 apk 文件
Posted
技术标签:
【中文标题】使用 DownloadManager 从 S3 下载 apk 文件【英文标题】:Download apk file from S3 using DownloadManager 【发布时间】:2015-09-30 11:17:58 【问题描述】:有没有办法使用 android 的 DownloadManager 从 S3 存储桶下载文件?
我目前可以这样做从 Dropbox 下载一个 apk 文件:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.addRequestHeader("Content-Type", "application/vnd.android.package-archive");
request.setMimeType("application/vnd.android.package-archive");
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long id = manager.enqueue(request);
现在我要做的是用我的亚马逊 URL 替换“url”。当我这样做时,下载只会停留在 0% 并卡在那里。
有没有办法做到这一点?
顺便说一下,我传入的亚马逊网址包含AWSAccessKeyId
、Expires
和Signature
参数。网址如下所示:
https://bucket-name.s3-us-west-2.amazonaws.com/uploads/app/apk/22/app.apk?AWSAccessKeyId=""&Expires=""&Signature=""
【问题讨论】:
您是否尝试过纯 HTTP 而不是 HTTPS?您是否尝试过在您正在测试的设备或模拟器上的 Web 浏览器应用程序中访问 URL?您是否尝试过用于公共资源的 URL(即,不需要任何这些查询参数的 URL)?这些只是一些可能缩小问题范围的想法。 @CommonsWare 我刚刚尝试了你建议的一些事情。如果我单击 S3 存储桶中文件上的“公开”选项,则下载有效。这消除了对参数的需求。所以我假设问题与我的 AWS 凭证有关?尽管链接中有凭据,但该文件确实会下载到我计算机上的浏览器中。 “所以我假设问题与我的 AWS 凭证有关?” -- 我从未尝试过带有DownloadManager
的查询参数的URL。我会认为DownloadManager
会支持它。查看已解析的 Uri
和 getQuery()
或 getQueryParameters()
之类的内容,并确保您的值在此过程中不会被打乱。
@CommonsWare 好的,我刚刚查看了解析的 Uri 以及 getQueryParamters() 和 getQuery() 中的所有内容,一切似乎都很好。奇怪的是,我从来没有从 DownloadManager 得到错误或任何东西。它只是挂起。我想我会得到类似 401 或 403 错误之类的东西。
如果您可以找到其他一些涉及查询参数(不是 S3)的下载 URL,请试一试。如果失败,那么DownloadManager
可能对查询参数有限制。如果它成功了,那么DownloadManager
和 S3 之间涉及这些查询参数的握手就是罪魁祸首,尽管我真的不知道你会从那里去哪里。
【参考方案1】:
您好,您可以使用以下标头来获取请求中的apk文件。
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:819457
Content-Type:application/octet-stream
【讨论】:
【参考方案2】:失败的原因是您设置了Content-Type
标头。 HTTP 下载不需要此标头。但是,一旦设置,它就必须按照 AWS S3 的要求作为预签名 URL 中签名的一部分。否则你会看到 403 Forbidden - SignatureDoesNotMatch
错误。
快速的解决方案是删除Content-Type
标头。
request.addRequestHeader("Content-Type", "application/vnd.android.package-archive");
另一种解决方案是生成带有您需要的标头的预签名 URL。假设你真的想设置内容类型,你可以将它添加到 GeneratePresignedUrlRequest 然后从中创建一个 URL。
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, key);
request.setContentType("application/vnd.android.package-archive");
URL url = s3Client.generatePresignedUrl(request);
更多详情请见AmazonS3.generatePresignedUrl(GeneratePresignedUrlRequest)。
【讨论】:
哇。谢谢这工作。你说这是“快速”的解决方案。我应该注意与此解决方案相关的任何问题吗?有没有更好的“更长”的解决方案?我对您的解决方案没有意见,只是想知道是否有什么我应该注意的。以上是关于使用 DownloadManager 从 S3 下载 apk 文件的主要内容,如果未能解决你的问题,请参考以下文章
从 DownloadManager 打开下载的文件时如何修复 CursorIndexOutOfBoundsException? [复制]
DownloadManager不好用?试试ZlsamDownloadService