'Check if a file is an image or a video

Is there a way to check if the file I'm loading as a URI is a image or a video in android? I'm trying to dynamically loaded both images and videos into fragments for a list/detail view and need to tell them apart.



Solution 1:[1]

I'd check the mimeType and then check if it corresponds to an image or video.

A full example, for checking if a filepath is an image, would be:

public static boolean isImageFile(String path) {
    String mimeType = URLConnection.guessContentTypeFromName(path);
    return mimeType != null && mimeType.startsWith("image");
}

And for video:

public static boolean isVideoFile(String path) {
    String mimeType = URLConnection.guessContentTypeFromName(path);
    return mimeType != null && mimeType.startsWith("video");
}

Solution 2:[2]

If you are getting your Uri from a content resolver you can get the mime type using getType(Uri);

ContentResolver cR = context.getContentResolver();
String type = cR.getType(uri); 

should get back something similar to "image/jpeg" which you can check against for your display logic.

Solution 3:[3]

It seems most proper to check type via ContentResolver (as in jsrssoftware answer). Although, this may return null in some cases.

In such case, I ended up trying to decode stream as Bitmap to confirm it is in image (but only decoding bounds, so it's quite fast and not much memory-consuming).

My image-tester helper function looks like this:

public static boolean checkIsImage(Context context, Uri uri) {
    ContentResolver contentResolver = context.getContentResolver();
    String type = contentResolver.getType(uri);
    if (type != null) {
        return  type.startsWith("image/");
    } else {
        // try to decode as image (bounds only)
        InputStream inputStream = null;
        try {
            inputStream = contentResolver.openInputStream(uri);
            if (inputStream != null) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(inputStream, null, options);
                return options.outWidth > 0 && options.outHeight > 0;
            }
        } catch (IOException e) {
            // ignore
        } finally {
            FileUtils.closeQuietly(inputStream);
        }
    }
    // default outcome if image not confirmed
    return false;
}

For videos, one could do similar approach. I did not need it, but I believe MediaMetadataRetriever could be used to verify if stream contains valid video in case type check fails.

Solution 4:[4]

enum class MediaType {
    MediaTypeImage,
    MediaTypeVideo,
    Unknown
}

fun getMediaType(context: Context, source: Uri): MediaType {
    val mediaTypeRaw = context.contentResolver.getType(source)
    if (mediaTypeRaw?.startsWith("image") == true)
        return MediaType.MediaTypeImage
    if (mediaTypeRaw?.startsWith("video") == true)
        return MediaType.MediaTypeVideo
    return MediaType.Unknown
}

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
Solution 2 metalmonkeysoftware
Solution 3 tpaczesny
Solution 4 Konstantin Konopko