From cfdb52cfff6581f45971e1ddd5903beb0ce0220e Mon Sep 17 00:00:00 2001 From: "gowtham.balamurugan" Date: Mon, 26 Jun 2023 22:46:01 +0530 Subject: [PATCH] fix: android 13 file path issues --- .../gowtham/videotrimmer/MainActivity.java | 5 - .../gowtham/library/ui/ActVideoTrimmer.java | 38 +- .../library/utils/FileCacheHandler.java | 63 +++ .../com/gowtham/library/utils/FileUtils.java | 408 ------------------ .../com/gowtham/library/utils/FileUtilsKt.kt | 51 ++- 5 files changed, 131 insertions(+), 434 deletions(-) create mode 100644 library/src/main/java/com/gowtham/library/utils/FileCacheHandler.java delete mode 100644 library/src/main/java/com/gowtham/library/utils/FileUtils.java diff --git a/app/src/main/java/com/gowtham/videotrimmer/MainActivity.java b/app/src/main/java/com/gowtham/videotrimmer/MainActivity.java index 3c7e822..3deddd6 100644 --- a/app/src/main/java/com/gowtham/videotrimmer/MainActivity.java +++ b/app/src/main/java/com/gowtham/videotrimmer/MainActivity.java @@ -13,23 +13,18 @@ import android.widget.Toast; import android.widget.VideoView; -import androidx.activity.result.ActivityResult; -import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.cocosw.bottomsheet.BottomSheet; import com.gowtham.library.utils.CompressOption; -import com.gowtham.library.utils.FileUtils; import com.gowtham.library.utils.LogMessage; import com.gowtham.library.utils.TrimType; import com.gowtham.library.utils.TrimVideo; -import com.gowtham.library.utils.TrimmerUtils; import java.io.File; diff --git a/library/src/main/java/com/gowtham/library/ui/ActVideoTrimmer.java b/library/src/main/java/com/gowtham/library/ui/ActVideoTrimmer.java index a37a904..4505634 100644 --- a/library/src/main/java/com/gowtham/library/ui/ActVideoTrimmer.java +++ b/library/src/main/java/com/gowtham/library/ui/ActVideoTrimmer.java @@ -53,7 +53,7 @@ import com.gowtham.library.ui.seekbar.widgets.CrystalSeekbar; import com.gowtham.library.utils.CompressOption; import com.gowtham.library.utils.CustomProgressView; -import com.gowtham.library.utils.FileUtils; +import com.gowtham.library.utils.FileUtilKt; import com.gowtham.library.utils.LocaleHelper; import com.gowtham.library.utils.LogMessage; import com.gowtham.library.utils.TrimVideo; @@ -83,7 +83,7 @@ public class ActVideoTrimmer extends LocalizationActivity { private Dialog dialog; - private Uri uri; + private Uri filePath; private TextView txtStartDuration, txtEndDuration; @@ -212,20 +212,20 @@ private void initPlayer() { private void setDataInView() { try { Runnable fileUriRunnable = () -> { - uri = Uri.parse(bundle.getString(TrimVideo.TRIM_VIDEO_URI)); -// String path = FileUtils.getPath(ActVideoTrimmer.this, uri); - String path=FileUtils.getRealPath(ActVideoTrimmer.this,uri); - uri = Uri.parse(path); + Uri uri = Uri.parse(bundle.getString(TrimVideo.TRIM_VIDEO_URI)); + String path= FileUtilKt.getValidatedFileUri(ActVideoTrimmer.this,uri); + filePath = Uri.parse(path); runOnUiThread(() -> { LogMessage.v("VideoUri:: " + uri); + LogMessage.v("VideoPath:: " + filePath); progressBar.setVisibility(View.GONE); - totalDuration = TrimmerUtils.getDuration(ActVideoTrimmer.this, uri); + totalDuration = TrimmerUtils.getDuration(ActVideoTrimmer.this, filePath); imagePlayPause.setOnClickListener(v -> onVideoClicked()); Objects.requireNonNull(playerView.getVideoSurfaceView()).setOnClickListener(v -> onVideoClicked()); initTrimData(); - buildMediaSource(uri); + buildMediaSource(); loadThumbnails(); setUpSeekBar(); }); @@ -282,10 +282,10 @@ private void seekTo(long sec) { videoPlayer.seekTo(sec * 1000); } - private void buildMediaSource(Uri mUri) { + private void buildMediaSource() { try { DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this); - MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(mUri)); + MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(filePath)); videoPlayer.addMediaSource(mediaSource); videoPlayer.prepare(); videoPlayer.setPlayWhenReady(true); @@ -505,7 +505,7 @@ private void trimVideo() { //not exceed given maxDuration if has given outputPath = getFileName(); LogMessage.v("outputPath::" + outputPath + new File(outputPath).exists()); - LogMessage.v("sourcePath::" + uri); + LogMessage.v("sourcePath::" + filePath); videoPlayer.setPlayWhenReady(false); showProcessingDialog(); String[] complexCommand; @@ -520,7 +520,7 @@ else if (isAccurateCut) { //fastest trimming command however, result duration //will be low accurate(2-3 secs) complexCommand = new String[]{"-ss", TrimmerUtils.formatCSeconds(lastMinValue), - "-i", String.valueOf(uri), + "-i", String.valueOf(filePath), "-t", TrimmerUtils.formatCSeconds(lastMaxValue - lastMinValue), "-async", "1", "-strict", "-2", "-c", "copy", outputPath}; @@ -543,18 +543,18 @@ private String getFileName() { if (fileName != null && !fileName.isEmpty()) fName = fileName; File newFile = new File(path + File.separator + - (fName) + fileDateTime + "." + TrimmerUtils.getFileExtension(this, uri)); + (fName) + fileDateTime + "." + TrimmerUtils.getFileExtension(this, filePath)); return String.valueOf(newFile); } private String[] getCompressionCmd() { MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); - metaRetriever.setDataSource(String.valueOf(uri)); + metaRetriever.setDataSource(String.valueOf(filePath)); String height = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); String width = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); int w = TrimmerUtils.clearNull(width).isEmpty() ? 0 : Integer.parseInt(width); int h = Integer.parseInt(height); - int rotation = TrimmerUtils.getVideoRotation(this, uri); + int rotation = TrimmerUtils.getVideoRotation(this, filePath); if (rotation == 90 || rotation == 270) { int temp = w; w = h; @@ -564,7 +564,7 @@ private String[] getCompressionCmd() { if (compressOption.getWidth() != 0 || compressOption.getHeight() != 0 || !compressOption.getBitRate().equals("0k")) { return new String[]{"-ss", TrimmerUtils.formatCSeconds(lastMinValue), - "-i", String.valueOf(uri), "-s", compressOption.getWidth() + "x" + + "-i", String.valueOf(filePath), "-s", compressOption.getWidth() + "x" + compressOption.getHeight(), "-r", String.valueOf(compressOption.getFrameRate()), "-vcodec", "mpeg4", "-b:v", @@ -577,7 +577,7 @@ else if (w >= 800) { w = w / 2; h = Integer.parseInt(height) / 2; return new String[]{"-ss", TrimmerUtils.formatCSeconds(lastMinValue), - "-i", String.valueOf(uri), + "-i", String.valueOf(filePath), "-s", w + "x" + h, "-r", "30", "-vcodec", "mpeg4", "-b:v", "1M", "-b:a", "48000", "-ac", "2", "-ar", "22050", @@ -585,7 +585,7 @@ else if (w >= 800) { TrimmerUtils.formatCSeconds(lastMaxValue - lastMinValue), outputPath}; } else { return new String[]{"-ss", TrimmerUtils.formatCSeconds(lastMinValue), - "-i", String.valueOf(uri), "-s", w + "x" + h, "-r", + "-i", String.valueOf(filePath), "-s", w + "x" + h, "-r", "30", "-vcodec", "mpeg4", "-b:v", "400K", "-b:a", "48000", "-ac", "2", "-ar", "22050", "-t", @@ -666,7 +666,7 @@ private void showLocationAlert() { private String[] getAccurateCmd() { return new String[]{"-ss", TrimmerUtils.formatCSeconds(lastMinValue) - , "-i", String.valueOf(uri), "-t", + , "-i", String.valueOf(filePath), "-t", TrimmerUtils.formatCSeconds(lastMaxValue - lastMinValue), "-async", "1", outputPath}; } diff --git a/library/src/main/java/com/gowtham/library/utils/FileCacheHandler.java b/library/src/main/java/com/gowtham/library/utils/FileCacheHandler.java new file mode 100644 index 0000000..a65575d --- /dev/null +++ b/library/src/main/java/com/gowtham/library/utils/FileCacheHandler.java @@ -0,0 +1,63 @@ +package com.gowtham.library.utils; + +import android.content.Context; +import android.util.Log; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +public class FileCacheHandler { + + public static String putFileInCache(Context context, InputStream fis) + { + + FileOutputStream fos=null; + try + { + File f=new File(context.getCacheDir(), "temp_video_file"); + if(f.exists()){ + f.delete(); + } + fos=new FileOutputStream(f); + CopyStream(fis,fos); + return f.getAbsolutePath(); + } + catch(Exception e) + { + LogMessage.e(Log.getStackTraceString(e)); + return ""; + } + finally + { + try + { + fos.flush(); + fos.close(); + } catch (Exception e) { + LogMessage.e(Log.getStackTraceString(e)); + } + } + } + + public static void CopyStream(InputStream is, OutputStream os) + { + final int buffer_size = 1024; + try { + + byte[] bytes = new byte[buffer_size]; + for (; ; ) { + + int count = is.read(bytes, 0, buffer_size); + if (count == -1) { + break; + } + os.write(bytes, 0, count); + os.flush(); + } + } catch (Exception ex) { + LogMessage.e(Log.getStackTraceString(ex)); + } + } +} diff --git a/library/src/main/java/com/gowtham/library/utils/FileUtils.java b/library/src/main/java/com/gowtham/library/utils/FileUtils.java deleted file mode 100644 index 0a8deef..0000000 --- a/library/src/main/java/com/gowtham/library/utils/FileUtils.java +++ /dev/null @@ -1,408 +0,0 @@ -package com.gowtham.library.utils; - -import android.annotation.SuppressLint; -import android.content.ContentUris; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.provider.DocumentsContract; -import android.provider.MediaStore; -import android.provider.OpenableColumns; -import android.text.TextUtils; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; - -public class FileUtils { - - public static String getRealPath(Context context,Uri uri) { - String[] projection = { MediaStore.Video.Media.DATA }; - Cursor cursor= context.getContentResolver().query( - uri,projection,null,null,null); - int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA); - cursor.moveToFirst(); - String path=cursor.getString(column_index); - cursor.close(); - if(path==null){ - path= FileUtilKt.getFileDataFromUriId(context, uri); - } - if(path==null) - return FileUtils.getPath(context, uri); - return path; - } - - @SuppressLint("NewApi") - public static String getPath(Context context, final Uri uri) { - boolean isKitkatOrAbove=Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - String selection = null; - String[] selectionArgs = null; - if (isKitkatOrAbove) { - if (isExternalStorageDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - String fullPath = getPathFromExtSD(split); - if (!fullPath.isEmpty()) { - return fullPath; - } else { - return null; - } - } - if (isDownloadsDocument(uri)) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - final String id; - Cursor cursor = null; - try { - cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null); - if (cursor != null && cursor.moveToFirst()) { - String fileName = cursor.getString(0); - String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName; - if (!TextUtils.isEmpty(path) && new File(path).exists()) { - return path; - }else{ - return copyFileToInternalStorage(context,uri,""); - } - } - } - finally { - if (cursor != null) { - cursor.close(); - } - } - id = DocumentsContract.getDocumentId(uri); - if (!TextUtils.isEmpty(id)) { - if (id.startsWith("raw:")) { - return id.replaceFirst("raw:", ""); - } - String[] contentUriPrefixesToTry = new String[]{ - "content://downloads/public_downloads", - "content://downloads/my_downloads" - }; - for (String contentUriPrefix : contentUriPrefixesToTry) { - try { - final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id)); - - - return getDataColumn(context, contentUri, null, null); - } catch (NumberFormatException e) { - //In Android 8 and Android P the id is not a number - return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", ""); - } - } - } - } - else { - final String id = DocumentsContract.getDocumentId(uri); - Uri contentUri=null; - if (id.startsWith("raw:")) { - return id.replaceFirst("raw:", ""); - } - try { - contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); - } - catch (NumberFormatException e) { - e.printStackTrace(); - } - if (contentUri != null) { - return getDataColumn(context, contentUri, null, null); - } - } - } - 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; - } - selection = "_id=?"; - selectionArgs = new String[]{split[1]}; - return getDataColumn(context, contentUri, selection, - selectionArgs); - } - - if (isGoogleDriveUri(uri)) { - return getDriveFilePath(context,uri); - } - - if(isWhatsAppFile(uri)){ - return getFilePathForWhatsApp(context,uri); - } - - - if ("content".equalsIgnoreCase(uri.getScheme())) { - - if (isGooglePhotosUri(uri)) { - return uri.getLastPathSegment(); - } - if (isGoogleDriveUri(uri)) { - return getDriveFilePath(context,uri); - } - if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) - { - // return getFilePathFromURI(context,uri); - return copyFileToInternalStorage(context,uri,""); - // return getRealPathFromURI(context,uri); - } - else - { - return getDataColumn(context, uri, null, null); - } - - } - if ("file".equalsIgnoreCase(uri.getScheme())) { - return uri.getPath(); - } - } - else { - - if(isWhatsAppFile(uri)){ - return getFilePathForWhatsApp(context,uri); - } - - if ("content".equalsIgnoreCase(uri.getScheme())) { - String[] projection = { - MediaStore.Images.Media.DATA - }; - Cursor cursor = null; - try { - cursor = context.getContentResolver() - .query(uri, projection, selection, selectionArgs, null); - int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); - if (cursor.moveToFirst()) { - return cursor.getString(column_index); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - return null; - } - - private static boolean fileExists(String filePath) { - File file = new File(filePath); - - return file.exists(); - } - - private static String getPathFromExtSD(String[] pathData) { - final String type = pathData[0]; - final String relativePath = "/" + pathData[1]; - String fullPath = ""; - - if ("primary".equalsIgnoreCase(type)) { - fullPath = Environment.getExternalStorageDirectory() + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - } - // Environment.isExternalStorageRemovable() is `true` for external and internal storage - // so we cannot relay on it. - // - // instead, for each possible path, check if file exists - // we'll start with secondary storage as this could be our (physically) removable sd card - fullPath = System.getenv("SECONDARY_STORAGE") + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - - fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - - return fullPath; - } - - private static String getDriveFilePath(Context context,Uri uri) { - Uri returnUri = uri; - Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); - /* - * Get the column indexes of the data in the Cursor, - * * move to the first row in the Cursor, get the data, - * * and display it. - * */ - int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); - returnCursor.moveToFirst(); - String name = (returnCursor.getString(nameIndex)); - String size = (Long.toString(returnCursor.getLong(sizeIndex))); - File file = new File(context.getCacheDir(), name); - try { - InputStream inputStream = context.getContentResolver().openInputStream(uri); - FileOutputStream outputStream = new FileOutputStream(file); - int read = 0; - int maxBufferSize = 1 * 1024 * 1024; - int bytesAvailable = inputStream.available(); - - //int bufferSize = 1024; - int bufferSize = Math.min(bytesAvailable, maxBufferSize); - - final byte[] buffers = new byte[bufferSize]; - while ((read = inputStream.read(buffers)) != -1) { - outputStream.write(buffers, 0, read); - } - Log.e("File Size", "Size " + file.length()); - inputStream.close(); - outputStream.close(); - Log.e("File Path", "Path " + file.getPath()); - Log.e("File Size", "Size " + file.length()); - } catch (Exception e) { - Log.e("Exception", e.getMessage()); - } - return file.getPath(); - } - - /*** - * Used for Android Q+ - * @param uri - * @param newDirName if you want to create a directory, you can set this variable - * @return - */ - public static String copyFileToInternalStorage(Context context,Uri uri,String newDirName) { - Uri returnUri = uri; - Cursor returnCursor = context.getContentResolver().query(returnUri, new String[]{ - OpenableColumns.DISPLAY_NAME,OpenableColumns.SIZE - }, null, null, null); - - /* - * Get the column indexes of the data in the Cursor, - * * move to the first row in the Cursor, get the data, - * * and display it. - * */ - int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); - returnCursor.moveToFirst(); - String name = "temp_file"; - String size = (Long.toString(returnCursor.getLong(sizeIndex))); - - File output; - if(!newDirName.equals("")) { - File dir = new File(context.getFilesDir() + "/" + newDirName); - if (!dir.exists()) { - dir.mkdir(); - } - output = new File(context.getFilesDir() + "/" + newDirName + "/" + name); - } - else{ - output = new File(context.getFilesDir() + "/" + name); - } - try { - InputStream inputStream = context.getContentResolver().openInputStream(uri); - FileOutputStream outputStream = new FileOutputStream(output); - int read = 0; - int bufferSize = 1024; - final byte[] buffers = new byte[bufferSize]; - while ((read = inputStream.read(buffers)) != -1) { - outputStream.write(buffers, 0, read); - } - - inputStream.close(); - outputStream.close(); - returnCursor.close(); - } - catch (Exception e) { - - Log.e("Exception", e.getMessage()); - } - - return output.getPath(); - } - - private static String getFilePathForWhatsApp(Context context,Uri uri){ - return copyFileToInternalStorage(context,uri,""); - } - - private 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; - } - - private static boolean isExternalStorageDocument(Uri uri) { - return "com.android.externalstorage.documents".equals(uri.getAuthority()); - } - - private static boolean isDownloadsDocument(Uri uri) { - return "com.android.providers.downloads.documents".equals(uri.getAuthority()); - } - - private static boolean isMediaDocument(Uri uri) { - return "com.android.providers.media.documents".equals(uri.getAuthority()); - } - - private static boolean isGooglePhotosUri(Uri uri) { - return "com.google.android.apps.photos.content".equals(uri.getAuthority()); - } - - public static boolean isWhatsAppFile(Uri uri){ - return "com.whatsapp.provider.media".equals(uri.getAuthority()); - } - - private static boolean isGoogleDriveUri(Uri uri) { - return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority()); - } - - public static void getAllVideos(Context context) { - Uri returnUri; - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) - returnUri= MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL); - else - returnUri=MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - - Cursor cursor= context.getContentResolver().query( - returnUri,new String[]{ - MediaStore.Video.Media._ID, - MediaStore.Video.Media.DISPLAY_NAME, - MediaStore.Video.Media.WIDTH, - MediaStore.Video.Media.HEIGHT, - },null,null,null); - - int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID); - int displayNameColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME); - int widthColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.WIDTH); - int heightColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.HEIGHT); - - while (cursor.moveToNext()){ - long id = cursor.getLong(idColumn); - String displayName = cursor.getString(displayNameColumn); - int width = cursor.getInt(widthColumn); - int height = cursor.getInt(heightColumn); - Uri contentUri = ContentUris.withAppendedId( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - id - ); - LogMessage.v("Video "+displayName+" contentUri "+contentUri); - } - } - -} diff --git a/library/src/main/java/com/gowtham/library/utils/FileUtilsKt.kt b/library/src/main/java/com/gowtham/library/utils/FileUtilsKt.kt index 0021897..2c4aa7e 100644 --- a/library/src/main/java/com/gowtham/library/utils/FileUtilsKt.kt +++ b/library/src/main/java/com/gowtham/library/utils/FileUtilsKt.kt @@ -4,14 +4,60 @@ import android.content.Context import android.database.Cursor import android.net.Uri import android.provider.MediaStore +import android.util.Log +import java.io.File object FileUtilKt { @JvmStatic - fun getFileDataFromUriId(context: Context, uri: Uri): String? { + fun getValidatedFileUri(context: Context, uri: Uri): String? { + val actualUri = getActualFileUri(context, uri) + return if (actualUri != null && File(actualUri).canRead()) + actualUri + else { + FileCacheHandler.putFileInCache(context, context.contentResolver.openInputStream(uri)) + } + } + + @JvmStatic + fun getActualFileUri(context: Context, uri: Uri): String? { + try { + val actualPath = getFileUriFromContentProvider(context, uri) + return if (actualPath != null) { + actualPath + } else { + val id = uri.path?.split(":")?.last() + id?.let { + val realUri = getFileUriFromContentProviderBySplit(context, id) + realUri + } + } + + } catch (e: Exception) { + LogMessage.e(Log.getStackTraceString(e)); + } + return null + } + + private fun getFileUriFromContentProvider(context: Context, uri: Uri): String? { + var cursor: Cursor? = null + try { + val proj = arrayOf(MediaStore.Video.Media.DATA) + cursor = context.contentResolver.query(uri, proj, null, null, null) + if (cursor != null) { + val columnIndex: Int = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA) + cursor.moveToFirst() + return cursor.getString(columnIndex) + } + return null + } finally { + cursor?.close() + } + } + + private fun getFileUriFromContentProviderBySplit(context: Context, id: String): String? { var cursor: Cursor? = null try { - val id = uri.path?.split(":")?.last() ?: return null val queryUri = MediaStore.Files.getContentUri("external") val projection = arrayOf( MediaStore.Files.FileColumns._ID, @@ -35,4 +81,5 @@ object FileUtilKt { cursor?.close() } } + } \ No newline at end of file