|
|
@@ -5,6 +5,7 @@ import android.net.Uri;
|
|
|
import android.util.Log;
|
|
|
import android.annotation.TargetApi;
|
|
|
import android.app.Activity;
|
|
|
+import android.content.Context;
|
|
|
import android.os.Build;
|
|
|
import android.view.KeyEvent;
|
|
|
import android.view.View;
|
|
|
@@ -17,9 +18,17 @@ import android.webkit.WebSettings;
|
|
|
import android.webkit.WebView;
|
|
|
import android.webkit.WebViewClient;
|
|
|
import android.widget.FrameLayout;
|
|
|
+import android.provider.MediaStore;
|
|
|
+import android.support.v4.content.FileProvider;
|
|
|
|
|
|
+import java.util.List;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
+import java.io.File;
|
|
|
+import java.util.Date;
|
|
|
+import java.io.IOException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
|
|
import io.flutter.plugin.common.MethodCall;
|
|
|
import io.flutter.plugin.common.MethodChannel;
|
|
|
@@ -35,6 +44,7 @@ class WebviewManager {
|
|
|
private ValueCallback<Uri> mUploadMessage;
|
|
|
private ValueCallback<Uri[]> mUploadMessageArray;
|
|
|
private final static int FILECHOOSER_RESULTCODE=1;
|
|
|
+ private Uri fileUri;
|
|
|
|
|
|
@TargetApi(7)
|
|
|
class ResultHandler {
|
|
|
@@ -47,6 +57,8 @@ class WebviewManager {
|
|
|
String dataString = intent.getDataString();
|
|
|
if(dataString != null){
|
|
|
results = new Uri[]{ Uri.parse(dataString) };
|
|
|
+ }else if(fileUri != null){
|
|
|
+ results = new Uri[]{ fileUri };
|
|
|
}
|
|
|
}
|
|
|
if(mUploadMessageArray != null){
|
|
|
@@ -76,10 +88,12 @@ class WebviewManager {
|
|
|
WebView webView;
|
|
|
Activity activity;
|
|
|
ResultHandler resultHandler;
|
|
|
+ Context context;
|
|
|
|
|
|
- WebviewManager(final Activity activity) {
|
|
|
+ WebviewManager(final Activity activity, final Context context) {
|
|
|
this.webView = new ObservableWebView(activity);
|
|
|
this.activity = activity;
|
|
|
+ this.context = context;
|
|
|
this.resultHandler = new ResultHandler();
|
|
|
WebViewClient webViewClient = new BrowserClient();
|
|
|
webView.setOnKeyListener(new View.OnKeyListener() {
|
|
|
@@ -158,11 +172,29 @@ class WebviewManager {
|
|
|
}
|
|
|
mUploadMessageArray = filePathCallback;
|
|
|
|
|
|
- Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
|
- contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
- contentSelectionIntent.setType("*/*");
|
|
|
- Intent[] intentArray;
|
|
|
- intentArray = new Intent[0];
|
|
|
+ final String[] acceptTypes = getSafeAcceptedTypes(fileChooserParams);
|
|
|
+ List<Intent> intentList = new ArrayList<Intent>();
|
|
|
+ if (acceptsImages(acceptTypes)) {
|
|
|
+ Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
+ fileUri = getOutputFilename(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
+ takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
|
|
|
+ intentList.add(takePhotoIntent);
|
|
|
+ }
|
|
|
+ if (acceptsVideo(acceptTypes)) {
|
|
|
+ Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
|
|
|
+ fileUri = getOutputFilename(MediaStore.ACTION_VIDEO_CAPTURE);
|
|
|
+ takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
|
|
|
+ intentList.add(takeVideoIntent);
|
|
|
+ }
|
|
|
+ Intent contentSelectionIntent;
|
|
|
+ if (Build.VERSION.SDK_INT >= 21) {
|
|
|
+ contentSelectionIntent = fileChooserParams.createIntent();
|
|
|
+ } else {
|
|
|
+ contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
|
+ contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
+ contentSelectionIntent.setType("*/*");
|
|
|
+ }
|
|
|
+ Intent[] intentArray = intentList.toArray(new Intent[intentList.size()]);
|
|
|
|
|
|
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
|
|
|
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
|
|
|
@@ -174,6 +206,73 @@ class WebviewManager {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ private Uri getOutputFilename(String intentType) {
|
|
|
+ String prefix = "";
|
|
|
+ String suffix = "";
|
|
|
+
|
|
|
+ if (intentType == MediaStore.ACTION_IMAGE_CAPTURE) {
|
|
|
+ prefix = "image-";
|
|
|
+ suffix = ".jpg";
|
|
|
+ } else if (intentType == MediaStore.ACTION_VIDEO_CAPTURE) {
|
|
|
+ prefix = "video-";
|
|
|
+ suffix = ".mp4";
|
|
|
+ }
|
|
|
+
|
|
|
+ String packageName = context.getPackageName();
|
|
|
+ File capturedFile = null;
|
|
|
+ try {
|
|
|
+ capturedFile = createCapturedFile(prefix, suffix);
|
|
|
+ } catch (IOException e) {
|
|
|
+ Log.e("CREATE FILE", "Error occurred while creating the File", e);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return FileProvider.getUriForFile(context, packageName + ".fileprovider", capturedFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ private File createCapturedFile(String prefix, String suffix) throws IOException {
|
|
|
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
|
|
+ String imageFileName = prefix + "_" + timeStamp;
|
|
|
+ File storageDir = context.getExternalFilesDir(null);
|
|
|
+ return File.createTempFile(imageFileName, suffix, storageDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Boolean acceptsImages(String[] types) {
|
|
|
+ return isArrayEmpty(types) || arrayContainsString(types, "image");
|
|
|
+ }
|
|
|
+
|
|
|
+ private Boolean acceptsVideo(String[] types) {
|
|
|
+ return isArrayEmpty(types) || arrayContainsString(types, "video");
|
|
|
+ }
|
|
|
+
|
|
|
+ private Boolean arrayContainsString(String[] array, String pattern) {
|
|
|
+ for (String content : array) {
|
|
|
+ if (content.contains(pattern)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Boolean isArrayEmpty(String[] arr) {
|
|
|
+ // when our array returned from getAcceptTypes() has no values set from the
|
|
|
+ // webview
|
|
|
+ // i.e. <input type="file" />, without any "accept" attr
|
|
|
+ // will be an array with one empty string element, afaik
|
|
|
+ return arr.length == 0 || (arr.length == 1 && arr[0].length() == 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String[] getSafeAcceptedTypes(WebChromeClient.FileChooserParams params) {
|
|
|
+
|
|
|
+ // the getAcceptTypes() is available only in api 21+
|
|
|
+ // for lower level, we ignore it
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
|
+ return params.getAcceptTypes();
|
|
|
+ }
|
|
|
+
|
|
|
+ final String[] EMPTY = {};
|
|
|
+ return EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
private void clearCookies() {
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
|
CookieManager.getInstance().removeAllCookies(new ValueCallback<Boolean>() {
|