假设我有一个完整的文件路径:(/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返回类型
I don't realize why MimeTypeMap.getFileExtensionFromUrl() has problems with spaces and some other characters, that returns "", but I just wrote this method to change the file name to an admit-able one. It's just playing with Strings. However, It kind of works. Through the method, the spaces existing in the file name is turned into a desirable character (which, here, is "x") via replaceAll(" ", "x") and other unsuitable characters are turned into a suitable one via URLEncoder. so the usage (according to the codes presented in the question and the selected answer) should be something like getMimeType(reviseUrl(url)).
private String reviseUrl(String url) {
String revisedUrl = "";
int fileNameBeginning = url.lastIndexOf("/");
int fileNameEnding = url.lastIndexOf(".");
String cutFileNameFromUrl = url.substring(fileNameBeginning + 1, fileNameEnding).replaceAll(" ", "x");
revisedUrl = url.
substring(0, fileNameBeginning + 1) +
java.net.URLEncoder.encode(cutFileNameFromUrl) +
url.substring(fileNameEnding, url.length());
return revisedUrl;
}
我尝试使用标准方法来确定mime类型,但我不能使用MimeTypeMap.getFileExtensionFromUrl(uri.getPath())保留文件扩展名。这个方法返回一个空字符串。所以我做了一个重要的解决方案来保留文件扩展名。
下面是返回文件扩展名的方法:
private String getExtension(String fileName){
char[] arrayOfFilename = fileName.toCharArray();
for(int i = arrayOfFilename.length-1; i > 0; i--){
if(arrayOfFilename[i] == '.'){
return fileName.substring(i+1, fileName.length());
}
}
return "";
}
并且保留了文件扩展名,可以获得如下所示的mime类型:
public String getMimeType(File file) {
String mimeType = "";
String extension = getExtension(file.getName());
if (MimeTypeMap.getSingleton().hasExtension(extension)) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return mimeType;
}