3

I want to download images inside my webview. I used a link tag like this

<a href="../Temp/Images/def.jpg" download="">Download</div></a>

Which works fine on a chrome browser but does not work in my webview app. I already activated several permissions.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />

But still the link does not react. How can I trigger a download?

EDIT:

Response Headers:

Cache-Control:private
Connection:Close
Content-Disposition:attachment; filename=IMG_20141004_171308.jpg
Content-Length:3039432
Content-Type:image/jpeg
Date:Wed, 15 Oct 2014 12:35:57 GMT
Server:ASP.NET Development Server/10.0.0.0
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:4.0
Derlin
  • 9,572
  • 2
  • 32
  • 53
zanzoken
  • 787
  • 4
  • 12
  • 18

3 Answers3

8

Try adding download listener -

mWebView.setDownloadListener(new DownloadListener() {

    public void onDownloadStart(String url, String userAgent,
        String contentDisposition, String mimetype,
                                   long contentLength) {

            Request request = new Request(Uri.parse(url));
            request.allowScanningByMediaScanner();

                request.setNotificationVisibility(
                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

                request.setDestinationInExternalPublicDir(
                Environment.DIRECTORY_DOWNLOADS,    //Download folder
                "download");                        //Name of file


                DownloadManager dm = (DownloadManager) getSystemService(
                DOWNLOAD_SERVICE);

                dm.enqueue(request);  

    }
});
Confuse
  • 5,646
  • 7
  • 36
  • 58
6

I had same problem. Here is how I solved it. I extended WebViewClient:

import java.io.File;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.DownloadManager;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.webkit.WebView;
import android.webkit.WebViewClient;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MyWebViewClient extends WebViewClient {

    private Context context;

    public MyWebViewClient(Context context) {
        this.context = context;
    }

    @SuppressLint("NewApi")
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(url.contains(".jpg")){

            DownloadManager mdDownloadManager = (DownloadManager) context  
                    .getSystemService(Context.DOWNLOAD_SERVICE);  
            DownloadManager.Request request = new DownloadManager.Request(  
                    Uri.parse(url));  
            File destinationFile = new File(  
                    Environment.getExternalStorageDirectory(),  
                    getFileName(url));  
            request.setDescription("Downloading ...");  
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);  
            request.setDestinationUri(Uri.fromFile(destinationFile));  
            mdDownloadManager.enqueue(request);  


            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }

    public String getFileName(String url) {  
        String filenameWithoutExtension = "";  
        filenameWithoutExtension = String.valueOf(System.currentTimeMillis()  
                + ".jpg");  
        return filenameWithoutExtension;  
    }  


}

Of course you can modify url filter such as Uppercase etc other extensions...

In Fragment, add the line:

webPreview.setWebViewClient(new MyWebViewClient(getActivity()));

Or in Activity, add the line:

webPreview.setWebViewClient(new MyWebViewClient(this));

Of course modify webPreview to the WebView name you set

Make sure you add to WebView settings:

webSettings.setDomStorageEnabled(true);

if you have set:

webSettings.setBlockNetworkImage (false);
Wildroid
  • 864
  • 7
  • 9
  • I used this code shows this error java.lang.SecurityException: No permission to write to /storage/emulated/0/1499081348105.jpg: Neither user 10109 nor current process has android.permission.WRITE_EXTERNAL_STORAGE. – Ankit Prajapati Jul 03 '17 at 11:30
  • 1
    @AnkitPrajapati I think that is because you didn't allow in the application manifest the permission WRITE_EXTERNAL_STORAGE – I'l Follio Jul 22 '17 at 21:57
  • @I'l Follio thanks for your answer , but I read that API >=23 needs runtime permission , which i did like this https://stackoverflow.com/questions/44882785/android-webview-not-triggering-a-href-download-file/44884557?noredirect=1#comment76821699_44884557 – Ankit Prajapati Jul 25 '17 at 07:05
0

The correct working code in API 30 and more. Make sure to add following permission in manifest.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


  webView.setDownloadListener(new DownloadListener() {


        public void onDownloadStart(String url, String userAgent,
                                    String contentDisposition, String mimetype,
                                    long contentLength) {

            Log.i("KAMLESH","Download Image Request  "+url);

            if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
            {
                requestForPermissions(permissionsRequired);
                return;
            }

            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
            request.allowScanningByMediaScanner();

            request.setNotificationVisibility(
                    DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "download");                        //Name of file

            File file =  new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOWNLOADS), "image_" + System.currentTimeMillis() + ".jpg");
            file.getParentFile().mkdirs();

            request.setDestinationUri(Uri.fromFile(file));

            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

            dm.enqueue(request);



        }
    });


void requestForPermissions(String permissions[])
{
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Need Permission");
    builder.setMessage("This app needs Storage permission.");
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

            dialog.cancel();
            ActivityCompat.requestPermissions(WebViewActivity.this, permissionsRequired, 1);


        }
    });

    builder.show();

}
Coderz Way
  • 264
  • 1
  • 5