假设我有一个完整的文件路径,如:(/ 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);
答案 0 :(得分:288)
首先,您应该考虑调用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;
}
答案 1 :(得分:134)
检测任何文件的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;
}
答案 2 :(得分:32)
上面的MimeTypeMap解决方案在我的使用中返回null。这很有效,而且更容易:
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
答案 3 :(得分:16)
Jens'的优化版本回答了null-safety和fallback-type。
@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;
}
重要:getFileExtensionFromUrl()仅适用于小写!
奖励:以上方法作为一个不那么详细的 Kotlin扩展函数:
fun File.getMimeType(fallback: String = "image/*"): String {
return MimeTypeMap.getFileExtensionFromUrl(toString())
?.apply { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
?: fallback // You might set it to */*
}
答案 4 :(得分: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();
}
答案 5 :(得分:6)
密切关注上面umerk44的solution。 getMimeTypeFromExtension
调用guessMimeTypeTypeFromExtension
并且是CASE SENSITIVE。我花了一个下午然后仔细看看 - getMimeTypeFromExtension
将返回NULL
如果你传递“JPG”,而如果你传递“jpg”它将返回“image / jpeg”。
答案 6 :(得分:5)
以下是我在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;
}
答案 7 :(得分:4)
有时Jeb和Jens的答案不起作用并返回null。在这种情况下,我使用以下解决方案文件头通常包含类型签名。我读了它并与list of signatures中的已知进行比较。
/**
*
* @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;
}
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;
}
现在即使文件的URI没有,我也有文件类型。接下来我按文件类型获取mime类型。如果你不知道要获得哪种mime类型,你可以在this table中找到合适的。
适用于很多文件类型。但是对于视频它不起作用,因为你需要知道视频编解码器来获取mime类型。要获取视频的mime类型,我使用MediaMetadataRetriever。
答案 8 :(得分:3)
我尝试使用标准方法来确定mime类型,但我无法使用MimeTypeMap.getFileExtensionFromUrl(uri.getPath())保留文件扩展名。这个方法给我一个空字符串。所以我提出了非常重要的解决方案来保留文件扩展名。
这是返回文件扩展名的方法
private String getExtention(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 = getExtention(file.getName());
if (MimeTypeMap.getSingleton().hasExtension(extension)) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return mimeType;
}
答案 9 :(得分:2)
它对我有用,对内容和文件都灵活
public static String getMimeType(Context context, Uri uri) {
String extension;
//Check uri format to avoid null
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
//If scheme is a content
final MimeTypeMap mime = MimeTypeMap.getSingleton();
extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));
} else {
//If scheme is a File
//This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
}
return extension;
}
答案 10 :(得分:2)
MimeTypeMap
可能无法识别某些文件扩展名,如flv,mpeg,3gpp,cpp。因此,您需要考虑如何扩展MimeTypeMap以维护代码。这是一个例子。
另外,这里是一个完整的mime类型列表
http://www.sitepoint.com/web-foundations/mime-types-complete-list /
答案 11 :(得分:2)
Xamarin Android (来自@ HoaLe上面的答案)
public String getMimeType(Uri uri) {
String mimeType = null;
if (uri.Scheme.Equals(ContentResolver.SchemeContent))
{
ContentResolver cr = Application.Context.ContentResolver;
mimeType = cr.GetType(uri);
}
else
{
String fileExtension = MimeTypeMap.GetFileExtensionFromUrl(uri.ToString());
mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(
fileExtension.ToLower());
}
return mimeType;
}
答案 12 :(得分:1)
get file object....
File file = new File(filePath);
then....pass as a parameter to...
getMimeType(file);
...here is
public String getMimeType(File file) {
String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()).toLowerCase());
if (mimetype == null) {
return "*/*";
}
return mimetype;///return the mimeType
}
答案 13 :(得分:1)
来自资产/文件(请注意,MimeTypeMap中缺少一些案例)。
private String getMimeType(String path) {
if (null == path) return "*/*";
String extension = path;
int lastDot = extension.lastIndexOf('.');
if (lastDot != -1) {
extension = extension.substring(lastDot + 1);
}
// Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
extension = extension.toLowerCase(Locale.getDefault());
if (extension.equals("3ga")) {
return "audio/3gpp";
} else if (extension.equals("js")) {
return "text/javascript";
} else if (extension.equals("woff")) {
return "application/x-font-woff";
} else {
// TODO
// anyting missing from the map (http://www.sitepoint.com/web-foundations/mime-types-complete-list/)
// reference: http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils
}
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
使用ContentResolver
contentResolver.getType(uri)
http / https请求
try {
HttpURLConnection conn = httpClient.open(new URL(uri.toString()));
conn.setDoInput(false);
conn.setRequestMethod("HEAD");
return conn.getHeaderField("Content-Type");
} catch (IOException e) {
}
答案 14 :(得分:0)
还返回null值 在我的案例路径是
/ storage / emulated / 0 / Music / 01 - Ghost on the Dance Floor.mp3
作为解决方法使用
val url = inUrl.replace(“”,“”)
所以方法看起来像
/**
* @var text
*
* @ORM\Column(name="access_token", type="text")
*/
private $accessToken;
结果它返回成功结果:
音频/ MPEG
希望它可以帮助任何人
答案 15 :(得分:0)
使用Kotlin
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)
}
}
return try {
URLConnection.guessContentTypeFromStream(this.inputStream()) ?: catchUrlMimeType()
} catch (ignored: IOException) {
catchUrlMimeType()
}
}
这似乎是最好的选择,因为它结合了先前的答案。
首先,它尝试使用URLConnection.guessContentTypeFromStream获取类型,但如果失败或返回null,则尝试使用Android O及更高版本获取mimetype
java.nio.file.Files
java.nio.file.Paths
否则,如果Android版本低于O或方法失败,它将使用ContentResolver和MimeTypeMap返回类型
答案 16 :(得分:0)
我不知道为什么MimeTypeMap.getFileExtensionFromUrl()
遇到space
和其他字符问题,并返回""
,但是我只是写了这种方法来将文件名更改为允许-可以的。它只是在玩String
。但是,这是可行的。通过该方法,通过space
将文件名中存在的replaceAll(" ", "x")
转换为所需的字符(在此为“ x”),而通过{ {1}}。因此用法(根据问题和所选答案中显示的代码)应类似于 URLEncoder
。
getMimeType(reviseUrl(url))
答案 17 :(得分:0)
我认为最简单的方法是引用此资源文件: https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/libcore/net/android.mime.types
答案 18 :(得分:0)
我遇到了类似的问题。到目前为止,我知道不同名称的结果可能会有所不同,因此终于有了这个解决方案。
public String getMimeType(String filePath) {
String type = null;
String extension = null;
int i = filePath.lastIndexOf('.');
if (i > 0)
extension = filePath.substring(i+1);
if (extension != null)
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
return type;
}
答案 19 :(得分:0)
// This will return the mimeType.
// for eg. xyz.png it will return image/png.
// here uri is the file that we were picked using intent from ext/internal storage.
private String getMimeType(Uri uri) {
// This class provides applications access to the content model.
ContentResolver contentResolver = getContentResolver();
// getType(Uri url)-Return the MIME type of the given content URL.
return contentResolver.getType(uri);
}
答案 20 :(得分:0)
Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
File file = new File(filePatch);
Uri uris = Uri.fromFile(file);
String mimetype = null;
if
(uris.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr =
getApplicationContext().getContentResolver();
mimetype = cr.getType(uris);
} else {
String fileExtension =
MimeTypeMap.getFileExtensionFromUrl(uris.toString());
mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());
}
答案 21 :(得分:0)
public final class FileUtil {
// By default, Android doesn't provide support for JSON
public static final String MIME_TYPE_JSON = "application/json";
@Nullable
public static String getMimeType(@NonNull Context context, @NonNull Uri uri) {
String mimeType = null;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = context.getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = getExtension(uri.toString());
if(fileExtension == null){
return null;
}
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
if(mimeType == null){
// Handle the misc file extensions
return handleMiscFileExtensions(fileExtension);
}
}
return mimeType;
}
@Nullable
private static String getExtension(@Nullable String fileName){
if(fileName == null || TextUtils.isEmpty(fileName)){
return null;
}
char[] arrayOfFilename = fileName.toCharArray();
for(int i = arrayOfFilename.length-1; i > 0; i--){
if(arrayOfFilename[i] == '.'){
return fileName.substring(i+1, fileName.length());
}
}
return null;
}
@Nullable
private static String handleMiscFileExtensions(@NonNull String extension){
if(extension.equals("json")){
return MIME_TYPE_JSON;
}
else{
return null;
}
}
}
答案 22 :(得分:0)
来自本地档案的mime:
String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);
答案 23 :(得分:0)
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);
}
答案 24 :(得分:0)
上述解决方案在.rar文件的情况下返回null,在这种情况下使用URLConnection.guessContentTypeFromName(url)。
答案 25 :(得分:0)
// new processing the mime type out of Uri which may return null in some cases
String mimeType = getContentResolver().getType(uri);
// old processing the mime type out of path using the extension part if new way returned null
if (mimeType == null){mimeType URLConnection.guessContentTypeFromName(path);}