1

Is it possible to download a file to a user defined directory from android webview. Currently the file is being downloaded in SDCard/downloads. Is it possible to override the default download location?

I am currently using the following code to download a file

Intent intent = new Intent(Intent.ACTION_VIEW Uri.parse("download file location"));
startActivity(intent); 
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
Tanmay Mandal
  • 39,873
  • 12
  • 51
  • 48
  • Same question: http://stackoverflow.com/questions/4069593/android-webview-with-custom-download-folder but with no answer. – Harry Joy Feb 01 '11 at 08:49
  • 4
    As a hack/solution: Don't use the Browser for the download. Handle the download yourself, and you can store it wherever you can write to. If you use the Browser for the download, it will download where the Browser wants to, not where you want it to. – Harry Joy Feb 01 '11 at 08:52
  • @harry Thanks buddy for your solution.But unfortunately I need the browser. – Tanmay Mandal Feb 01 '11 at 09:35

1 Answers1

1

When you mean you need the browser... do you mean you need to handle the download with the browser? Cause you can use the webview and still handle the download yourself.

As @Harry Joy commented, I would use the shouldOverrideUrlLoading(WebView view, String url) method and filter those urls/extensions you want to download separately. If you don't have any specific file extensions or urls you may want to download, but you can edit your html/javascript code maybe you can do some javascript trick to add a flag and make your WebView recognize the url as a download.

To handle the download, maybe you already know, but it would be something like this

    if (sUserAgent == null) {
        Log.e(TAG + " - Conexion", getString(R.string.e_envio_datos));
    }
    // Create client and set our specific user-agent string
    HttpClient client = new DefaultHttpClient();
    HttpPost request = new HttpPost(url);
    request.setHeader("User-Agent", sUserAgent);
    try {
        HttpResponse response = client.execute(request);
        // Check if server response is valid
        StatusLine status = response.getStatusLine();
        if (status.getStatusCode() != HTTP_STATUS_OK) {
            // Error
        } else {
            InputStream in = response.getEntity().getContent();
            byte[] read = new byte [1024];
            int numReadBytes= 0, singleByte;
            boolean endFlow= false;
            do {
                singleByte= in.read();
                endFlow = singleByte == -1;
                if (!endFlow) {
                    read[numReadBytes] = (byte) singleByte;
                    numReadBytes++;
                }
            } while (!endFlow);
            if (numReadBytes> 0) {
    // Here you implement some code to store the array of bytes as a file
                storeDataWherever(read);
            }
        }
    } catch (IOException e) {
        Log.e(TAG + " - Conexion", e.getMessage());
    } catch (ArrayIndexOutOfBoundsException e){
        Log.e(TAG + " - Conexion", getString(R.string.e_respuesta_size));       
    }
mdelolmo
  • 6,417
  • 3
  • 40
  • 58
  • I want to download a DRM content, when I am saving file using the HTTPClient , Android is not being able to understand that it is a DRM file, so forward locking is happening.Android is able to understand the DRM content only when downloaded through browser, but there I can not save the file to a desired directory. Any solution ?Thanks – Tanmay Mandal Feb 01 '11 at 14:37
  • I'm not sure if an Intent.ACTION_VIEW with a local url would work, due to a security issue. But to download the data (bytes) to a custom location you don't need Android to understand that type of file. – mdelolmo Feb 01 '11 at 16:30
  • If the user had to log in via the WebView, would this code maintain the authentication when fetching the file or will this only work for non-secure files? – MetaGuru Sep 12 '12 at 19:28
  • @libertas, I never tried something like you say, but I think they are different sessions, and therefore, with THIS sample code, you don't maintain the authentication. Nevertheless, I would try to fetch the user credentials with a previous form, and use it for both, the `WebView` trough the method `setHttpAuthUsernamePassword` and for the http request object. To set the credentials for the http request, there is plenty of documentation out there on how to do that. Good luck – mdelolmo Sep 13 '12 at 07:21
  • @mdelolmo I see how the 'setHttpAuthUsernamePassword' is used for WebView, but what would I use to authenticate the HttpClient/Post/Response? If I send the form post using that, would there be a way to maintain a cookie or something? – MetaGuru Sep 13 '12 at 12:50
  • @libertas, I don't think you need any cookie, you should already have the credentials stored in some object. For a sample code, have a look at [this](http://stackoverflow.com/questions/3094738/https-request-authentication-in-android?rq=1) – mdelolmo Sep 17 '12 at 14:45
  • @mdelolmo Well in my case the user logs in via an HTML Form POST in the WebView which is loaded from the server, then it stores a cookie, making non-WebView based calls thus aren't authenticated. – MetaGuru Sep 17 '12 at 19:21