Bläddra i källkod

Merge pull request #105 from peter9teufel/master

Support file upload via WebView on Android
Hadrien Lejard 7 år sedan
förälder
incheckning
7ac858523d

+ 12 - 2
android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java

@@ -3,6 +3,7 @@ package com.flutter_webview_plugin;
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Point;
 import android.view.Display;
 import android.widget.FrameLayout;
@@ -17,7 +18,7 @@ import io.flutter.plugin.common.PluginRegistry;
 /**
  * FlutterWebviewPlugin
  */
-public class FlutterWebviewPlugin implements MethodCallHandler {
+public class FlutterWebviewPlugin implements MethodCallHandler, PluginRegistry.ActivityResultListener {
     private Activity activity;
     private WebviewManager webViewManager;
     static MethodChannel channel;
@@ -25,7 +26,8 @@ public class FlutterWebviewPlugin implements MethodCallHandler {
 
     public static void registerWith(PluginRegistry.Registrar registrar) {
         channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME);
-        FlutterWebviewPlugin instance = new FlutterWebviewPlugin(registrar.activity());
+        final FlutterWebviewPlugin instance = new FlutterWebviewPlugin(registrar.activity());
+        registrar.addActivityResultListener(instance);
         channel.setMethodCallHandler(instance);
     }
 
@@ -196,4 +198,12 @@ public class FlutterWebviewPlugin implements MethodCallHandler {
         final float scale = context.getResources().getDisplayMetrics().density;
         return (int) (dp * scale + 0.5f);
     }
+
+    @Override
+    public boolean onActivityResult(int i, int i1, Intent intent) {
+        if(webViewManager != null && webViewManager.resultHandler != null){
+            return webViewManager.resultHandler.handleResult(i, i1, intent);
+        }
+        return false;
+    }
 }

+ 108 - 1
android/src/main/java/com/flutter_webview_plugin/WebviewManager.java

@@ -1,5 +1,7 @@
 package com.flutter_webview_plugin;
 
+import android.content.Intent;
+import android.net.Uri;
 import android.util.Log;
 import android.annotation.TargetApi;
 import android.app.Activity;
@@ -9,6 +11,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.CookieManager;
 import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.FrameLayout;
@@ -16,17 +19,62 @@ import android.widget.FrameLayout;
 import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
 
+import static android.app.Activity.RESULT_OK;
+
 /**
  * Created by lejard_h on 20/12/2017.
  */
 
 class WebviewManager {
 
+    private ValueCallback<Uri> mUploadMessage;
+    private ValueCallback<Uri[]> mUploadMessageArray;
+    private final static int FILECHOOSER_RESULTCODE=1;
+
+    @TargetApi(7)
+    class ResultHandler {
+        public boolean handleResult(int requestCode, int resultCode, Intent intent){
+            boolean handled = false;
+            if(Build.VERSION.SDK_INT >= 21){
+                Uri[] results = null;
+                // check result
+                if(resultCode == Activity.RESULT_OK){
+                    if(requestCode == FILECHOOSER_RESULTCODE){
+                        if(mUploadMessageArray != null){
+                            String dataString = intent.getDataString();
+                            if(dataString != null){
+                                results = new Uri[]{Uri.parse(dataString)};
+                            }
+                        }
+                        handled = true;
+                    }
+                }
+                mUploadMessageArray.onReceiveValue(results);
+                mUploadMessageArray = null;
+            }else {
+                if (requestCode == FILECHOOSER_RESULTCODE) {
+                    if (null != mUploadMessage) {
+                        Uri result = intent == null || resultCode != RESULT_OK ? null
+                                : intent.getData();
+                        mUploadMessage.onReceiveValue(result);
+                        mUploadMessage = null;
+                    }
+                    handled = true;
+                }
+            }
+            return handled;
+        }
+    }
+
     boolean closed = false;
     WebView webView;
+    Activity activity;
+    ResultHandler resultHandler;
 
-    WebviewManager(Activity activity) {
+    WebviewManager(final Activity activity) {
         this.webView = new WebView(activity);
+        this.activity = activity;
+        this.resultHandler = new ResultHandler();
         WebViewClient webViewClient = new BrowserClient();
         webView.setOnKeyListener(new View.OnKeyListener() {
             @Override
@@ -48,6 +96,65 @@ class WebviewManager {
         });
 
         webView.setWebViewClient(webViewClient);
+        webView.setWebChromeClient(new WebChromeClient()
+        {
+            //The undocumented magic method override
+            //Eclipse will swear at you if you try to put @Override here
+            // For Android 3.0+
+            public void openFileChooser(ValueCallback<Uri> uploadMsg) {
+
+                mUploadMessage = uploadMsg;
+                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+                i.addCategory(Intent.CATEGORY_OPENABLE);
+                i.setType("image/*");
+                activity.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);
+
+            }
+
+            // For Android 3.0+
+            public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
+                mUploadMessage = uploadMsg;
+                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+                i.addCategory(Intent.CATEGORY_OPENABLE);
+                i.setType("*/*");
+               activity.startActivityForResult(
+                        Intent.createChooser(i, "File Browser"),
+                        FILECHOOSER_RESULTCODE);
+            }
+
+            //For Android 4.1
+            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
+                mUploadMessage = uploadMsg;
+                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+                i.addCategory(Intent.CATEGORY_OPENABLE);
+                i.setType("image/*");
+                activity.startActivityForResult( Intent.createChooser( i, "File Chooser" ), FILECHOOSER_RESULTCODE );
+
+            }
+
+            //For Android 5.0+
+            public boolean onShowFileChooser(
+                    WebView webView, ValueCallback<Uri[]> filePathCallback,
+                    FileChooserParams fileChooserParams){
+                if(mUploadMessageArray != null){
+                    mUploadMessageArray.onReceiveValue(null);
+                }
+                mUploadMessageArray = filePathCallback;
+
+                Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
+                contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
+                contentSelectionIntent.setType("*/*");
+                Intent[] intentArray;
+                intentArray = new Intent[0];
+
+                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
+                chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
+                chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
+                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
+                activity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
+                return true;
+            }
+        });
     }
 
     private void clearCookies() {

+ 8 - 0
lib/src/base.dart

@@ -146,6 +146,14 @@ class FlutterWebviewPlugin {
     await _channel.invokeMethod("reloadUrl", args);
   }
 
+  /// adds the plugin as ActivityResultListener
+  /// Only needed and used on Android
+  Future registerAcitivityResultListener() => _channel.invokeMethod("registerAcitivityResultListener");
+
+  /// removes the plugin as ActivityResultListener
+  /// Only needed and used on Android
+  Future removeAcitivityResultListener() => _channel.invokeMethod("removeAcitivityResultListener");
+
   /// Close all Streams
   void dispose() {
     _onDestroy.close();