Parcourir la source

[Add] - Add intent handeling

Visakeswaran il y a 5 ans
Parent
révision
5482a0f582

+ 78
- 6
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java Voir le fichier

@@ -129,6 +129,10 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
129 129
   // Use `webView.loadUrl("about:blank")` to reliably reset the view
130 130
   // state and release page resources (including any running JavaScript).
131 131
   protected static final String BLANK_URL = "about:blank";
132
+  
133
+  // Intent urls are a type of deeplinks which start with: intent://
134
+  private static final String INTENT_URL_PREFIX = "intent://";
135
+  
132 136
   protected WebViewConfig mWebViewConfig;
133 137
 
134 138
   protected RNCWebChromeClient mWebChromeClient = null;
@@ -740,18 +744,86 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
740 744
           createWebViewEvent(webView, url)));
741 745
     }
742 746
 
747
+
743 748
     @Override
744 749
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
745
-      activeUrl = url;
746
-      dispatchEvent(
747
-        view,
748
-        new TopShouldStartLoadWithRequestEvent(
749
-          view.getId(),
750
-          createWebViewEvent(view, url)));
750
+      if (url.equals(BLANK_URL)) return false;
751
+
752
+      // url blacklisting
753
+      if (mUrlPrefixesForDefaultIntent != null && mUrlPrefixesForDefaultIntent.size() > 0) {
754
+        ArrayList<Object> urlPrefixesForDefaultIntent = mUrlPrefixesForDefaultIntent.toArrayList();
755
+        for (Object urlPrefix : urlPrefixesForDefaultIntent) {
756
+          if (url.startsWith((String) urlPrefix)) {
757
+            launchIntent(view.getContext(), url);
758
+            return true;
759
+          }
760
+        }
761
+      }
762
+
763
+      if (mOriginWhitelist != null && shouldHandleURL(mOriginWhitelist, url)) {
764
+        return false;
765
+      }
766
+
767
+      launchIntent(view.getContext(), url);
751 768
       return true;
752 769
     }
753 770
 
754 771
 
772
+    private void launchIntent(Context context, String url) {
773
+      Intent intent = null;
774
+
775
+      // URLs starting with 'intent://' require special handling.
776
+      if (url.startsWith(INTENT_URL_PREFIX)) {
777
+        try {
778
+          intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
779
+        } catch (URISyntaxException e) {
780
+          FLog.e(ReactConstants.TAG, "Can't parse intent:// URI", e);
781
+        }
782
+      }
783
+
784
+      if (intent != null) {
785
+        // This is needed to prevent security issue where non-exported activities from the same process can be started with intent:// URIs.
786
+        // See: T10607927/S136245
787
+        intent.addCategory(Intent.CATEGORY_BROWSABLE);
788
+        intent.setComponent(null);
789
+        intent.setSelector(null);
790
+
791
+        PackageManager packageManager = context.getPackageManager();
792
+        ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
793
+        if (info != null) {
794
+            // App is installed.
795
+            context.startActivity(intent);
796
+        } else {
797
+            String fallbackUrl = intent.getStringExtra("browser_fallback_url");
798
+            intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fallbackUrl));
799
+        }
800
+      } else {
801
+        intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
802
+      }
803
+
804
+      try {
805
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
806
+        intent.addCategory(Intent.CATEGORY_BROWSABLE);
807
+        context.startActivity(intent);
808
+      } catch (ActivityNotFoundException e) {
809
+        FLog.w(ReactConstants.TAG, "activity not found to handle uri scheme for: " + url, e);
810
+      }
811
+    }
812
+
813
+    private boolean shouldHandleURL(List<Pattern> originWhitelist, String url) {
814
+      Uri uri = Uri.parse(url);
815
+      String scheme = uri.getScheme() != null ? uri.getScheme() : "";
816
+      String authority = uri.getAuthority() != null ? uri.getAuthority() : "";
817
+      String urlToCheck = scheme + "://" + authority;
818
+      for (Pattern pattern : originWhitelist) {
819
+        if (pattern.matcher(urlToCheck).matches()) {
820
+          return true;
821
+        }
822
+      }
823
+      return false;
824
+    }
825
+
826
+
755 827
     @TargetApi(Build.VERSION_CODES.N)
756 828
     @Override
757 829
     public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {