29

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.

user2532233
  • 831
  • 2
  • 9
  • 13

6 Answers6

88

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");
}
alfongj
  • 2,255
  • 1
  • 19
  • 23
  • Good answer. Would like to mention that the java String object has a .startsWith method which is a tad more readable than indexOf == 0. – clocksmith Oct 07 '16 at 03:21
  • 3
    This does not work, if the given path does not include an image extension. E.g. the Android Camera App may return a path like 'content://com.android.providers.media.documents/document/im‌​age%3A130', for which isImageFile() will return false. This seems to work: https://stackoverflow.com/a/31691791/1665966 – Johnson_145 Sep 27 '17 at 10:43
  • 1
    Bad answer, because video mime types cannot be handled by that code. The sources of the method URLConnection.guessContentTypeFromName(...) are here: https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-28/blob/master/java/net/URLConnection.java As you can see, only a minimum set of mime types is supported and no video mime type is included. The source code is the same of Oracle Java 13 and of OpenJDK. – Francesco Galgani Dec 22 '19 at 11:16
18

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.

  • 1
    that returned null for me, the URI are being built from an XML with the code ` Uri uri = Uri.parse(packageLocation+DummyContent.INFO_MAP.get(getArguments().getString(ARG_ITEM_ID)).get(0)); ` where info_map is a map with (String, ArrayList) pairings where get(0) gives the file name and get(1) right now gets a parameter from the xml for the video type. I was hoping to get rid of the need for an arraylist there to boost performance. get(0) will give you something like vid if the file was vid.p4. – user2532233 Jul 12 '13 at 15:47
  • the getType(Uri) function returns null if it can't determine what the mime type of the given uri is. My guess is that your file mime isn't one of the recognised types. – metalmonkeysoftware Jul 12 '13 at 16:48
  • 1
    but they are jpgs and mp4s. this is odd – user2532233 Jul 12 '13 at 17:45
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.

tpaczesny
  • 666
  • 8
  • 8
3
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
}
Konstantin Konopko
  • 5,229
  • 4
  • 36
  • 62
0

The best way to check is ...

Image:

private fun isImage(path: String): Boolean {
        val mimeType: String = URLConnection.guessContentTypeFromName(path)
        return mimeType.startsWith("image")
}

Video:

private fun isVideo(path: String): Boolean {
        val mimeType: String = URLConnection.guessContentTypeFromName(path)
        return mimeType.startsWith("video")
}

.zip or .rar:

private fun isZip(name: String): Boolean {
        return name.contains(".zip") || name.contains(".rar")
}
-53

Easiest way is to check extensions I guess

if ( file.toString().endsWith(".jpg") {
//photo
} else if (file.toString().endsWith(".3gp")) {
//video
}
Marko Niciforovic
  • 3,561
  • 2
  • 21
  • 28
  • 43
    I don't think this should be the accepted answer. There is a long list of extensions that could be images or videos, and that list may grow with time, so it is a pain to maintain manually. I will write my own now. – alfongj Jun 07 '15 at 16:45
  • for saying nothing of the missing `toLowerCase()` after "toString()" ;-) – Rick77 Jan 24 '16 at 15:00
  • This is very bad approach to detect file format.Along with alfongj's comment there is another problem that extension doesn't have to match. – Predrag Manojlovic Jun 27 '16 at 19:12
  • UPDATE: Please note that answer from @alfongj is the correct one, mine is more a hackish/quick fix way that *may* be suitable in some scenarios.. – Marko Niciforovic Jul 01 '16 at 14:41
  • This is not the correct answer, since file extension might not be same as file mime type! – Rez Mar 22 '17 at 08:24
  • Just because you're loading from a URI doesn't even mean you'll get the file's path or filename. If it's a virtual file you'll get `DISPLAY_NAME` which is probably the filename but that's not guaranteed. – hippietrail Aug 28 '19 at 05:56