开发者

Android browser/webview bug? Content-Disposition: attachment; filename="xyz.txt"

So an android browser or a webview works fine with urls like this - abc.com/xyz.txt

However, if your URL looks like this - abc.com/xyz.php and what's sent to the browser in the headers is -开发者_运维问答 Content-Disposition: attachment; filename="xyz.txt", then the Android browsers and web view seems to get terribly confused.

It looks like it saves the correct file name on the phone, but the contents is filled with the webpage that was previously being viewed. This works perfectly well on PC based browsers and on an iPhone and Blackberry, it's only a problem on the Android 2.1 and 2.2 (haven't tested others).

Anyone have a solution? Will be very grateful. I really don't want to start storing static files and want to generate my download content on the fly. The log on the phone has revealed no clues.


Here's what's sent by the server to the browser

===================== start content ====================================
HTTP/1.1 200 OK
Date: Thu, 21 Oct 2010 21:22:11 GMT
Server: Apache
Content-Disposition: attachment; filename="Wafty.txt"
Content-length: 30
Content-Type: text/plain; charset=ISO-8859-1

Hello this is a test of a file
========= There was no carriage return at the end of the above line ====


Use:

Content-Disposition: attachment;filename="xyz.txt"

Do not use (mind extra space):

Content-Disposition: attachment;  filename="xyz.txt"


I have a similar problem to yours. The issue here is how WebView handles attachments (a real pain in the ass). When the WebView visits a web page that at some point returns an attachment, it says kinda like "Oh crap, what can I do with this non-HTML thingy?... Ey you! DownloadListener! do something with this URL that is saying some nonsense about an attachment". So, the DownloadListener takes over and here is the problem: it requests again the same URL to download the attachment, so, for downloading an attachment when visiting a page, the WebView perfoms 2 requests: the page itself and then another one to download the attachment, instead of just downloading it.

And how is this a problem? Well, let's say that in your abc.com/xyz.php you have some logic like:

<?php
   if(User::loggedIn()) {
       header("Content-Disposition: attachment...");
       //Some more logic for the download
   }
?>

The second request performed by the DownloadListener will make another request to abc.com/xyz.php but this time it won't contain cookies or session information so it won't enter the "download" logic.

A possible solution would be to redirect to a temporal copy or the real path to the file that doesn't contains any logic so there is no problem. Of course, you also need to define your Download listener withing your WebView, something like this for example.

webView.setDownloadListener(new DownloadListener() {

    @Override
    public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {

        final DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        Request request = new DownloadManager.Request(Uri.parse(url));
        request.setMimeType(mimeType);

        //Persist download notification in the status bar after the download completes (Android 3.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        }

        dm.enqueue(request);
    }

});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜