Sus*_*gar 162 filesystems android mime-types
假设我有一个完整的文件路径,如:(/ 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;
}
Run Code Online (Sandbox Code Playgroud)
但是当我调用它时,它返回null.
File file = new File(filePath);
String fileType=CommonFunctions.getMimeType(file, context);
Run Code Online (Sandbox Code Playgroud)
Jen*_*ens 302
首先,您应该考虑调用MimeTypeMap#getMimeTypeFromExtension(),如下所示:
// url = file path or whatever suitable URL you want.
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
Run Code Online (Sandbox Code Playgroud)
小智 147
检测任何文件的mime类型
public String getMimeType(Uri uri) {
String mimeType = null;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = getAppContext().getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return mimeType;
}
Run Code Online (Sandbox Code Playgroud)
Jeb*_*Jeb 32
上面的MimeTypeMap解决方案在我的使用中返回null.这很有效,而且更容易:
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
Run Code Online (Sandbox Code Playgroud)
Tob*_*ias 17
优化的版本延的answere与空安全和回退类型.
@NonNull
static String getMimeType(@NonNull File file) {
String type = null;
final String url = file.toString();
final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
}
if (type == null) {
type = "image/*"; // fallback type. You might set it to */*
}
return type;
}
Run Code Online (Sandbox Code Playgroud)
重要说明:getFileExtensionFromUrl()仅适用于小写!
额外奖励:以上方法作为较少详细的Kotlin扩展功能:
fun File.getMimeType(fallback: String = "image/*"): String {
return MimeTypeMap.getFileExtensionFromUrl(toString())
?.apply { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
?: fallback // You might set it to */*
}
Run Code Online (Sandbox Code Playgroud)
ume*_*k44 15
File file = new File(path, name);
MimeTypeMap mime = MimeTypeMap.getSingleton();
int index = file.getName().lastIndexOf('.')+1;
String ext = file.getName().substring(index).toLowerCase();
String type = mime.getMimeTypeFromExtension(ext);
intent.setDataAndType(Uri.fromFile(file), type);
try
{
context.startActivity(intent);
}
catch(ActivityNotFoundException ex)
{
ex.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
在 kotlin 中,这要简单得多。
解决方案一:
fun getMimeType(file: File): String? =
MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)
Run Code Online (Sandbox Code Playgroud)
方案二:(文件扩展功能)
fun File.mimeType(): String? =
MimeTypeMap.getSingleton().getMimeTypeFromExtension(this.extension)
Run Code Online (Sandbox Code Playgroud)
我为此创建了一个小型图书馆。但底层代码几乎是一样的。
它可以在 GitHub 上找到
使用科特林
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()
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是最好的选择,因为它结合了以前的答案。
首先,它尝试使用 URLConnection.guessContentTypeFromStream 获取类型,但如果失败或返回 null,它会尝试使用 Android O 及更高版本获取 mimetype
java.nio.file.Files
java.nio.file.Paths
Run Code Online (Sandbox Code Playgroud)
否则,如果 Android 版本低于 O 或方法失败,它将使用 ContentResolver 和 MimeTypeMap 返回类型
这是我在Android应用中使用的解决方案:
public static String getMimeType(String url)
{
String extension = url.substring(url.lastIndexOf("."));
String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
return mimeType;
}
Run Code Online (Sandbox Code Playgroud)
有时Jeb和Jens的答案不起作用,并且返回null。在这种情况下,我使用关注解决方案。文件头通常包含类型签名。我阅读并与签名列表中的已知签名进行比较。
/**
*
* @param is InputStream on start of file. Otherwise signature can not be defined.
* @return int id of signature or -1, if unknown signature was found. See SIGNATURE_ID_(type) constants to
* identify signature by its id.
* @throws IOException in cases of read errors.
*/
public static int getSignatureIdFromHeader(InputStream is) throws IOException {
// read signature from head of source and compare with known signatures
int signatureId = -1;
int sigCount = SIGNATURES.length;
int[] byteArray = new int[MAX_SIGNATURE_LENGTH];
StringBuilder builder = new StringBuilder();
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
byteArray[i] = is.read();
builder.append(Integer.toHexString(byteArray[i]));
}
if (DEBUG) {
Log.d(TAG, "head bytes=" + builder.toString());
}
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
// check each bytes with known signatures
int bytes = byteArray[i];
int lastSigId = -1;
int coincidences = 0;
for (int j = 0; j < sigCount; j++) {
int[] sig = SIGNATURES[j];
if (DEBUG) {
Log.d(TAG, "compare" + i + ": " + Integer.toHexString(bytes) + " with " + sig[i]);
}
if (bytes == sig[i]) {
lastSigId = j;
coincidences++;
}
}
// signature is unknown
if (coincidences == 0) {
break;
}
// if first bytes of signature is known we check signature for full coincidence
if (coincidences == 1) {
int[] sig = SIGNATURES[lastSigId];
int sigLength = sig.length;
boolean isSigKnown = true;
for (; i < MAX_SIGNATURE_LENGTH && i < sigLength; i++) {
bytes = byteArray[i];
if (bytes != sig[i]) {
isSigKnown = false;
break;
}
}
if (isSigKnown) {
signatureId = lastSigId;
}
break;
}
}
return signatureId;
}
Run Code Online (Sandbox Code Playgroud)
signatureId是签名数组中签名的索引。例如,
private static final int[] SIGNATURE_PNG = hexStringToIntArray("89504E470D0A1A0A");
private static final int[] SIGNATURE_JPEG = hexStringToIntArray("FFD8FF");
private static final int[] SIGNATURE_GIF = hexStringToIntArray("474946");
public static final int SIGNATURE_ID_JPEG = 0;
public static final int SIGNATURE_ID_PNG = 1;
public static final int SIGNATURE_ID_GIF = 2;
private static final int[][] SIGNATURES = new int[3][];
static {
SIGNATURES[SIGNATURE_ID_JPEG] = SIGNATURE_JPEG;
SIGNATURES[SIGNATURE_ID_PNG] = SIGNATURE_PNG;
SIGNATURES[SIGNATURE_ID_GIF] = SIGNATURE_GIF;
}
Run Code Online (Sandbox Code Playgroud)
现在我有了文件类型,即使文件的URI还没有。接下来,按文件类型获取mime类型。如果您不知道要获取哪种MIME类型,则可以在此表中找到适当的类型。
它适用于许多文件类型。但是对于视频来说,它是行不通的,因为您需要使用已知的视频编解码器才能获得哑剧类型。要获取视频的mime类型,请使用MediaMetadataRetriever。
小智 5
我尝试使用标准方法来确定 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 "";
}
Run Code Online (Sandbox Code Playgroud)
并且保留了文件扩展名,可以得到如下的 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
117351 次 |
| 最近记录: |