¿Cómo determinar el tipo de archivo MIME en Android?

Supongamos que tengo una ruta completa de archivo como: (/ sdcard / tlogo.png). Quiero saber su tipo de mimo.

Creé una función para ello

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; } 

pero cuando lo llamo, devuelve nulo.

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

En primer lugar, debe considerar llamar a MimeTypeMap#getMimeTypeFromExtension() , así:

 // 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; } 

Detecta el tipo de mime de mi

 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; } 

La solución anterior de MimeTypeMap devolvió nulo mi uso. Esto funciona, y es más fácil:

 Uri uri = Uri.fromFile(file); ContentResolver cR = context.getContentResolver(); String mime = cR.getType(uri); 
 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(); } 

Versión optimizada de la respuesta de Jens con seguridad nula y tipo de respaldo.

 @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; } 

Importante : getFileExtensionFromUrl () solo funciona con minúsculas .


Actualización (19.03.2018)

Bonificación: métodos anteriores como una función de extensión de Kotlin menos detallada:

 fun File.getMimeType(fallback: String = "image/*"): String { return MimeTypeMap.getFileExtensionFromUrl(toString()) ?.apply { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) } ?: fallback // You might set it to */* } 

Presta mucha atención a la solución de umerk44 anterior. getMimeTypeFromExtension invoca guessMimeTypeTypeFromExtension y es CASE SENSITIVE. Pasé una tarde en esto y luego lo getMimeTypeFromExtension más de cerca: getMimeTypeFromExtension devolverá NULL si le pasa “JPG”, mientras que devolverá “image / jpeg” si lo pasa “jpg”.

A veces las respuestas de Jeb y Jens no funcionan y devuelven nulo. En este caso, uso la solución de seguimiento. El jefe del archivo generalmente contiene una firma de tipo. Lo leí y lo comparo con lo conocido en la lista de firmas .

 /** * * @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 es un índice de firma en matriz de firmas. Por ejemplo,

 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; } 

Ahora tengo el tipo de archivo incluso si el URI del archivo no. Luego obtengo el tipo mime por tipo de archivo. Si no sabe qué tipo de mimo obtener, puede encontrarlo en esta tabla .

Funciona para muchos tipos de archivos. Pero para el video no funciona, porque necesita un códec de video conocido para obtener un tipo de mimo. Para obtener el tipo de mime de video, uso MediaMetadataRetriever .

Aquí está la solución que utilicé en mi aplicación de 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; } 

MimeTypeMap posible que MimeTypeMap no reconozca algunas extensiones de archivos como flv, mpeg, 3gpp, cpp. Entonces, debe pensar cómo expandir MimeTypeMap para mantener su código. Aquí hay un ejemplo.

http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils

Además, aquí hay una lista completa de tipos de mime

http: //www.sitepoint.com/web-foundations/mime-types-complete-list/

 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 } 

Si bien desde activo / archivo (Tenga en cuenta que faltan pocos casos en 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); } 

Mientras usas ContentResolver

 contentResolver.getType(uri) 

Mientras que la solicitud 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) { } 

Intenté usar métodos estándar para determinar el tipo de mimo, pero no puedo retener la extensión de archivo usando MimeTypeMap.getFileExtensionFromUrl (uri.getPath ()). Este método me devolvió una cadena vacía. Así que hice una solución no trivial para retener la extensión del archivo.

Aquí está el método para devolver la extensión del archivo

 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 ""; } 

Y al haber conservado la extensión del archivo, es posible obtener el tipo de mimo como se muestra a continuación

 public String getMimeType(File file) { String mimeType = ""; String extension = getExtention(file.getName()); if (MimeTypeMap.getSingleton().hasExtension(extension)) { mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); } return mimeType; } 

Para Xamarin Android (de la respuesta de @HaaLe anterior)

 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; } 

La solución anterior devolvió nulo en el caso del archivo .rar, usando URLConnection.guessContentTypeFromName (url) funcionó en este caso.

mimo del archivo local:

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

tiene opción múltiple para obtener la extensión del archivo: como: 1- String filename = uri.getLastPathSegment(); ver este enlace

2-puedes usar este código también

  filePath .substring(filePath.lastIndexOf(".")+1); 

pero este no es un buen aproch. 3-si tienes un URI de archivo, utiliza este código

 String[] projection = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.MIME_TYPE }; 

4-si tienes URL, utiliza este código:

  public static String getMimeType(String url) { String type = null; String extension = MimeTypeMap.getFileExtensionFromUrl(url); if (extension != null) { type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); } return type; } 

disfruta tu código 🙂

 // 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);} 
 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); } 

También devuelve un valor nulo en mi ruta de caso

/ storage / emulated / 0 / Music / 01 – Fantasma en la pista de baile.mp3

como trabajar alrededor del uso

val url = inUrl.replace (“”, “”)

entonces el método se ve como

 @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 } 

como resultado, devuelve el resultado de éxito:

audio / mpeg

Espero que ayude a cualquiera

Ninguna de las respuestas aquí es perfecta. Aquí hay una respuesta que combina los mejores elementos de todas las respuestas principales:

 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; } } }