forked from Ivasoft/mattermost-mobile
(cherry picked from commit 0a4dafa127)
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
@@ -3,11 +3,9 @@ package com.mattermost.share;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentResolver;
|
||||
import android.os.Environment;
|
||||
import android.webkit.MimeTypeMap;
|
||||
@@ -15,18 +13,18 @@ import android.util.Log;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Objects;
|
||||
|
||||
// Class based on the steveevers DocumentHelper https://gist.github.com/steveevers/a5af24c226f44bb8fdc3
|
||||
|
||||
public class RealPathUtil {
|
||||
public static String getRealPathFromURI(final Context context, final Uri uri) {
|
||||
|
||||
final boolean isKitKatOrNewer = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
|
||||
// DocumentProvider
|
||||
if (isKitKatOrNewer && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
@@ -111,6 +109,7 @@ public class RealPathUtil {
|
||||
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
returnCursor.moveToFirst();
|
||||
fileName = sanitizeFilename(returnCursor.getString(nameIndex));
|
||||
returnCursor.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
// just continue to get the filename with the last segment of the path
|
||||
@@ -118,7 +117,7 @@ public class RealPathUtil {
|
||||
|
||||
try {
|
||||
if (TextUtils.isEmpty(fileName)) {
|
||||
fileName = sanitizeFilename(uri.getLastPathSegment().toString().trim());
|
||||
fileName = sanitizeFilename(uri.getLastPathSegment().trim());
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +126,6 @@ public class RealPathUtil {
|
||||
cacheDir.mkdirs();
|
||||
}
|
||||
|
||||
String mimeType = getMimeType(uri.getPath());
|
||||
tmpFile = new File(cacheDir, fileName);
|
||||
tmpFile.createNewFile();
|
||||
|
||||
@@ -234,7 +232,7 @@ public class RealPathUtil {
|
||||
|
||||
private static void deleteRecursive(File fileOrDirectory) {
|
||||
if (fileOrDirectory.isDirectory())
|
||||
for (File child : fileOrDirectory.listFiles())
|
||||
for (File child : Objects.requireNonNull(fileOrDirectory.listFiles()))
|
||||
deleteRecursive(child);
|
||||
|
||||
fileOrDirectory.delete();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
|
||||
index 48fb5c1..3872d91 100644
|
||||
index 48fb5c1..5ca1e20 100644
|
||||
--- a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
|
||||
+++ b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
|
||||
@@ -3,6 +3,7 @@ package com.imagepicker;
|
||||
@@ -10,15 +10,7 @@ index 48fb5c1..3872d91 100644
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -49,6 +50,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
+import java.util.ArrayList;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
import com.facebook.react.modules.core.PermissionAwareActivity;
|
||||
@@ -69,6 +71,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -69,6 +70,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
public static final int REQUEST_LAUNCH_IMAGE_LIBRARY = 13002;
|
||||
public static final int REQUEST_LAUNCH_VIDEO_LIBRARY = 13003;
|
||||
public static final int REQUEST_LAUNCH_VIDEO_CAPTURE = 13004;
|
||||
@@ -26,11 +18,14 @@ index 48fb5c1..3872d91 100644
|
||||
public static final int REQUEST_PERMISSIONS_FOR_CAMERA = 14001;
|
||||
public static final int REQUEST_PERMISSIONS_FOR_LIBRARY = 14002;
|
||||
|
||||
@@ -266,26 +269,24 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -265,27 +267,22 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
{
|
||||
cameraIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, videoDurationLimit);
|
||||
}
|
||||
}
|
||||
+ else if (pickBoth) {
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
+ } else if (pickBoth) {
|
||||
+ Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
+ this.setImageCaptureUri(takePictureIntent);
|
||||
+ Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
|
||||
@@ -41,9 +36,7 @@ index 48fb5c1..3872d91 100644
|
||||
+ cameraIntent.putExtra(Intent.EXTRA_TITLE, "Choose an action");
|
||||
+ cameraIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
|
||||
+ requestCode = REQUEST_LAUNCH_MIXED_CAPTURE;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
+ } else {
|
||||
requestCode = REQUEST_LAUNCH_IMAGE_CAPTURE;
|
||||
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
|
||||
@@ -66,23 +59,24 @@ index 48fb5c1..3872d91 100644
|
||||
}
|
||||
|
||||
if (cameraIntent.resolveActivity(reactContext.getPackageManager()) == null)
|
||||
@@ -350,16 +351,19 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -349,17 +346,18 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
requestCode = REQUEST_LAUNCH_VIDEO_LIBRARY;
|
||||
libraryIntent = new Intent(Intent.ACTION_PICK);
|
||||
libraryIntent.setType("video/*");
|
||||
}
|
||||
+ else if (pickBoth) {
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
+ } else if (pickBoth) {
|
||||
+ libraryIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
+ libraryIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
+ libraryIntent.setType("image/*");
|
||||
+ libraryIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
|
||||
+ requestCode = REQUEST_LAUNCH_MIXED_CAPTURE;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
+ } else {
|
||||
requestCode = REQUEST_LAUNCH_IMAGE_LIBRARY;
|
||||
libraryIntent = new Intent(Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
-
|
||||
|
||||
- if (pickBoth)
|
||||
- {
|
||||
- libraryIntent.setType("image/* video/*");
|
||||
@@ -91,7 +85,7 @@ index 48fb5c1..3872d91 100644
|
||||
}
|
||||
|
||||
if (libraryIntent.resolveActivity(reactContext.getPackageManager()) == null)
|
||||
@@ -385,75 +389,47 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -385,75 +383,42 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,29 +107,10 @@ index 48fb5c1..3872d91 100644
|
||||
- callback = null;
|
||||
- return;
|
||||
- }
|
||||
+ protected String getMimeType(Activity activity, Uri uri) {
|
||||
+ String mimeType = null;
|
||||
+ if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
|
||||
+ ContentResolver cr = activity.getApplicationContext().getContentResolver();
|
||||
+ mimeType = cr.getType(uri);
|
||||
+ } else {
|
||||
+ String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
|
||||
+ .toString());
|
||||
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
|
||||
+ fileExtension.toLowerCase());
|
||||
+ }
|
||||
+ return mimeType;
|
||||
+ }
|
||||
|
||||
-
|
||||
- Uri uri = null;
|
||||
- switch (requestCode)
|
||||
+ protected void extractImageFromResult(Activity activity, Uri uri, int requestCode) {
|
||||
+ String realPath = getRealPathFromURI(uri);
|
||||
+ String mime = getMimeType(activity, uri);
|
||||
+ final boolean isUrl = !TextUtils.isEmpty(realPath) &&
|
||||
+ Patterns.WEB_URL.matcher(realPath).matches();
|
||||
+ if (realPath == null || isUrl)
|
||||
{
|
||||
- {
|
||||
- case REQUEST_LAUNCH_IMAGE_CAPTURE:
|
||||
- uri = cameraCaptureURI;
|
||||
- break;
|
||||
@@ -172,20 +147,35 @@ index 48fb5c1..3872d91 100644
|
||||
- responseHelper.invokeResponse(callback);
|
||||
- callback = null;
|
||||
- return;
|
||||
-
|
||||
+ protected String getMimeType(Activity activity, Uri uri) {
|
||||
+ String mimeType = null;
|
||||
+ if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
|
||||
+ ContentResolver cr = activity.getApplicationContext().getContentResolver();
|
||||
+ mimeType = cr.getType(uri);
|
||||
+ } else {
|
||||
+ String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
|
||||
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
|
||||
+ fileExtension.toLowerCase());
|
||||
+ }
|
||||
+ return mimeType;
|
||||
+ }
|
||||
|
||||
- case REQUEST_LAUNCH_VIDEO_CAPTURE:
|
||||
- final String path = getRealPathFromURI(data.getData());
|
||||
- responseHelper.putString("uri", data.getData().toString());
|
||||
- responseHelper.putString("path", path);
|
||||
- fileScan(reactContext, path);
|
||||
+ try
|
||||
+ {
|
||||
+ protected void extractImageFromResult(Activity activity, Uri uri, int requestCode) {
|
||||
+ String realPath = getRealPathFromURI(uri);
|
||||
+ String mime = getMimeType(activity, uri);
|
||||
+ final boolean isUrl = !TextUtils.isEmpty(realPath) &&
|
||||
+ Patterns.WEB_URL.matcher(realPath).matches();
|
||||
+ if (isUrl) {
|
||||
+ try {
|
||||
+ File file = createFileFromURI(uri);
|
||||
+ realPath = file.getAbsolutePath();
|
||||
+ uri = Uri.fromFile(file);
|
||||
+ }
|
||||
+ catch (Exception e)
|
||||
+ {
|
||||
+ } catch (Exception e) {
|
||||
+ // image not in cache
|
||||
+ responseHelper.putString("error", "Could not read photo");
|
||||
+ responseHelper.putString("uri", uri.toString());
|
||||
@@ -201,7 +191,7 @@ index 48fb5c1..3872d91 100644
|
||||
final ReadExifResult result = readExifInterface(responseHelper, imageConfig);
|
||||
|
||||
if (result.error != null)
|
||||
@@ -461,6 +437,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -461,6 +426,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
removeUselessFiles(requestCode, imageConfig);
|
||||
responseHelper.invokeError(callback, result.error.getMessage());
|
||||
callback = null;
|
||||
@@ -209,7 +199,7 @@ index 48fb5c1..3872d91 100644
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,7 +449,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -472,7 +438,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
updatedResultResponse(uri, imageConfig.original.getAbsolutePath());
|
||||
|
||||
// don't create a new file if contraint are respected
|
||||
@@ -218,7 +208,7 @@ index 48fb5c1..3872d91 100644
|
||||
{
|
||||
responseHelper.putInt("width", initialWidth);
|
||||
responseHelper.putInt("height", initialHeight);
|
||||
@@ -481,6 +458,14 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -481,6 +447,13 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
else
|
||||
{
|
||||
imageConfig = getResizedImage(reactContext, this.options, imageConfig, initialWidth, initialHeight, requestCode);
|
||||
@@ -229,11 +219,10 @@ index 48fb5c1..3872d91 100644
|
||||
+ this.options = null;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (imageConfig.resized == null)
|
||||
{
|
||||
removeUselessFiles(requestCode, imageConfig);
|
||||
@@ -523,6 +508,64 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -523,6 +496,61 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
this.options = null;
|
||||
}
|
||||
|
||||
@@ -269,15 +258,12 @@ index 48fb5c1..3872d91 100644
|
||||
+ case REQUEST_LAUNCH_IMAGE_CAPTURE:
|
||||
+ extractImageFromResult(activity, cameraCaptureURI, requestCode);
|
||||
+ break;
|
||||
+
|
||||
+ case REQUEST_LAUNCH_IMAGE_LIBRARY:
|
||||
+ extractImageFromResult(activity, data.getData(), requestCode);
|
||||
+ break;
|
||||
+
|
||||
+ case REQUEST_LAUNCH_VIDEO_LIBRARY:
|
||||
+ extractVideoFromResult(data.getData());
|
||||
+ break;
|
||||
+
|
||||
+ case REQUEST_LAUNCH_MIXED_CAPTURE:
|
||||
+ case REQUEST_LAUNCH_VIDEO_CAPTURE:
|
||||
+ if (data == null || data.getData() == null) {
|
||||
@@ -298,7 +284,7 @@ index 48fb5c1..3872d91 100644
|
||||
public void invokeCustomButton(@NonNull final String action)
|
||||
{
|
||||
responseHelper.invokeCustomButton(this.callback, action);
|
||||
@@ -551,7 +594,8 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -551,7 +579,8 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
{
|
||||
return callback == null || (cameraCaptureURI == null && requestCode == REQUEST_LAUNCH_IMAGE_CAPTURE)
|
||||
|| (requestCode != REQUEST_LAUNCH_IMAGE_CAPTURE && requestCode != REQUEST_LAUNCH_IMAGE_LIBRARY
|
||||
@@ -308,7 +294,7 @@ index 48fb5c1..3872d91 100644
|
||||
}
|
||||
|
||||
private void updatedResultResponse(@Nullable final Uri uri,
|
||||
@@ -571,22 +615,23 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -571,22 +600,24 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@NonNull final Callback callback,
|
||||
@NonNull final int requestCode)
|
||||
{
|
||||
@@ -318,21 +304,21 @@ index 48fb5c1..3872d91 100644
|
||||
- .checkSelfPermission(activity, Manifest.permission.CAMERA);
|
||||
-
|
||||
- boolean permissionsGranted = false;
|
||||
-
|
||||
|
||||
+ int selfCheckResult = 0;
|
||||
switch (requestCode) {
|
||||
case REQUEST_PERMISSIONS_FOR_LIBRARY:
|
||||
- permissionsGranted = writePermission == PackageManager.PERMISSION_GRANTED;
|
||||
+ selfCheckResult = ActivityCompat
|
||||
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
break;
|
||||
case REQUEST_PERMISSIONS_FOR_CAMERA:
|
||||
- permissionsGranted = cameraPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;
|
||||
+ selfCheckResult = ActivityCompat
|
||||
+ .checkSelfPermission(activity, Manifest.permission.CAMERA);
|
||||
+ .checkSelfPermission(activity, Manifest.permission.CAMERA);
|
||||
+ if (selfCheckResult == PackageManager.PERMISSION_GRANTED) {
|
||||
+ selfCheckResult = ActivityCompat
|
||||
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
@@ -341,42 +327,52 @@ index 48fb5c1..3872d91 100644
|
||||
if (!permissionsGranted)
|
||||
{
|
||||
final Boolean dontAskAgain = ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA);
|
||||
@@ -787,4 +832,22 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
@@ -787,4 +818,21 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
|
||||
videoDurationLimit = options.getInt("durationLimit");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ private void setImageCaptureUri(Intent cameraIntent) {
|
||||
+ final File original = createNewFile(reactContext, this.options, false);
|
||||
+ imageConfig = imageConfig.withOriginalFile(original);
|
||||
+ imageConfig = imageConfig.withOriginalFile(original);
|
||||
+
|
||||
+ if (imageConfig.original != null) {
|
||||
+ cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
|
||||
+ }else {
|
||||
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
|
||||
+ return;
|
||||
+ }
|
||||
+ if (cameraCaptureURI == null)
|
||||
+ {
|
||||
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
|
||||
+ return;
|
||||
+ }
|
||||
+ cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraCaptureURI);
|
||||
+ if (imageConfig.original != null) {
|
||||
+ cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
|
||||
+ } else {
|
||||
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
|
||||
+ return;
|
||||
+ }
|
||||
+ if (cameraCaptureURI == null) {
|
||||
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
|
||||
+ return;
|
||||
+ }
|
||||
+ cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraCaptureURI);
|
||||
+ }
|
||||
}
|
||||
diff --git a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/utils/RealPathUtil.java b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/utils/RealPathUtil.java
|
||||
index cc90dce..c1cc74d 100644
|
||||
index cc90dce..72ddc92 100644
|
||||
--- a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/utils/RealPathUtil.java
|
||||
+++ b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/utils/RealPathUtil.java
|
||||
@@ -7,16 +7,22 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@@ -1,201 +1,270 @@
|
||||
package com.imagepicker.utils;
|
||||
|
||||
-import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
-import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
-import android.content.ContentUris;
|
||||
+import android.provider.OpenableColumns;
|
||||
import android.content.ContentUris;
|
||||
+import android.content.ContentResolver;
|
||||
import android.os.Environment;
|
||||
+import android.os.ParcelFileDescriptor;
|
||||
+import android.webkit.MimeTypeMap;
|
||||
+import android.util.Log;
|
||||
+import android.text.TextUtils;
|
||||
+
|
||||
+import android.os.ParcelFileDescriptor;
|
||||
+
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
@@ -384,93 +380,432 @@ index cc90dce..c1cc74d 100644
|
||||
-import java.io.File;
|
||||
+import java.io.*;
|
||||
+import java.nio.channels.FileChannel;
|
||||
+import java.util.Objects;
|
||||
+
|
||||
+// Class based on the steveevers DocumentHelper https://gist.github.com/steveevers/a5af24c226f44bb8fdc3
|
||||
|
||||
public class RealPathUtil {
|
||||
|
||||
+ public static final String CACHE_DIR_NAME = "mmShare";
|
||||
+ public static final String CACHE_DIR_NAME = "mmShare";
|
||||
+
|
||||
public static @Nullable Uri compatUriFromFile(@NonNull final Context context,
|
||||
@NonNull final File file) {
|
||||
Uri result = null;
|
||||
@@ -58,12 +64,7 @@ public class RealPathUtil {
|
||||
}
|
||||
// DownloadsProvider
|
||||
else if (isDownloadsDocument(uri)) {
|
||||
+ public static @Nullable
|
||||
+ Uri compatUriFromFile(@NonNull final Context context,
|
||||
+ @NonNull final File file) {
|
||||
+ Uri result = null;
|
||||
+ final String packageName = context.getApplicationContext().getPackageName();
|
||||
+ final String authority = packageName + ".provider";
|
||||
+ try {
|
||||
+ result = FileProvider.getUriForFile(context, authority, file);
|
||||
+ }
|
||||
+ catch(IllegalArgumentException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ public static String getRealPathFromURI(final Context context, final Uri uri) {
|
||||
+
|
||||
+ // DocumentProvider
|
||||
+ if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
+ // ExternalStorageProvider
|
||||
+ if (isExternalStorageDocument(uri)) {
|
||||
+ final String docId = DocumentsContract.getDocumentId(uri);
|
||||
+ final String[] split = docId.split(":");
|
||||
+ final String type = split[0];
|
||||
+
|
||||
+ if ("primary".equalsIgnoreCase(type)) {
|
||||
+ return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
+ }
|
||||
+ } else if (isDownloadsDocument(uri)) {
|
||||
+ // DownloadsProvider
|
||||
+
|
||||
+ final String id = DocumentsContract.getDocumentId(uri);
|
||||
+ if (!TextUtils.isEmpty(id)) {
|
||||
+ if (id.startsWith("raw:")) {
|
||||
+ return id.replaceFirst("raw:", "");
|
||||
+ }
|
||||
+ try {
|
||||
+ return getPathFromSavingTempFile(context, uri);
|
||||
+ } catch (NumberFormatException e) {
|
||||
+ Log.e("ReactNative", "DownloadsProvider unexpected uri " + uri.toString());
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (isMediaDocument(uri)) {
|
||||
+ // MediaProvider
|
||||
+
|
||||
+ final String docId = DocumentsContract.getDocumentId(uri);
|
||||
+ final String[] split = docId.split(":");
|
||||
+ final String type = split[0];
|
||||
+
|
||||
+ Uri contentUri = null;
|
||||
+ if ("image".equals(type)) {
|
||||
+ contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
+ } else if ("video".equals(type)) {
|
||||
+ contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
+ } else if ("audio".equals(type)) {
|
||||
+ contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
+ }
|
||||
+
|
||||
+ final String selection = "_id=?";
|
||||
+ final String[] selectionArgs = new String[] {
|
||||
+ split[1]
|
||||
+ };
|
||||
+
|
||||
+ if (contentUri != null) {
|
||||
+ return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
+ } else {
|
||||
+ return getPathFromSavingTempFile(context, uri);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
+ // MediaStore (and general)
|
||||
+
|
||||
+ if (isGooglePhotosUri(uri)) {
|
||||
+ return uri.getLastPathSegment();
|
||||
+ }
|
||||
+
|
||||
+ // Try save to tmp file, and return tmp file path
|
||||
+ return getPathFromSavingTempFile(context, uri);
|
||||
+ } else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
+ return uri.getPath();
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ public static String getPathFromSavingTempFile(Context context, final Uri uri) {
|
||||
+ File tmpFile;
|
||||
+ String fileName = null;
|
||||
+
|
||||
+ if (uri == null || uri.isRelative()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ // Try and get the filename from the Uri
|
||||
+ try {
|
||||
+ Cursor returnCursor =
|
||||
+ context.getContentResolver().query(uri, null, null, null, null);
|
||||
+ int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
+ returnCursor.moveToFirst();
|
||||
+ fileName = sanitizeFilename(returnCursor.getString(nameIndex));
|
||||
+ returnCursor.close();
|
||||
+
|
||||
+ } catch (Exception e) {
|
||||
+ // just continue to get the filename with the last segment of the path
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ if (TextUtils.isEmpty(fileName)) {
|
||||
+ fileName = sanitizeFilename(uri.getLastPathSegment().trim());
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ File cacheDir = new File(context.getCacheDir(), CACHE_DIR_NAME);
|
||||
+ if (!cacheDir.exists()) {
|
||||
+ cacheDir.mkdirs();
|
||||
+ }
|
||||
+
|
||||
+ tmpFile = new File(cacheDir, fileName);
|
||||
+ tmpFile.createNewFile();
|
||||
+
|
||||
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
|
||||
+
|
||||
+ FileChannel src = new FileInputStream(pfd.getFileDescriptor()).getChannel();
|
||||
+ FileChannel dst = new FileOutputStream(tmpFile).getChannel();
|
||||
+ dst.transferFrom(src, 0, src.size());
|
||||
+ src.close();
|
||||
+ dst.close();
|
||||
+ } catch (IOException ex) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return tmpFile.getAbsolutePath();
|
||||
+ }
|
||||
+
|
||||
+ public static String getDataColumn(Context context, Uri uri, String selection,
|
||||
+ String[] selectionArgs) {
|
||||
+
|
||||
+ Cursor cursor = null;
|
||||
+ final String column = "_data";
|
||||
+ final String[] projection = {
|
||||
+ column
|
||||
+ };
|
||||
+
|
||||
+ try {
|
||||
+ cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
||||
+ null);
|
||||
+ if (cursor != null && cursor.moveToFirst()) {
|
||||
+ final int index = cursor.getColumnIndexOrThrow(column);
|
||||
+ return cursor.getString(index);
|
||||
+ }
|
||||
+ } finally {
|
||||
+ if (cursor != null)
|
||||
+ cursor.close();
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ public static boolean isExternalStorageDocument(Uri uri) {
|
||||
+ return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isDownloadsDocument(Uri uri) {
|
||||
+ return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isMediaDocument(Uri uri) {
|
||||
+ return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isGooglePhotosUri(Uri uri) {
|
||||
+ return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
||||
+ }
|
||||
+
|
||||
+ public static String getExtension(String uri) {
|
||||
+ if (uri == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ int dot = uri.lastIndexOf(".");
|
||||
+ if (dot >= 0) {
|
||||
+ return uri.substring(dot);
|
||||
+ } else {
|
||||
+ // No extension.
|
||||
+ return "";
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static String getMimeType(File file) {
|
||||
+
|
||||
+ String extension = getExtension(file.getName());
|
||||
+
|
||||
+ if (extension.length() > 0)
|
||||
+ return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));
|
||||
+
|
||||
+ return "application/octet-stream";
|
||||
+ }
|
||||
+
|
||||
+ public static String getMimeType(String filePath) {
|
||||
+ File file = new File(filePath);
|
||||
+ return getMimeType(file);
|
||||
+ }
|
||||
+
|
||||
+ public static String getMimeTypeFromUri(final Context context, final Uri uri) {
|
||||
+ try {
|
||||
+ ContentResolver cR = context.getContentResolver();
|
||||
+ return cR.getType(uri);
|
||||
+ } catch (Exception e) {
|
||||
+ return "application/octet-stream";
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void deleteTempFiles(final File dir) {
|
||||
+ try {
|
||||
+ if (dir.isDirectory()) {
|
||||
+ deleteRecursive(dir);
|
||||
+ }
|
||||
+ } catch (Exception e) {
|
||||
+ // do nothing
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void deleteRecursive(File fileOrDirectory) {
|
||||
+ if (fileOrDirectory.isDirectory())
|
||||
+ for (File child : Objects.requireNonNull(fileOrDirectory.listFiles()))
|
||||
+ deleteRecursive(child);
|
||||
+
|
||||
+ fileOrDirectory.delete();
|
||||
+ }
|
||||
+
|
||||
+ private static String sanitizeFilename(String filename) {
|
||||
+ if (filename == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
|
||||
- public static @Nullable Uri compatUriFromFile(@NonNull final Context context,
|
||||
- @NonNull final File file) {
|
||||
- Uri result = null;
|
||||
- if (Build.VERSION.SDK_INT < 21) {
|
||||
- result = Uri.fromFile(file);
|
||||
- }
|
||||
- else {
|
||||
- final String packageName = context.getApplicationContext().getPackageName();
|
||||
- final String authority = new StringBuilder(packageName).append(".provider").toString();
|
||||
- try {
|
||||
- result = FileProvider.getUriForFile(context, authority, file);
|
||||
- }
|
||||
- catch(IllegalArgumentException e) {
|
||||
- e.printStackTrace();
|
||||
- }
|
||||
- }
|
||||
- return result;
|
||||
- }
|
||||
-
|
||||
- @SuppressLint("NewApi")
|
||||
- public static @Nullable String getRealPathFromURI(@NonNull final Context context,
|
||||
- @NonNull final Uri uri) {
|
||||
-
|
||||
- final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
-
|
||||
- // DocumentProvider
|
||||
- if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
- // ExternalStorageProvider
|
||||
- if (isExternalStorageDocument(uri)) {
|
||||
- final String docId = DocumentsContract.getDocumentId(uri);
|
||||
- final String[] split = docId.split(":");
|
||||
- final String type = split[0];
|
||||
-
|
||||
- if ("primary".equalsIgnoreCase(type)) {
|
||||
- return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
- }
|
||||
-
|
||||
- // TODO handle non-primary volumes
|
||||
- }
|
||||
- // DownloadsProvider
|
||||
- else if (isDownloadsDocument(uri)) {
|
||||
-
|
||||
- final String id = DocumentsContract.getDocumentId(uri);
|
||||
- final Uri contentUri = ContentUris.withAppendedId(
|
||||
- Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
||||
-
|
||||
- return getDataColumn(context, contentUri, null, null);
|
||||
+ return getPathFromSavingTempFile(context, uri);
|
||||
}
|
||||
// MediaProvider
|
||||
else if (isMediaDocument(uri)) {
|
||||
@@ -89,7 +90,7 @@ public class RealPathUtil {
|
||||
}
|
||||
}
|
||||
// MediaStore (and general)
|
||||
- }
|
||||
- // MediaProvider
|
||||
- else if (isMediaDocument(uri)) {
|
||||
- final String docId = DocumentsContract.getDocumentId(uri);
|
||||
- final String[] split = docId.split(":");
|
||||
- final String type = split[0];
|
||||
-
|
||||
- Uri contentUri = null;
|
||||
- if ("image".equals(type)) {
|
||||
- contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
- } else if ("video".equals(type)) {
|
||||
- contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
- } else if ("audio".equals(type)) {
|
||||
- contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
- }
|
||||
-
|
||||
- final String selection = "_id=?";
|
||||
- final String[] selectionArgs = new String[] {
|
||||
- split[1]
|
||||
- };
|
||||
-
|
||||
- return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
- }
|
||||
- }
|
||||
- // MediaStore (and general)
|
||||
- else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
+ if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
|
||||
// Return the remote address
|
||||
if (isGooglePhotosUri(uri))
|
||||
@@ -98,7 +99,7 @@ public class RealPathUtil {
|
||||
if (isFileProviderUri(context, uri))
|
||||
return getFileProviderPath(context, uri);
|
||||
|
||||
-
|
||||
- // Return the remote address
|
||||
- if (isGooglePhotosUri(uri))
|
||||
- return uri.getLastPathSegment();
|
||||
-
|
||||
- if (isFileProviderUri(context, uri))
|
||||
- return getFileProviderPath(context, uri);
|
||||
-
|
||||
- return getDataColumn(context, uri, null, null);
|
||||
+ return getPathFromSavingTempFile(context, uri);
|
||||
}
|
||||
// File
|
||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
@@ -108,6 +109,49 @@ public class RealPathUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
+
|
||||
+ public static String getPathFromSavingTempFile(Context context, final Uri uri) {
|
||||
+ File tmpFile;
|
||||
+ String fileName = null;
|
||||
+
|
||||
+ // Try and get the filename from the Uri
|
||||
+ try {
|
||||
+ Cursor returnCursor =
|
||||
+ context.getContentResolver().query(uri, null, null, null, null);
|
||||
+ int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
+ returnCursor.moveToFirst();
|
||||
+ fileName = returnCursor.getString(nameIndex);
|
||||
+ } catch (Exception e) {
|
||||
+ // just continue to get the filename with the last segment of the path
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ if (fileName == null) {
|
||||
+ fileName = uri.getLastPathSegment().toString().trim();
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ File cacheDir = new File(context.getCacheDir(), CACHE_DIR_NAME);
|
||||
+ if (!cacheDir.exists()) {
|
||||
+ cacheDir.mkdirs();
|
||||
+ }
|
||||
+
|
||||
+ tmpFile = new File(cacheDir, fileName);
|
||||
+ tmpFile.createNewFile();
|
||||
+
|
||||
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
|
||||
+
|
||||
+ FileChannel src = new FileInputStream(pfd.getFileDescriptor()).getChannel();
|
||||
+ FileChannel dst = new FileOutputStream(tmpFile).getChannel();
|
||||
+ dst.transferFrom(src, 0, src.size());
|
||||
+ src.close();
|
||||
+ dst.close();
|
||||
+ } catch (IOException ex) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return tmpFile.getAbsolutePath();
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Get the value of the data column for this Uri. This is useful for
|
||||
* MediaStore Uris, and other file-based ContentProviders.
|
||||
- }
|
||||
- // File
|
||||
- else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
- return uri.getPath();
|
||||
- }
|
||||
-
|
||||
- return null;
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * Get the value of the data column for this Uri. This is useful for
|
||||
- * MediaStore Uris, and other file-based ContentProviders.
|
||||
- *
|
||||
- * @param context The context.
|
||||
- * @param uri The Uri to query.
|
||||
- * @param selection (Optional) Filter used in the query.
|
||||
- * @param selectionArgs (Optional) Selection arguments used in the query.
|
||||
- * @return The value of the _data column, which is typically a file path.
|
||||
- */
|
||||
- public static String getDataColumn(Context context, Uri uri, String selection,
|
||||
- String[] selectionArgs) {
|
||||
-
|
||||
- Cursor cursor = null;
|
||||
- final String column = "_data";
|
||||
- final String[] projection = {
|
||||
- column
|
||||
- };
|
||||
-
|
||||
- try {
|
||||
- cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
||||
- null);
|
||||
- if (cursor != null && cursor.moveToFirst()) {
|
||||
- final int index = cursor.getColumnIndexOrThrow(column);
|
||||
- return cursor.getString(index);
|
||||
- }
|
||||
- } finally {
|
||||
- if (cursor != null)
|
||||
- cursor.close();
|
||||
- }
|
||||
- return null;
|
||||
- }
|
||||
-
|
||||
-
|
||||
- /**
|
||||
- * @param uri The Uri to check.
|
||||
- * @return Whether the Uri authority is ExternalStorageProvider.
|
||||
- */
|
||||
- public static boolean isExternalStorageDocument(Uri uri) {
|
||||
- return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * @param uri The Uri to check.
|
||||
- * @return Whether the Uri authority is DownloadsProvider.
|
||||
- */
|
||||
- public static boolean isDownloadsDocument(Uri uri) {
|
||||
- return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * @param uri The Uri to check.
|
||||
- * @return Whether the Uri authority is MediaProvider.
|
||||
- */
|
||||
- public static boolean isMediaDocument(Uri uri) {
|
||||
- return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * @param uri The Uri to check.
|
||||
- * @return Whether the Uri authority is Google Photos.
|
||||
- */
|
||||
- public static boolean isGooglePhotosUri(@NonNull final Uri uri) {
|
||||
- return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * @param context The Application context
|
||||
- * @param uri The Uri is checked by functions
|
||||
- * @return Whether the Uri authority is FileProvider
|
||||
- */
|
||||
- public static boolean isFileProviderUri(@NonNull final Context context,
|
||||
- @NonNull final Uri uri) {
|
||||
- final String packageName = context.getPackageName();
|
||||
- final String authority = new StringBuilder(packageName).append(".provider").toString();
|
||||
- return authority.equals(uri.getAuthority());
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * @param context The Application context
|
||||
- * @param uri The Uri is checked by functions
|
||||
- * @return File path or null if file is missing
|
||||
- */
|
||||
- public static @Nullable String getFileProviderPath(@NonNull final Context context,
|
||||
- @NonNull final Uri uri)
|
||||
- {
|
||||
- final File appDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
|
||||
- final File file = new File(appDir, uri.getLastPathSegment());
|
||||
- return file.exists() ? file.toString(): null;
|
||||
- }
|
||||
+ File f = new File(filename);
|
||||
+ return f.getName();
|
||||
+ }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user