Merge pull request #620 from cbodin/fix/add-android-media-intents-on-wildcard-input-accept

Add android media intents on wildcard input accept
This commit is contained in:
Lorenzo Pichilli 2021-01-29 00:53:09 +01:00 committed by GitHub
commit 179ef6320b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 81 additions and 33 deletions

View File

@ -3,9 +3,11 @@ package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
import android.Manifest; import android.Manifest;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.ContentResolver;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
@ -46,6 +48,7 @@ import com.pichillilorenzo.flutter_inappwebview.Shared;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -72,7 +75,8 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private static final int PICKER = 1; private static final int PICKER = 1;
private static final int PICKER_LEGACY = 3; private static final int PICKER_LEGACY = 3;
final String DEFAULT_MIME_TYPES = "*/*"; final String DEFAULT_MIME_TYPES = "*/*";
private static Uri outputFileUri; private static Uri videoOutputFileUri;
private static Uri imageOutputFileUri;
protected static final FrameLayout.LayoutParams FULLSCREEN_LAYOUT_PARAMS = new FrameLayout.LayoutParams( protected static final FrameLayout.LayoutParams FULLSCREEN_LAYOUT_PARAMS = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER); ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER);
@ -810,39 +814,37 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
// this filename instead // this filename instead
switch (requestCode) { switch (requestCode) {
case PICKER: case PICKER:
if (resultCode != RESULT_OK) { Uri[] results = null;
if (InAppWebViewFlutterPlugin.filePathCallback != null) { if (resultCode == RESULT_OK) {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(null); results = getSelectedFiles(data, resultCode);
} }
} else {
Uri result[] = this.getSelectedFiles(data, resultCode); if (InAppWebViewFlutterPlugin.filePathCallback != null) {
if (result != null) { InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(results);
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(result);
} else {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(new Uri[]{outputFileUri});
}
} }
break; break;
case PICKER_LEGACY: case PICKER_LEGACY:
Uri result = resultCode != Activity.RESULT_OK ? null : data == null ? outputFileUri : data.getData(); Uri result = null;
if (resultCode == RESULT_OK) {
result = data != null ? data.getData() : getCapturedMediaFile();
}
InAppWebViewFlutterPlugin.filePathCallbackLegacy.onReceiveValue(result); InAppWebViewFlutterPlugin.filePathCallbackLegacy.onReceiveValue(result);
break; break;
} }
InAppWebViewFlutterPlugin.filePathCallback = null; InAppWebViewFlutterPlugin.filePathCallback = null;
InAppWebViewFlutterPlugin.filePathCallbackLegacy = null; InAppWebViewFlutterPlugin.filePathCallbackLegacy = null;
outputFileUri = null; imageOutputFileUri = null;
videoOutputFileUri = null;
return true; return true;
} }
private Uri[] getSelectedFiles(Intent data, int resultCode) { private Uri[] getSelectedFiles(Intent data, int resultCode) {
if (data == null) {
return null;
}
// we have one file selected // we have one file selected
if (data.getData() != null) { if (data != null && data.getData() != null) {
if (resultCode == RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (resultCode == RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return WebChromeClient.FileChooserParams.parseResult(resultCode, data); return WebChromeClient.FileChooserParams.parseResult(resultCode, data);
} else { } else {
@ -851,7 +853,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
} }
// we have multiple files selected // we have multiple files selected
if (data.getClipData() != null) { if (data != null && data.getClipData() != null) {
final int numSelectedFiles = data.getClipData().getItemCount(); final int numSelectedFiles = data.getClipData().getItemCount();
Uri[] result = new Uri[numSelectedFiles]; Uri[] result = new Uri[numSelectedFiles];
for (int i = 0; i < numSelectedFiles; i++) { for (int i = 0; i < numSelectedFiles; i++) {
@ -859,6 +861,40 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
} }
return result; return result;
} }
// we have a captured image or video file
Uri mediaUri = getCapturedMediaFile();
if (mediaUri != null) {
return new Uri[]{mediaUri};
}
return null;
}
private boolean isFileNotEmpty(Uri uri) {
Activity activity = inAppBrowserActivity != null ? inAppBrowserActivity : Shared.activity;
long length;
try {
AssetFileDescriptor descriptor = activity.getContentResolver().openAssetFileDescriptor(uri, "r");
length = descriptor.getLength();
descriptor.close();
} catch (IOException e) {
return false;
}
return length > 0;
}
private Uri getCapturedMediaFile() {
if (imageOutputFileUri != null && isFileNotEmpty(imageOutputFileUri)) {
return imageOutputFileUri;
}
if (videoOutputFileUri != null && isFileNotEmpty(videoOutputFileUri)) {
return videoOutputFileUri;
}
return null; return null;
} }
@ -935,15 +971,15 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private Intent getPhotoIntent() { private Intent getPhotoIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE); imageOutputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageOutputFileUri);
return intent; return intent;
} }
private Intent getVideoIntent() { private Intent getVideoIntent() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
outputFileUri = getOutputUri(MediaStore.ACTION_VIDEO_CAPTURE); videoOutputFileUri = getOutputUri(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); intent.putExtra(MediaStore.EXTRA_OUTPUT, videoOutputFileUri);
return intent; return intent;
} }
@ -971,6 +1007,20 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
return intent; return intent;
} }
private Boolean acceptsAny(String[] types) {
if (isArrayEmpty(types)) {
return true;
}
for (String type : types) {
if (type.equals("*/*")) {
return true;
}
}
return false;
}
private Boolean acceptsImages(String types) { private Boolean acceptsImages(String types) {
String mimeType = types; String mimeType = types;
if (types.matches("\\.\\w+")) { if (types.matches("\\.\\w+")) {
@ -981,7 +1031,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private Boolean acceptsImages(String[] types) { private Boolean acceptsImages(String[] types) {
String[] mimeTypes = getAcceptedMimeType(types); String[] mimeTypes = getAcceptedMimeType(types);
return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "image"); return acceptsAny(types) || arrayContainsString(mimeTypes, "image");
} }
private Boolean acceptsVideo(String types) { private Boolean acceptsVideo(String types) {
@ -994,7 +1044,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private Boolean acceptsVideo(String[] types) { private Boolean acceptsVideo(String[] types) {
String[] mimeTypes = getAcceptedMimeType(types); String[] mimeTypes = getAcceptedMimeType(types);
return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "video"); return acceptsAny(types) || arrayContainsString(mimeTypes, "video");
} }
private Boolean arrayContainsString(String[] array, String pattern) { private Boolean arrayContainsString(String[] array, String pattern) {
@ -1056,31 +1106,29 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
String prefix = ""; String prefix = "";
String suffix = ""; String suffix = "";
String dir = ""; String dir = "";
String filename = "";
if (intentType.equals(MediaStore.ACTION_IMAGE_CAPTURE)) { if (intentType.equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
prefix = "image-"; prefix = "image";
suffix = ".jpg"; suffix = ".jpg";
dir = Environment.DIRECTORY_PICTURES; dir = Environment.DIRECTORY_PICTURES;
} else if (intentType.equals(MediaStore.ACTION_VIDEO_CAPTURE)) { } else if (intentType.equals(MediaStore.ACTION_VIDEO_CAPTURE)) {
prefix = "video-"; prefix = "video";
suffix = ".mp4"; suffix = ".mp4";
dir = Environment.DIRECTORY_MOVIES; dir = Environment.DIRECTORY_MOVIES;
} }
filename = prefix + String.valueOf(System.currentTimeMillis()) + suffix;
// for versions below 6.0 (23) we use the old File creation & permissions model // for versions below 6.0 (23) we use the old File creation & permissions model
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// only this Directory works on all tested Android versions // only this Directory works on all tested Android versions
// ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21) // ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21)
File storageDir = Environment.getExternalStoragePublicDirectory(dir); File storageDir = Environment.getExternalStoragePublicDirectory(dir);
String filename = String.format("%s-%d%s", prefix, System.currentTimeMillis(), suffix);
return new File(storageDir, filename); return new File(storageDir, filename);
} }
Activity activity = inAppBrowserActivity != null ? inAppBrowserActivity : Shared.activity; Activity activity = inAppBrowserActivity != null ? inAppBrowserActivity : Shared.activity;
File storageDir = activity.getApplicationContext().getExternalFilesDir(null); File storageDir = activity.getApplicationContext().getExternalFilesDir(null);
return File.createTempFile(filename, suffix, storageDir); return File.createTempFile(prefix, suffix, storageDir);
} }
private Boolean isArrayEmpty(String[] arr) { private Boolean isArrayEmpty(String[] arr) {