【问题标题】:Support for other protocols in Android webview支持 Android webview 中的其他协议
【发布时间】:2011-04-04 17:44:14
【问题描述】:

我创建了一个 web 视图应用程序,显示的页面具有 market:// 链接,但单击它们后,我得到 404 屏幕以及不支持协议的错误。我尝试过查看文档,但找不到与此相关的任何内容。非常感谢任何帮助。

【问题讨论】:

    标签: android android-webview custom-url uri-scheme


    【解决方案1】:

    不是为特定方案添加检查,而是修改@sven 解决方案,这将适用于所有方案

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

    【讨论】:

      【解决方案2】:

      了解 webview 及其客户端(webviewclient 和 webchromeclient)的工作原理很重要。请通过http://therockncoder.blogspot.in/2014/04/understanding-androids-webchromeclient.html

      在 webviewclient 的 shouldOverrideUrlLoading() 方法中,您可以决定是在新浏览器中还是在 webview 中打开链接。如果您不覆盖此方法,默认情况下它将在您的 android 应用程序之外的新浏览器中打开该链接。 如果你想在 webview 中打开,覆盖下面的方法

      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
          }
      

      whatsapp://send?text=Hello%20World!market://details?id=xx.xx.xx 等方案将打开相应的应用如果它们在 web 视图之外打开并且该应用程序已安装在手机上,则会自动打开。

      如果您想在 webview 中打开某些链接并在 webview 之外打开特定方案,您需要覆盖 WebChromeClients onCreateWindow() 方法,如上面提供的链接中所述。它应该解决目的。

      【讨论】:

        【解决方案3】:

        为我工作:

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

        【讨论】:

          【解决方案4】:

          希望对您有所帮助

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

          【讨论】:

          • 最好在代码之外加上一些解释。
          • 请考虑包含一些关于您的答案的信息,而不是简单地发布代码。我们试图提供的不仅仅是“修复”,而是帮助人们学习。您应该解释原始代码中的问题、您所做的不同之处以及您的更改为何有效。
          【解决方案5】:

          最简单的解决方案

           Intent newApp = new Intent(Intent.ACTION_VIEW,  Uri.parse(URL));
          startActivity(newApp);
          

          【讨论】:

            【解决方案6】:

            对我来说,JavaScript 并不是一个解决方案,因为 HTML 不受我的控制。因此,如果您需要从应用程序端进行控制,那么有一个相对简单的解决方案:从WebViewClient 派生并使用WebView.setWebViewClient() 注入实现。您需要在 WebViewClientimplementation 中覆盖的只是 shouldOverrideUrlLoading 方法,如下所示:

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

            对我来说这很好用。

            【讨论】:

            • 好主意,快速简单。但我确实认为会有官方协议识别支持。
            • 应该在 onReceivedError 中调用它而不是 shouldOverrideUrlLoading
            • @OmidAminiva 可能不是 - 这意味着意图处理得很好,但会向用户显示错误消息
            【解决方案7】:

            要使链接生效,您必须在设备/模拟器上安装市场应用。 此外,您的应用需要请求访问网络的权限。

            更新: 作为一种解决方法,您可以从 web 视图中调用 java 代码,例如,如果您生成这样的链接:

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

            定义一个名为 go() 的 javascript 函数:

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

            然后您可以将处理程序对象传入 WebView:

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

            Handler接口可以定义如下:

               public interface Handler{
            
                public void go(String url);
            
            }
            

            【讨论】:

            • 我在设备上试过了,还是不行。我有网络权限工作,因为一切正常,但是当单击市场链接时,我收到不支持协议的错误。非常感谢任何帮助。
            • 您使用什么设备?您确定该设备已安装市场客户端吗?
            • 或者是否可以使用默认浏览器打开market://链接作为一种解决方法?
            • 链接是你自己生成的吗?如果是的话,你可以使用javascript调用android java代码,这可以启动市场意图。
            • 是的,链接是我输入的。它基本上是 webview 包装了我的 wordpress 网站的移动版本,其中包含市场链接。所以我会在我的网站中使用 javascript 吗?我不熟悉 javascript,因此非常感谢任何建议或指出正确的方向。
            猜你喜欢
            • 1970-01-01
            • 2013-04-10
            • 1970-01-01
            • 2023-03-04
            • 2014-03-06
            • 2012-05-09
            • 2011-07-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多