title: "net::ERR_UNKNOWN_URL_SCHEME" error when url is"intent://kakaopay..."
body: <p>I have build a hybrid-app using flutter's <code>web_view_plugin</code>(webview).
  One of our paying methods require to open a 3rd party app(in this case kakaotalk). But the flutter webview plugin does not provide this function and returned <code>net::ERR_UNKNOWN_URL_SCHEME</code>. I did some research and I understand that the problem lies in the <code>url</code>. If the <code>url</code> does not start with <code>http</code> or <code>https</code>, it will cause this error. </p>
  
  <p>So, to solve this problem I had to change native java code. Now I have no experience at all with <code>java</code> and <code>android</code>, so fixing the native code was very difficult. I understand that I have to modify <code>shouldOverrideUrlLoading</code> part, in order to allow the <code>url</code> that starts with <code>intent://</code> and also I have to put in some validation to check if the app is installed or not.(If not installed the user should be redirected to playstore)</p>
  
  <p>The code which I added is in <code>shouldOverrideUrlLoading</code>.
  I also did three imports. The rest is code, generated by flutter</p>
  
  <pre><code>package com.flutter_webview_plugin;
  
  import android.annotation.TargetApi;
  import android.graphics.Bitmap;
  import android.os.Build;
  import android.webkit.WebResourceRequest;
  import android.webkit.WebResourceResponse;
  import android.webkit.WebView;
  import android.webkit.WebViewClient;
  
  import java.util.HashMap;
  import java.util.Map;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  import android.content.Intent; //added import
  import android.net.Uri; //added import
  import android.content.ActivityNotFoundException; //added import
  /**
   * Created by lejard_h on 20/12/2017.
   */
  
  public class BrowserClient extends WebViewClient {
      private Pattern invalidUrlPattern = null;
  
      public BrowserClient() {
          this(null);
      }
  
      public BrowserClient(String invalidUrlRegex) {
          super();
          if (invalidUrlRegex != null) {
              invalidUrlPattern = Pattern.compile(invalidUrlRegex);
          }
      }
  
      public void updateInvalidUrlRegex(String invalidUrlRegex) {
          if (invalidUrlRegex != null) {
              invalidUrlPattern = Pattern.compile(invalidUrlRegex);
          } else {
              invalidUrlPattern = null;
          }
      }
  
      @Override
      public void onPageStarted(WebView view, String url, Bitmap favicon) {
          super.onPageStarted(view, url, favicon);
          Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          data.put("url", url);
          data.put("type", "startLoad");
          FlutterWebviewPlugin.channel.invokeMethod("onState", data);
      }
  
      @Override
      public void onPageFinished(WebView view, String url) {
          super.onPageFinished(view, url);
          Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          data.put("url", url);
  
          FlutterWebviewPlugin.channel.invokeMethod("onUrlChanged", data);
  
          data.put("type", "finishLoad");
          FlutterWebviewPlugin.channel.invokeMethod("onState", data);
  
      }
  
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
          // returning true causes the current WebView to abort loading the URL,
          // while returning false causes the WebView to continue loading the URL as usual.
          String url = request.getUrl().toString();
          boolean isInvalid = checkInvalidUrl(url);
          Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          data.put("url", url);
          data.put("type", isInvalid ? "abortLoad" : "shouldStart");
  
          FlutterWebviewPlugin.channel.invokeMethod("onState", data);
          return isInvalid;
      }
  
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          // returning true causes the current WebView to abort loading the URL,
          // while returning false causes the WebView to continue loading the URL as usual.
          if (url.startsWith(INTENT_PROTOCOL_START)) {
                  final int customUrlStartIndex = INTENT_PROTOCOL_START.length();
                  final int customUrlEndIndex = url.indexOf(INTENT_PROTOCOL_INTENT);
                  if (customUrlEndIndex &lt; 0) {
                      return false;
                  } else {
                      final String customUrl = url.substring(customUrlStartIndex, customUrlEndIndex);
                      try {
                          view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(customUrl)));
                      } catch (ActivityNotFoundException e) {
                          final int packageStartIndex = customUrlEndIndex + INTENT_PROTOCOL_INTENT.length();
                          final int packageEndIndex = url.indexOf(INTENT_PROTOCOL_END);
  
                          final String packageName = url.substring(packageStartIndex, packageEndIndex &lt; 0 ? url.length() : packageEndIndex);
                          view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY_STORE_PREFIX + packageName)));
                      }
                      return true;
                  }
              } else {
                  return false;
              }
          // boolean isInvalid = checkInvalidUrl(url);
          // Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          // data.put("url", url);
          // data.put("type", isInvalid ? "abortLoad" : "shouldStart");
  
          // FlutterWebviewPlugin.channel.invokeMethod("onState", data);
          // return isInvalid;
      }
  
  
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      @Override
      public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
          super.onReceivedHttpError(view, request, errorResponse);
          Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          data.put("url", request.getUrl().toString());
          data.put("code", Integer.toString(errorResponse.getStatusCode()));
          FlutterWebviewPlugin.channel.invokeMethod("onHttpError", data);
      }
  
      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
          super.onReceivedError(view, errorCode, description, failingUrl);
          Map&lt;String, Object&gt; data = new HashMap&lt;&gt;();
          data.put("url", failingUrl);
          data.put("code", errorCode);
          FlutterWebviewPlugin.channel.invokeMethod("onHttpError", data);
      }
  
      private boolean checkInvalidUrl(String url) {
          if (invalidUrlPattern == null) {
              return false;
          } else {
              Matcher matcher = invalidUrlPattern.matcher(url);
              return matcher.lookingAt();
          }
      }
  }
  </code></pre>
  
  <p>The code compiles, but it still returns the same error <code>net::ERR_UNKNOWN_URL_SCHEME</code> when I try to pay with the "3rd party app(kakaotalk)"</p>