Download File In webview ChromClient

android

#1

How can i Download File in Webview which is Implemented in ChromeClient


#2

Use the set download listener callback in WebView.


#3

webview.android.setDownloadListener(new MyDownloadListener());

and

class MyDownloadListener implements android.webkit.DownloadListener{

    onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength)
    {
        // const androidApp = app.android;
        // if (androidApp.foregroundActivity === androidApp.startActivity) {
        //     ////console.log("We are currently in the main (start) activity of the application");
        //     const context = utils.ad.getApplicationContext();
        //     let intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
        //         intent.setData(android.net.Uri.parse(url));
        //         androidApp.foregroundActivity.startActivity(intent);
        // }
        openAdvancedUrl(url);
       
    }
}

Gives Error

Cannot convert object to Landroid/webkit/DownloadListener; at index 0

In Angular TypeScript


#4

Please check the docs, that’s is not exactly how you would implement a native Java class.


#5

Thanks

webview.android.setDownloadListener(new android.webkit.DownloadListener({
                onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength)
                {
                    const androidApp = app.android;
                    if (androidApp.foregroundActivity === androidApp.startActivity) {
                        const context = utils.ad.getApplicationContext();
                        let intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
                            intent.setData(android.net.Uri.parse(url));
                            androidApp.foregroundActivity.startActivity(intent);
                    }
                }
            }));

#7

Showing this error - ERROR TypeError: Cannot read property ‘setDownloadListener’ of undefined


#8

Simply the same mistake I guess, you are accessing android object even before its available to you. Make sure you do anything on native object after loaded event.


#9

In HTML file
<WebView #myWebView [src]="webViewSrc" (loadStarted)="webViewLoaded($event)"></WebView>
In

componentname.component.ts

 webViewLoaded(args: EventData): any
    {
        const webview: WebView = <WebView>args.object;
        if(webview.android) { // in IOS android will be undefined
            console.log("Inside android");
           
            webview.android.getSettings().setBuiltInZoomControls(false);
            webview.android.getSettings().setJavaScriptEnabled(true);
            webview.android.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
            webview.android.getSettings().setAllowFileAccess(true);
            webview.android.getSettings().setPluginsEnabled(true);
            webview.android.getSettings().setAllowContentAccess(true);
            webview.android.getSettings().setAllowFileAccess(true);
            webview.android.getSettings().setAllowFileAccessFromFileURLs(true);
            webview.android.getSettings().setAllowUniversalAccessFromFileURLs(true);
            webview.android.getSettings().setDomStorageEnabled(true);

            webview.android.setDownloadListener(new android.webkit.DownloadListener({
                onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength)
                {
                    const androidApp = app.android;
                    if (androidApp.foregroundActivity === androidApp.startActivity) {
                        const context = utils.ad.getApplicationContext();
                        let intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
                            intent.setData(android.net.Uri.parse(url));
                            androidApp.foregroundActivity.startActivity(intent);
                    }
                }
            }));
          }
    }

#10

Thanks,
But still i am stuck in the download part as currently the url which i am getting inside onDownloadStart method is a blob url and intent expect url starting from http/https.


#11

Can you setup a playground example where I can see the issue.

Also please let me know which device and OS version you used to test it.


#12

The problem is something like -
URL :- https://stackblitz.com/edit/angular-blob-file-download?file=app%2Fapp.component.ts
If i am trying to open this website in google chrome desktop/mobile browser and click on download it simply download the file.
But if i am trying inside webview it show activity not found exception as url received in onDownloadStart method is something like “blob:http://…”.

min sdk version - 17
Android version currently testing - 7.0


#13

I believe we are talking about NativeScript here (Web app !== Native mobile app). There are certain things you will have to do when you build your own web view within app as @mahavirvataliya demonstrated above. When you open web page in Chrome it takes care of those things for you, so you can’t actually compare both.


#14

if you think of blob type then use downloadmanager as follow make sure permission will be granted for storage

webview.android.setDownloadListener(new android.webkit.DownloadListener({
                onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength) {
                    let request = new android.app.DownloadManager.Request(android.net.Uri.parse(url));
                    request.setMimeType(mimetype);
                    let cookies = android.webkit.CookieManager.getInstance().getCookie(url);
                    request.addRequestHeader("cookie", cookies);
                    request.addRequestHeader("User-Agent", userAgent);
                    request.setDescription("Downloading file...");
                    request.setTitle(android.webkit.URLUtil.guessFileName(url, contentDisposition, mimetype));
                    request.allowScanningByMediaScanner();
                    request.setNotificationVisibility(android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                    request.setDestinationInExternalPublicDir(android.os.Environment.DIRECTORY_DOWNLOADS, android.webkit.URLUtil.guessFileName(url, contentDisposition, mimetype));
                    let dm = utils.ad.getApplicationContext().getSystemService(android.content.Context.DOWNLOAD_SERVICE);
                    dm.enqueue(request);
                }
            }));

#15

because here it will use mimetype in parameter