Support for other protocols in Android webview

你说的曾经没有我的故事 提交于 2019-11-27 03:59:29

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.

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);

}

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;
        }
}

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;
        }
    }
}

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.

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;
 }

Simplest solution

 Intent newApp = new Intent(Intent.ACTION_VIEW,  Uri.parse(URL));
startActivity(newApp);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!