假设我有一个完整的文件路径:(/sdcard/tlogo.png)。我想知道它的mime类型。

我为它创建了一个函数

public static String getMimeType(File file, Context context)    
{
    Uri uri = Uri.fromFile(file);
    ContentResolver cR = context.getContentResolver();
    MimeTypeMap mime = MimeTypeMap.getSingleton();
    String type = mime.getExtensionFromMimeType(cR.getType(uri));
    return type;
}

但当我调用它时,它返回null。

File file = new File(filePath);
String fileType=CommonFunctions.getMimeType(file, context);

当前回答

EDIT

我为此创建了一个小型库。 但是底层代码几乎是一样的。

它在GitHub上可用

MimeMagic-Android

2020年9月

使用芬兰湾的科特林

fun File.getMimeType(context: Context): String? {
    if (this.isDirectory) {
        return null
    }

    fun fallbackMimeType(uri: Uri): String? {
        return if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
            context.contentResolver.getType(uri)
        } else {
            val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
            MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase(Locale.getDefault()))
        }
    }

    fun catchUrlMimeType(): String? {
        val uri = Uri.fromFile(this)

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val path = Paths.get(uri.toString())
            try {
                Files.probeContentType(path) ?: fallbackMimeType(uri)
            } catch (ignored: IOException) {
                fallbackMimeType(uri)
            }
        } else {
            fallbackMimeType(uri)
        }
    }

    val stream = this.inputStream()
    return try {
        URLConnection.guessContentTypeFromStream(stream) ?: catchUrlMimeType()
    } catch (ignored: IOException) {
        catchUrlMimeType()
    } finally {
        stream.close()
    }
}

这似乎是最好的选择,因为它结合了前面的答案。

首先,它尝试使用URLConnection获取类型。guessContentTypeFromStream,但如果这个失败或返回null,它会尝试在Android O和以上使用mimetype

java.nio.file.Files
java.nio.file.Paths

否则,如果Android版本低于O或方法失败,它将使用ContentResolver和MimeTypeMap返回类型

其他回答

public static String getFileType(Uri file)
{
    try
    {
        if (file.getScheme().equals(ContentResolver.SCHEME_CONTENT))
            return subStringFromLastMark(SystemMaster.getContentResolver().getType(file), "/");
        else
            return MimeTypeMap.getFileExtensionFromUrl(file.toString()).toLowerCase();
    }
    catch(Exception e)
    {
        return null;
    }
}

public static String getMimeType(Uri file)
{
    try
    {
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(getFileType(file));
    }
    catch(Exception e)
    {
        return null;
    }
}

public static String subStringFromLastMark(String str,String mark)
{
    int l = str.lastIndexOf(mark);
    int end = str.length();
    if(l == -1)
        return str;

    return str.substring(l + 1, end);
}

EDIT

我为此创建了一个小型库。 但是底层代码几乎是一样的。

它在GitHub上可用

MimeMagic-Android

2020年9月

使用芬兰湾的科特林

fun File.getMimeType(context: Context): String? {
    if (this.isDirectory) {
        return null
    }

    fun fallbackMimeType(uri: Uri): String? {
        return if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
            context.contentResolver.getType(uri)
        } else {
            val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
            MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase(Locale.getDefault()))
        }
    }

    fun catchUrlMimeType(): String? {
        val uri = Uri.fromFile(this)

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val path = Paths.get(uri.toString())
            try {
                Files.probeContentType(path) ?: fallbackMimeType(uri)
            } catch (ignored: IOException) {
                fallbackMimeType(uri)
            }
        } else {
            fallbackMimeType(uri)
        }
    }

    val stream = this.inputStream()
    return try {
        URLConnection.guessContentTypeFromStream(stream) ?: catchUrlMimeType()
    } catch (ignored: IOException) {
        catchUrlMimeType()
    } finally {
        stream.close()
    }
}

这似乎是最好的选择,因为它结合了前面的答案。

首先,它尝试使用URLConnection获取类型。guessContentTypeFromStream,但如果这个失败或返回null,它会尝试在Android O和以上使用mimetype

java.nio.file.Files
java.nio.file.Paths

否则,如果Android版本低于O或方法失败,它将使用ContentResolver和MimeTypeMap返回类型

是否也返回空值 在我的案例中,路径是

/storage/ emululated /0/Music/01 - Ghost on the Dance Floor.mp3

在工作中使用

瓦尔·奥尼。replace(“”、“”)

方法是这样的

@JvmStatic
    fun getMimeType(inUrl: String?): String {
        if (inUrl == null) return ""

        val url = inUrl.replace(" ","")
        var type: String? = null

        val extension = MimeTypeMap.getFileExtensionFromUrl(url)
        if (extension != null) {
            type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase())
        }

        if(type ==null){
            val cR = WifiTalkie.getApplicationContext().contentResolver
            type = cR.getType(Uri.parse(url))
        }

        if (type == null) {
            type = "*/*" // fallback method_type. You might set it to */*
        }
        return type
    }

结果返回成功结果:

音频/ mpeg

希望能对大家有所帮助

我认为最简单的方法是引用这个资源文件: https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/libcore/net/android.mime.types

Mime从本地文件:

String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);