'Get file size using URI in android
I am working on android video application where I am recording a Video using Camera Intent and taking a video from gallery. When recording video or after selecting video from gallery I want to know the size of my video which I took. I want to make a logic to show a user a toast message if selected Video size is greater then 5MB. I made the bottom logic which is not working and giving me 0 value where I tried to take the size from URI.
Thanks in advance.
My Logic which is not working
java.net.URI juri = new java.net.URI(uri.toString());
File mediaFile = new File(juri.getPath());
long fileSizeInBytes = mediaFile.length();
long fileSizeInKB = fileSizeInBytes / 1024;
long fileSizeInMB = fileSizeInKB / 1024;
if (fileSizeInMB > 5) {
Toast.makeText(this,"Video files lesser than 5MB are allowed",Toast.LENGTH_LONG).show();
return;
}
This is my code which I am using to get video from Gallery and to record video.
public void takeVideoFromCamera(){
File mediaFile =new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/myvideo.mp4");
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri videoUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// videoUri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", mediaFile);
videoUri = FileProvider.getUriForFile(this, "i.am.ce.by.ncy.provider", mediaFile);
} else {
videoUri = Uri.fromFile(mediaFile);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 5491520L);//5*1048*1048=5MB
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT,45);
startActivityForResult(intent, VIDEO_CAPTURE);
}
public void takeVideoFromGallery(){
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
long maxVideoSize = 5 * 1024 * 1024; // 10 MB
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, maxVideoSize);
startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO);
}
onActivityResult code
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_OK) {
switch (requestCode) {
case VIDEO_CAPTURE:
if (resultCode == RESULT_OK) {
showVideoImage(data.getData());
// Here I want to know what is the size of my Video File
}
break;
case REQUEST_TAKE_GALLERY_VIDEO:
if (resultCode == RESULT_OK) {
showVideoGallery(data);
// Here I want to know what is the size of my Video File
}
break;
}
Solution 1:[1]
- Checks
AssetFileDescriptor.length
- If not found, checks
ParcelFileDescriptor.getStatSize
implicitly insideAssetFileDescriptor.length
- If not found, check
MediaStore/ContentResolver
if URI hascontent://
scheme
Should work for file://
, content://
schemes. Returns -1L
if failed to find:
fun Uri.length(contentResolver: ContentResolver)
: Long {
val assetFileDescriptor = try {
contentResolver.openAssetFileDescriptor(this, "r")
} catch (e: FileNotFoundException) {
null
}
// uses ParcelFileDescriptor#getStatSize underneath if failed
val length = assetFileDescriptor?.use { it.length } ?: -1L
if (length != -1L) {
return length
}
// if "content://" uri scheme, try contentResolver table
if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
return contentResolver.query(this, arrayOf(OpenableColumns.SIZE), null, null, null)
?.use { cursor ->
// maybe shouldn't trust ContentResolver for size: https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
if (sizeIndex == -1) {
return@use -1L
}
cursor.moveToFirst()
return try {
cursor.getLong(sizeIndex)
} catch (_: Throwable) {
-1L
}
} ?: -1L
} else {
return -1L
}
}
Solution 2:[2]
AssetFileDescriptor fileDescriptor = getApplicationContext().getContentResolver().openAssetFileDescriptor(uri , "r");
long fileSize = fileDescriptor.getLength();
Solution 3:[3]
java.net.URI juri = new java.net.URI(uri.toString());
File mediaFile = new File(juri.getPath());
A Uri
is not a File
.
showVideoImage(data.getData());
ACTION_VIDEO_CAPTURE
does not return a Uri
.
Moreover, you already know where the file is. You create a File
object in takeVideoFromCamera()
and use that for EXTRA_OUTPUT
. Hold onto that File
object (and also save it in the saved instance state Bundle
), then use that for finding out the size of the resulting video.
Solution 4:[4]
private long getFileSize(Uri fileUri) {
Cursor returnCursor = getContentResolver().
query(fileUri, null, null, null, null);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
long size = returnCursor.getLong(sizeIndex);
returnCursor.close();
return size;
}
Check here for more details
Solution 5:[5]
This is working for me:
Uri path = data.getData();
Cursor returnCursor = getContentResolver().
query(path, null, null, null, null);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
int size = returnCursor.getInt(sizeIndex) / 1000;
returnCursor.close();
tv_description.setText("size: " + size);
You Can use getInt, getLong etc...
Solution 6:[6]
Following extension function supports 3 different URI types,
- Content URI
content://document/primary:sample.png
- File URI
file://data/user/0/com.example.testapp/cache/output.png
- Resource URI
"android.resource://com.example.testapp/" + R.raw.sample
fun Uri.length(context: Context): Long {
val fromContentProviderColumn = fun(): Long {
// Try to get content length from the content provider column OpenableColumns.SIZE
// which is recommended to implement by all the content providers
var cursor: Cursor? = null
return try {
cursor = context.contentResolver.query(
this,
arrayOf(OpenableColumns.SIZE),
null,
null,
null
) ?: throw Exception("Content provider returned null or crashed")
val sizeColumnIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
if (sizeColumnIndex != -1 && cursor.count > 0) {
cursor.moveToFirst()
cursor.getLong(sizeColumnIndex)
} else {
-1
}
} catch (e: Exception) {
Log.d(TAG, e.message ?: e.javaClass.simpleName)
-1
} finally {
cursor?.close()
}
}
val fromFileDescriptor = fun(): Long {
// Try to get content length from content scheme uri or file scheme uri
var fileDescriptor: ParcelFileDescriptor? = null
return try {
fileDescriptor = context.contentResolver.openFileDescriptor(this, "r")
?: throw Exception("Content provider recently crashed")
fileDescriptor.statSize
} catch (e: Exception) {
Log.d(TAG, e.message ?: e.javaClass.simpleName)
-1
} finally {
fileDescriptor?.close()
}
}
val fromAssetFileDescriptor = fun(): Long {
// Try to get content length from content scheme uri, file scheme uri or android resource scheme uri
var assetFileDescriptor: AssetFileDescriptor? = null
return try {
assetFileDescriptor = context.contentResolver.openAssetFileDescriptor(this, "r")
?: throw Exception("Content provider recently crashed")
assetFileDescriptor.length
} catch (e: Exception) {
Log.d(TAG, e.message ?: e.javaClass.simpleName)
-1
} finally {
assetFileDescriptor?.close()
}
}
return when (scheme) {
ContentResolver.SCHEME_FILE -> {
fromFileDescriptor()
}
ContentResolver.SCHEME_CONTENT -> {
val length = fromContentProviderColumn()
if (length >= 0) {
length
} else {
fromFileDescriptor()
}
}
ContentResolver.SCHEME_ANDROID_RESOURCE -> {
fromAssetFileDescriptor()
}
else -> {
-1
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jemshit Iskenderov |
Solution 2 | Markus Rollmann |
Solution 3 | CommonsWare |
Solution 4 | EpicPandaForce |
Solution 5 | EpicPandaForce |
Solution 6 | UdaraWanasinghe |