2015-07-11 8 views
11

Gibt es eine Möglichkeit, eine Datei aus einem S3-Bucket mit Android DownloadManager herunterzuladen?Laden Sie eine apk-Datei von S3 mit dem DownloadManager herunter

Ich kann derzeit eine apk-Datei von Dropbox herunterladen dies zu tun:

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); 

Nun, was ich will ist „url“ tun, ersetzen mit meiner Amazon URL. Wenn ich das mache, bleibt der Download einfach bei 0% und bleibt dort hängen.

Gibt es eine Möglichkeit, dies zu tun?

Übrigens enthält die Amazon URL, die ich übergebe, die AWSAccessKeyId, Expires und Signature Parameter. Die URL sieht so aus:

https://bucket-name.s3-us-west-2.amazonaws.com/uploads/app/apk/22/app.apk?AWSAccessKeyId=""&Expires=""&Signature="" 
+0

Haben Sie anstelle von HTTPS einfach HTTP versucht? Haben Sie versucht, auf dem Gerät oder Emulator, auf dem Sie testen, auf die URL in einer Webbrowser-App zuzugreifen? Haben Sie eine URL versucht, die für eine öffentliche Ressource gilt (d. H. Eine, die keinen dieser Abfrageparameter benötigt)? Das sind nur einige Ideen, die das Problem vielleicht ein wenig einschränken. – CommonsWare

+0

@CommonsWare Ich habe gerade einige der vorgeschlagenen Dinge ausprobiert. Der Download funktioniert, wenn ich die Option "öffentlich machen" in der Datei in meinem S3-Bucket anklicke. Das beseitigt die Notwendigkeit für die Parameter. Also nehme ich an, dass das Problem irgendwie mit meinen AWS-Anmeldeinformationen zusammenhängt? Die Datei wird in meinem Browser auf meinem Computer mit den Anmeldeinformationen im Link heruntergeladen. – theDazzler

+0

"Also nehme ich an, dass das Problem irgendwie mit meinen AWS-Anmeldeinformationen zusammenhängt?" - Ich habe noch nie eine URL mit Abfrageparametern mit 'DownloadManager' probiert. Ich würde * denken * dass 'DownloadManager' es unterstützen würde. Werfen Sie einen Blick auf die geparste 'Uri' und Sachen wie' getQuery() 'oder' getQueryParameters() 'und stellen Sie sicher, dass Ihre Werte nicht irgendwo auf dem Weg verschlüsselt werden. – CommonsWare

Antwort

4

Der Grund, es nicht ist, weil Sie die Content-Type-Header gesetzt. Dieser Header wird für den HTTP-Download nicht benötigt. Wenn dies jedoch einmal festgelegt ist, muss es einen Teil der Signatur in der vordefinierten URL enthalten, wie von AWS S3 gefordert. Sonst sehen Sie 403 Forbidden - SignatureDoesNotMatch Fehler.

Die schnelle Lösung ist die Content-Type Header entfernen.

request.addRequestHeader("Content-Type", "application/vnd.android.package-archive"); 

Eine andere Lösung besteht darin, eine vordefinierte URL mit benötigten Kopfzeilen zu generieren. Angenommen, Sie möchten den Inhaltstyp wirklich festlegen, Sie können ihn zu GeneratePresignedUrlRequest hinzufügen und dann eine URL daraus erstellen.

GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, key); 
request.setContentType("application/vnd.android.package-archive"); 
URL url = s3Client.generatePresignedUrl(request); 

Weitere Details finden Sie unter AmazonS3.generatePresignedUrl(GeneratePresignedUrlRequest).

+0

Wow. Danke, das hat funktioniert.Du hast gesagt, das ist die "schnelle" Lösung. Gibt es Probleme mit dieser Lösung, auf die ich achten sollte? Gibt es eine bessere "längere" Lösung? Ich habe kein Problem mit Ihrer Lösung, aber ich frage mich nur, ob ich etwas wissen sollte. – theDazzler

+0

Siehe aktualisierte Antwort. – Yangfan

1

Hallo Sie können den folgenden Header verwenden, um die apk-Datei in Anforderung zu erhalten.

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 
Verwandte Themen