Comment déterminer le type de fichier MIME dans Android?
Supposons que j'ai un chemin complet du fichier comme: (/ sdcard/tlogo.png). Je veux connaître son type de mime.
J'ai créé une fonction pour cela
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;
}
mais quand je l'appelle, il retourne null.
File file = new File(filePath);
String fileType=CommonFunctions.getMimeType(file, context);
Avant tout, vous devriez envisager d'appeler MimeTypeMap#getMimeTypeFromExtension()
, comme ceci:
// 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;
}
Détecter le type mime de n'importe quel fichier
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 solution MimeTypeMap ci-dessus a renvoyé null dans mon utilisation. Cela fonctionne et est plus facile:
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
Version optimisée de Jens ' answere avec type null-safety et fallback.
@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;
}
Important: getFileExtensionFromUrl () ne fonctionne qu'avec minuscule!
Mise à jour (19.03.2018)
Bonus: Méthodes ci-dessus comme une méthode moins verbeuse fonction d'extension de Kotlin:
fun File.getMimeType(fallback: String = "image/*"): String {
return MimeTypeMap.getFileExtensionFromUrl(toString())
?.apply { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
?: fallback // You might set it to */*
}
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();
}
Portez une attention particulière à umerk44 / s solution ci-dessus. getMimeTypeFromExtension
invoque guessMimeTypeTypeFromExtension
et est sensible à la casse. J'ai passé un après-midi sur ce sujet, puis jeté un œil de plus près - getMimeTypeFromExtension
retournera NULL
si vous passez "JPG" alors qu'il retournera "image/jpeg" si vous le transmettez "jpg".
Voici la solution que j'ai utilisée dans mon application 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;
}
Parfois, les réponses de Jeb et Jens ne fonctionnent pas et renvoient null. Dans ce cas, j'utilise la solution suivante. L'en-tête du fichier contient généralement une signature de type. Je le lis et compare avec connu dans liste de 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
est un index de signature dans un tableau de signatures. Par exemple,
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;
}
Maintenant, j'ai le type de fichier même si l'URI du fichier n'a pas. Ensuite, je reçois le type mime par type de fichier. Si vous ne savez pas quel type de mime obtenir, vous pouvez trouver ce qui convient dans ce tableau .
Cela fonctionne pour beaucoup de types de fichiers. Mais pour la vidéo, cela ne fonctionne pas, car vous devez connaître le codec vidéo pour obtenir un type MIME. Pour obtenir le type mime d'une vidéo, j'utilise MediaMetadataRetriever .
MimeTypeMap
risque de ne pas reconnaître certaines extensions de fichier telles que flv, mpeg, 3gpp, cpp. Vous devez donc réfléchir à la manière de développer MimeTypeMap pour maintenir votre code. Voici un tel exemple .
De plus, voici une liste complète des types 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
}
Alors que de la ressource/fichier (Notez que peu de cas manquant de 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);
}
Bien que vous utilisiez ContentResolver
contentResolver.getType(uri)
Pendant la requête 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) {
}
Pour Xamarin Android (Réponse de @ HoaLe ci-dessus)
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;
}
J'ai essayé d'utiliser des méthodes standart pour déterminer le type mime, mais je ne peux pas conserver l'extension de fichier avec MimeTypeMap.getFileExtensionFromUrl (uri.getPath ()). Cette méthode m'a renvoyé une chaîne vide. J'ai donc créé une solution non triviale pour conserver l'extension de fichier.
Voici la méthode renvoyant une extension de fichier
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 "";
}
Et ayant conservé l’extension de fichier, il est possible d’obtenir le type mime comme ci-dessous
public String getMimeType(File file) {
String mimeType = "";
String extension = getExtention(file.getName());
if (MimeTypeMap.getSingleton().hasExtension(extension)) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return mimeType;
}
mime du fichier local:
String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);
A également renvoyé une valeur nulle.
/ stockage/émulé/0/Musique/01 - Ghost on the Dance Floor.mp3
comme travail autour de l'utilisation
val url = inUrl.replace ("", "")
alors méthode ressemble
@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
}
comme résultat, il renvoie le résultat du succès:
audio/mpeg
J'espère que ça aide quelqu'un
La solution ci-dessus a renvoyé la valeur null dans le cas du fichier .rar, en utilisant URLConnection.guessContentTypeFromName (url) qui a fonctionné dans ce cas.
// 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);
}
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);
}
Aucune des réponses ici n'est parfaite. Voici une réponse combinant les meilleurs éléments de toutes les meilleures réponses:
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;
}
}
}
vous avez le choix multiple d'obtenir l'extension du fichier: comme: 1 -String filename = uri.getLastPathSegment();
voir ceci link
2-vous pouvez aussi utiliser ce code
filePath .substring(filePath.lastIndexOf(".")+1);
mais ceci n'est pas bon aproch . 3-si vous avez un URI de fichier, utilisez ce code
String[] projection = { MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.MIME_TYPE };
4-si vous avez une URL, utilisez ce code:
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
profitez de votre code :)
// 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);}
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());
}
J'ai fait face à un problème similaire. Jusqu'à présent, je sais que le résultat peut être différent pour différents noms, et nous sommes donc finalement arrivés à cette solution.
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;
}