Support for other protocols in Android webview
Asked Answered
G

7

22

I've created a web view app, the page that is displayed features market:// links but upon clicking them I get the 404 screen along with the error that the protocol is not supported. I've tried looking through documentation but was unable to find anything relating to this. Any help is much appreciated.

Gunning answered 27/8, 2010 at 10:27 Comment(0)
L
43

For me the JavaScript thing wasn't a solution as the HTML is not under my control. So if you need to control this from the application side, then there is a relative simple solution: Derive from WebViewClientand inject the implementation using WebView.setWebViewClient(). All you need to override in your WebViewClientimplementation is the shouldOverrideUrlLoading method as shown here:

public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url != null && url.startsWith("market://")) {
        view.getContext().startActivity(
            new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        return true;
    } else {
        return false;
    }
}

For me this works fine.

Lithology answered 1/4, 2011 at 14:19 Comment(3)
Great idea, quick and easy. But I did think there would be official protocol recognition support.Roborant
should call it in onReceivedError instead of shouldOverrideUrlLoadingHalting
@OmidAminiva probably not - this means the intent is handled nicely, but the user gets shown an error messageBenevolence
W
3

HOPE THIS HELPS YOU

public boolean shouldOverrideUrlLoading(WebView view, String url) 
{
    if (url.startsWith("market://")||url.startsWith("vnd:youtube")||url.startsWith("tel:")||url.startsWith("mailto:"))
    {
        Intent intent = new Intent(Intent.ACTION_VIEW); 
        intent.setData(Uri.parse(url)); 
        startActivity(intent);
        return true;
     }
    else{
        view.loadUrl(url);
        return true;
        }
}
Wooden answered 9/1, 2015 at 15:0 Comment(2)
It would be better to add some explanation in addition to the code.Rhodian
Please consider including some information about your answer, rather than simply posting code. We try to provide not just 'fixes', but help people learn. You should explain what was wrong in the original code, what you did differently, and why your change(s) worked.Recommit
C
1

For the links to work you have to have the market app installed on your device/emulator. Also your app need to request a permission to access network.

UPD: as a workaround you can call java code from within the webview, for example if you generate links like this:

<a href="javascript:go('market://your.path.to.market.app')">..</a>

Define a javascript function named go():

<script type="text/javascript">
   function go(link) {
     if (handler) {
           handler.go(link);
         } else {
           document.location = link;
         }
   }
</script>

You then can pass in a handler object into the WebView:

webview.addJavascriptInterface(new Handler() {
        @Override
        public void go(String marketUrl) {
                         //start market intent here
        }
    },  "handler");

Handler interface can be defined as follows:

   public interface Handler{

    public void go(String url);

}
Colossian answered 27/8, 2010 at 10:53 Comment(10)
I've tried it on the device and it doesn't work. I have network permissions working because everything loads OK but when a market link is clicked I get an error of unsupported protocol. Any help is much appreciated.Gunning
What device do you use? Are you sure that device has market client installed?Colossian
Or would it be possible to make market:// links open using the default browser instead as a workaround?Gunning
Are the links generated by you? If yes you can use javascript to call android java code, which can start market intent.Colossian
Yeah the links are input by me. It's basically webview wrapping a mobile version of my wordpress site which has market links. So I would use javascript within my website? I'm not familar with javascript so any advice or pointing in the right direction is much appreciated.Gunning
Thanks for the update, I'll give it a go and let you know how it works out :).Gunning
Hmm, another problem I have is that I'm running the admob code from using PHP in the webview, the admob code also links to market links. I could use native android code for admob but that would mean that people who access the site just using the mobile internet wouldnt see ads. Hmmm.Gunning
Then I'd recommend you not to modify the links but rather add onClick handler to each link. At the onClick handler check for existence of 'handler' variable and if that exists, stop the event (to prevent browser action) and call android handler.Colossian
I'm not a big specialist in pure javascript, but I'm pretty sure that what I've described is possible. I think you easily will find lots of examples.Colossian
I'm having some problems figuring out the code - would you be available to hire to do this?Gunning
B
0

Work for me:

webView = (WebView) findViewById(R.id.webView);
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setPluginState(WebSettings.PluginState.ON_DEMAND);

webView.setWebViewClient(new MyWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);

webView.loadUrl("http://myweb.com");

private class MyWebViewClient extends WebViewClient {
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url != null && url.startsWith("whatsapp://")) {
            view.getContext().startActivity(
                    new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
            return true;
        } else {
            return false;
        }
    }
}
Brut answered 3/2, 2015 at 17:1 Comment(0)
C
0

It is important to understand how the webview and its clients (webviewclient and webchromeclient) works. Please go through the http://therockncoder.blogspot.in/2014/04/understanding-androids-webchromeclient.html

In the webviewclient's shouldOverrideUrlLoading() method, you can decide if you want to open the link in new browser or within the webview. If you don't override this method, it will by default open the link in a new browser outside of the your android application. If you want to open within webview, override the method as below

public boolean shouldOverrideUrlLoading(WebView view, String url) { <br>
    Log.v("activity", "INSIDE WEBVIEW CLIENT ON shouldOverrideUrlLoading");
        view.loadUrl(url);
        return false; //need to understand return value based on usage
    }

Schemes like whatsapp://send?text=Hello%20World! or market://details?id=xx.xx.xx will open the corresponding apps automatically if they are opened outside the webview and if that app is installed on the handset.

If you want to open certain links within webview and specific schemes outside webview, you need to override WebChromeClients onCreateWindow() method as explained in the link provided above. It should solve the purpose.

Cloakroom answered 24/7, 2015 at 7:26 Comment(0)
C
0

Instead of adding check for particular scheme, Modifying @sven solution, this will work for all schemes

public boolean shouldOverrideUrlLoading(WebView view, String url) {
 String host= Uri.parse(url).getHost();
 if (host == null) {
    view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
    return true;
   }

   view.loadUrl(url);
   return false;
 }
Canaletto answered 26/2, 2019 at 11:45 Comment(0)
C
-2

Simplest solution

 Intent newApp = new Intent(Intent.ACTION_VIEW,  Uri.parse(URL));
startActivity(newApp);
Caber answered 23/4, 2013 at 6:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.