Skip to content

Commit

Permalink
Merge pull request #620 from cbodin/fix/add-android-media-intents-on-…
Browse files Browse the repository at this point in the history
…wildcard-input-accept

Add android media intents on wildcard input accept
  • Loading branch information
pichillilorenzo authored Jan 28, 2021
2 parents 9ea8262 + 14e3e8c commit 179ef63
Showing 1 changed file with 81 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
Expand Down Expand Up @@ -46,6 +48,7 @@

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -72,7 +75,8 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private static final int PICKER = 1;
private static final int PICKER_LEGACY = 3;
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(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER);
Expand Down Expand Up @@ -810,39 +814,37 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
// this filename instead
switch (requestCode) {
case PICKER:
if (resultCode != RESULT_OK) {
if (InAppWebViewFlutterPlugin.filePathCallback != null) {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(null);
}
} else {
Uri result[] = this.getSelectedFiles(data, resultCode);
if (result != null) {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(result);
} else {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(new Uri[]{outputFileUri});
}
Uri[] results = null;
if (resultCode == RESULT_OK) {
results = getSelectedFiles(data, resultCode);
}

if (InAppWebViewFlutterPlugin.filePathCallback != null) {
InAppWebViewFlutterPlugin.filePathCallback.onReceiveValue(results);
}
break;

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);
break;

}

InAppWebViewFlutterPlugin.filePathCallback = null;
InAppWebViewFlutterPlugin.filePathCallbackLegacy = null;
outputFileUri = null;
imageOutputFileUri = null;
videoOutputFileUri = null;

return true;
}

private Uri[] getSelectedFiles(Intent data, int resultCode) {
if (data == null) {
return null;
}

// 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) {
return WebChromeClient.FileChooserParams.parseResult(resultCode, data);
} else {
Expand All @@ -851,14 +853,48 @@ private Uri[] getSelectedFiles(Intent data, int resultCode) {
}

// we have multiple files selected
if (data.getClipData() != null) {
if (data != null && data.getClipData() != null) {
final int numSelectedFiles = data.getClipData().getItemCount();
Uri[] result = new Uri[numSelectedFiles];
for (int i = 0; i < numSelectedFiles; i++) {
result[i] = data.getClipData().getItemAt(i).getUri();
}
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;
}

Expand Down Expand Up @@ -935,15 +971,15 @@ protected boolean needsCameraPermission() {

private Intent getPhotoIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
imageOutputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageOutputFileUri);
return intent;
}

private Intent getVideoIntent() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
outputFileUri = getOutputUri(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
videoOutputFileUri = getOutputUri(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoOutputFileUri);
return intent;
}

Expand Down Expand Up @@ -971,6 +1007,20 @@ private Intent getFileChooserIntent(String[] acceptTypes, boolean allowMultiple)
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) {
String mimeType = types;
if (types.matches("\\.\\w+")) {
Expand All @@ -981,7 +1031,7 @@ private Boolean acceptsImages(String types) {

private Boolean acceptsImages(String[] types) {
String[] mimeTypes = getAcceptedMimeType(types);
return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "image");
return acceptsAny(types) || arrayContainsString(mimeTypes, "image");
}

private Boolean acceptsVideo(String types) {
Expand All @@ -994,7 +1044,7 @@ private Boolean acceptsVideo(String types) {

private Boolean acceptsVideo(String[] types) {
String[] mimeTypes = getAcceptedMimeType(types);
return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "video");
return acceptsAny(types) || arrayContainsString(mimeTypes, "video");
}

private Boolean arrayContainsString(String[] array, String pattern) {
Expand Down Expand Up @@ -1056,31 +1106,29 @@ private File getCapturedFile(String intentType) throws IOException {
String prefix = "";
String suffix = "";
String dir = "";
String filename = "";

if (intentType.equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
prefix = "image-";
prefix = "image";
suffix = ".jpg";
dir = Environment.DIRECTORY_PICTURES;
} else if (intentType.equals(MediaStore.ACTION_VIDEO_CAPTURE)) {
prefix = "video-";
prefix = "video";
suffix = ".mp4";
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
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// only this Directory works on all tested Android versions
// ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21)
File storageDir = Environment.getExternalStoragePublicDirectory(dir);
String filename = String.format("%s-%d%s", prefix, System.currentTimeMillis(), suffix);
return new File(storageDir, filename);
}

Activity activity = inAppBrowserActivity != null ? inAppBrowserActivity : Shared.activity;
File storageDir = activity.getApplicationContext().getExternalFilesDir(null);
return File.createTempFile(filename, suffix, storageDir);
return File.createTempFile(prefix, suffix, storageDir);
}

private Boolean isArrayEmpty(String[] arr) {
Expand Down

0 comments on commit 179ef63

Please sign in to comment.