javaandroidandroid-webviewwebviewclient

Define and set options for custom WebViewClient class in Android


I have created a custom WebViewClient class that has very limited interaction - it can only load Amazon URLs and doesn't allow clicking of links. (amzn.to and smile.amazon are allowed as they redirect)

package com.domain.mypackage;

import android.net.Uri;
import android.view.KeyEvent;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class nonInteractiveWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideKeyEvent (WebView view, KeyEvent event) {
        return true;
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        String host = Uri.parse(view.getUrl()).getHost();

        if ("amzn.to".equals(host)) {
            return false;
        } else if (host != null && host.matches("(?i)^smile\\.amazon.*")) {
            return false;
        } else {
            return true;
        }
    }
}

I want to enhance this new class so that if I enable an option it will allow clicking of links, but only Amazon links. I have therefore added a boolean that I want to be able to set from the calling Activity.

package com.domain.mypackage;

import android.net.Uri;
import android.view.KeyEvent;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class nonInteractiveWebViewClient extends WebViewClient {

    public boolean canBrowseAmazonSites = false;

    @Override
    public boolean shouldOverrideKeyEvent (WebView view, KeyEvent event) {
        return true;
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        String host = Uri.parse(view.getUrl()).getHost();

        if ("amzn.to".equals(host)) {
            return false;
        } else if (host != null && host.matches("(?i)^smile\\.amazon.*")) {
            return false;
        // Allow clicking of Amazon links
        } else if ( canBrowseAmazonSites && host != null && ( host.matches("(?i)^smile\\.amazon.*") || host.matches("(?i)^www\\.amazon.*") ) ) {
            return false;
        } else {
            return true;
        }
    }
}

I create the WecViewClient in the calling Acttivity as follows:

    viewBinding.amazonWebview.getSettings().setJavaScriptEnabled(true);
    viewBinding.amazonWebview.getSettings().setSupportZoom(true);
    viewBinding.amazonWebview.setWebViewClient(new nonInteractiveWebViewClient() {
        @Override
        public void onPageStarted(WebView _param1, String _param2, Bitmap _param3) {
            super.onPageStarted(_param1, _param2, _param3);
            viewBinding.progressBar.setIndeterminate(true);
        }

        @Override
        public void onPageFinished(WebView _param1, String _param2) {
            super.onPageFinished(_param1, _param2);
            viewBinding.progressBar.setIndeterminate(false);
        }

    });

But I cannot work out how to set my Boolean from within the Activity.

I did wonder whether a Boolean was the right approach, or whether I should create a public method that I can call to set the Boolean, but either way, I can't figure out how to access the Boolean or the method.


Solution

  • I think I worked it out, but please comment if what I have done is in any way a bodge.

    I have left the class code as per the question, but added to the code i nteh main activity.

    Class code therefore remains:

    package com.domain.mypackage;
    
    import android.net.Uri;
    import android.view.KeyEvent;
    import android.webkit.WebResourceRequest;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    
    public class nonInteractiveWebViewClient extends WebViewClient {
    
        public boolean canBrowseAmazonSites = false;
    
        @Override
        public boolean shouldOverrideKeyEvent (WebView view, KeyEvent event) {
            return true;
        }
    
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            String host = Uri.parse(view.getUrl()).getHost();
    
            if ("amzn.to".equals(host)) {
                return false;
            } else if (host != null && host.matches("(?i)^smile\\.amazon.*")) {
                return false;
            // Allow clicking of Amazon links
            } else if ( canBrowseAmazonSites && host != null && ( host.matches("(?i)^smile\\.amazon.*") || host.matches("(?i)^www\\.amazon.*") ) ) {
                return false;
            } else {
                return true;
            }
        }
    }
    

    But now when I assign the WebViewClient to the WebView in the Activity, I declare it with an object name (rather than anonymously?).

    I can then access the boolean from that named object as follows:

       viewBinding.amazonWebview.getSettings().setJavaScriptEnabled(true);
        viewBinding.amazonWebview.getSettings().setSupportZoom(true);
        viewBinding.amazonWebview.setWebViewClient(amazonWebViewClient = new nonInteractiveWebViewClient() {
            @Override
            public void onPageStarted(WebView _param1, String _param2, Bitmap _param3) {
                super.onPageStarted(_param1, _param2, _param3);
                viewBinding.progressBar.setIndeterminate(true);
            }
    
            @Override
            public void onPageFinished(WebView _param1, String _param2) {
                super.onPageFinished(_param1, _param2);
                viewBinding.progressBar.setIndeterminate(false);
            }
        });
    
        amazonWebViewClient.canBrowseAmazonSites = true;
    

    Where amazonWebViewClient is decalred in the Activity class as follows:

        nonInteractiveWebViewClient amazonWebViewClient;