问题
I'm working on an app that will download a zip file stored on Amazon S3 via a Rails Heroku server after authenticating via oAuth 2. Here's the flow:
- Request to authenticate with the server running on Heroku via oAuth2.
- Receive oAuth2 access token.
- Request to download the zip file from the server (passing the oAuth token as bearer).
- The server authorizes the request and redirects to an Amazon S3 URL containing a expiring signature (to stop anyone downloading the content without being authenticated).
At this point, I want the DownloadManager to just follow the redirect and get the zip file from S3, however it's failing. Is there some way I can work around this? Or is it just a limitation of DownloadManager?
I'm new to Android and still not totally up on the best debugging methods, so I don't have a lot of output to show you. However, it seems that DownloadManager.COLUMN_STATUS == DownloadManager.STATUS_FAILED
and DownloadManager.COLUMN_REASON
is returning "placeholder"!
EDIT - Here is the code I'm using. Edited to hide the client etc...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("ChapterListActivity", "Item clicked: " + id);
final DownloadManager downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://myapphere.herokuapp.com/api/v1/volumes/2.zip");
DownloadManager.Request request = new Request(uri);
String accessToken = getSharedPreferences("keyhere", MODE_PRIVATE).getString("access_token", null);
Log.i("SLEChapterListActivity", "Getting file with access token... " + accessToken);
request.addRequestHeader("Authorization", "Bearer " + accessToken);
long reference = downloadManager.enqueue(request);
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long downloadReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
Log.i("ChapterListActivity", "Download completed");
Query query = new Query();
query.setFilterById(downloadReference);
Cursor cur = downloadManager.query(query);
if (cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
File mFile = new File(Uri.parse(uriString).getPath());
} else if (DownloadManager.STATUS_FAILED == cur.getInt(columnIndex)){
String statusResult = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_REASON));
Toast.makeText(context, "FAILED " + statusResult, Toast.LENGTH_SHORT).show();
} else if (DownloadManager.ERROR_TOO_MANY_REDIRECTS == cur.getInt(columnIndex)){
String statusResult = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_REASON));
Toast.makeText(context, "TOO MANY REDIRS " + statusResult, Toast.LENGTH_SHORT).show();
}
}
}
};
registerReceiver(receiver, filter);
}
回答1:
I've found in Download Manager sources (line 500):
3xx: redirects (not used by the download manager)
It's not supported, yet.
In my current project, downloads are made in two steps:
- Get Amazon url from our own server via oAuth2
- Enqueue DownloadManager with the Amazon url.
If you don't like the two step process, I don't, then take a look at RoboSpice project, it has similar philosophy as DownloadManager.
回答2:
Just answering a sub-part of this question. The reason why you get the reason as a "placeholder" String is because the reason column is an integer, not a String. See Android DownloadManager: Download fails, but COLUMN_REASON only returns “placeholder”.
来源:https://stackoverflow.com/questions/13150587/android-downloadmanager-not-working-when-redirected