Android dosya MIME türü nasıl belirlenir?


176

Diyelim ki tam bir dosya yolum var: (/ sdcard / tlogo.png). MIME türünü bilmek istiyorum.

Onun için bir fonksiyon yarattım

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

ama ben çağırdığımda, null döndürür.

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

Yanıtlar:


323

İlk ve en önemlisi, şu şekilde aramayı düşünmelisiniz 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;
}

4
benim için teşekkürler iş ve benim sorun başka bir çözüm: public static String getMimeType (String path, Context context) {String extention = path.substring (path.lastIndexOf (".")); String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl (genişletme); String mimeType = MimeTypeMap.getSingleton () .getMimeTypeFromExtension (mimeTypeMap); return mimeType;}
Sushant Bhatnagar

13
Ve eğer dosya iyi bir uzantıya sahip değilse? bir kişi bir .mp3 yapabilir ve metin içerir
throrin19

2
Ayrıca mp3 txt dosyaları yeniden adlandırma kişi sadece yazmadım varsayar, ancak bu - O zaman aslında dosyayı açmak ve kurşun-in (biçim OFC bağlı olarak) sihirli numarayı kontrol etmek gerekiyordu ID3içinde metninin başında sizinle daha fazla uğraşmak.
Jens

1
Dosyanın bilinmeyen bir uzantısı varsa. Yöntem geri dönüyor */*mu?

3
/ Storage / emulated / 0 / Download / images (4) .jpg olarak dosya yolunuz varsa ve mimetype istiyorsanız, null değerini döndürür.
Kalaiselvan

165

Herhangi bir dosyanın mime türünü algılama

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

5
Bu doğru cevap olmalı. toLowerCase()hile yaptı.
Rajat Saxena

1
Bu en iyi cevaptır, ancak dosya adının özel bir karakteri varsa, benim durumumda bir apostrophe! Örneğin. dosya adı = Don't go baby.mp3. PatternMatcherİçeride MimeTypeMap.getFileExtensionFromUrl()dosya adını işlemek ve boş bir String döndürür olamaz; null mimetype String olarak çıkıyor!
sud007

I. ShvedenenkoYukarıda belirttiğim sorunlar için Worked tarafından aşağıda benzer ancak hatasız bir çözüm var . Ancak bu cevap doğru yönde bir göstericiydi.
sud007

bu kod "/ storage / emulated / 0 / dcim / screenshots / screenshot_20190319-123828_ubl digital app.jpg" ile null değerini döndürür.
Abdul

@Abdul Bu yolun bir Uri şeması olmaması nedeniyle. file://Veya ile başlamalıdır content://.
HB.

33

Yukarıdaki MimeTypeMap çözümü kullanımımda null döndürdü. Bu işe yarar ve daha kolaydır:

Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);

19
Bu yöntem de null değerini döndürebilir.
Bay Smith

URI'ye göre null dönebilir veya dönmeyebilir gibi görünüyor. Hiçbir vücut nedenini bilmiyor gibi görünmüyor ;-(
Thomas Decaux

10
Medya android galerisinden seçilirse, TYPE döndürülür. Dosya Yöneticisi'nden seçilirse null döndürülür.
Rahul Rastogi

Rahul'ın söylediklerini olumlu bir şekilde doğrulayabilirim, sadece test ettim ve haklı
Chris

Bazı cihazlarda galeriden resim
seçersem

21

Sıfır güvenlik ve geri dönüş türüyle optimize edilmiş Jens yanıtlama sürümü .

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

Önemli : getFileExtensionFromUrl () yalnızca küçük harfle çalışır !


Güncelleme (19.03.2018)

Bonus: Daha az ayrıntılı Kotlin uzatma fonksiyonu olarak yukarıdaki yöntemler :

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

bu işe yaradı. benim zevk için biraz aşırı ayrıntılı.
filthy_wizard

Tabii ki bu daha kısa bir şekilde yazar olabilir. Kotlin ile muhtemelen sadece iki veya üç çizgi, ancak tilki sıfır güvenlik ve toLoverCaseparçasıydı.
Tobias

@filthy_wizard, sadece sizin için optimize edilmiş bir versiyon ekledi ;-)
Tobias

Bana gelince, toString () yerine getPath () yöntemini kullanmak daha açık ve sadece kotlin özellik erişim sözdizimini kullanarak yol.
Leonid

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();

    }

1
Benim için mükemmel çalışıyor! Ancak dosya uzantısını almak için FilenameUtils.getExetension (yol) kullanmaya ne dersiniz?
peterb

7

Süper çok dikkat edin umerk44 'ın çözümü yukarıda. getMimeTypeFromExtensionÇAĞRI guessMimeTypeTypeFromExtensionDUYARLIDIR. Bunun ardından yakından baktık üzerinde bir öğleden sonra geçirdi - getMimeTypeFromExtensiondönecektir NULLsiz "JPG" siz "jpg" geçmek eğer "image / jpeg" dönecektir oysa bu adımı geçerseniz.


5

İşte Android uygulamamda kullandığım çözüm:

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

1
url? Birçok URL'nin uzantısı yok. Örneğin, bu sayfanın uzantısı yok. URL için yeni URL (url) .openConnection (). GetRequestProperty ("İçerik türü") kullanmalısınız;
barwnikk

5

Bazen Jeb ve Jens'in cevapları işe yaramıyor ve boş dönüyor. Bu durumda takip çözümünü kullanıyorum. Dosya başı genellikle tür imzası içerir. Ben okudum ve imza listesinde bilinen ile karşılaştırıyorum .

/**
 *
 * @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, imza dizisindeki bir imza dizinidir. Örneğin,

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

Şimdi dosya URI'sı olmasa bile dosya türüm var. Sonra dosya türüne göre mime türü alıyorum. Hangi mime türünü alacağınızı bilmiyorsanız, bu tabloda uygun bulabilirsiniz .

Birçok dosya türü için çalışır. Ancak video için işe yaramaz, çünkü bir mime türü elde etmek için bilinen video codec bileşenine ihtiyacınız vardır. Videonun mime tipini almak için MediaMetadataRetriever kullanıyorum .


4

Mime türünü belirlemek için standart yöntemler kullanmaya çalıştım, ancak kullanarak dosya uzantısını tutamıyorum MimeTypeMap.getFileExtensionFromUrl(uri.getPath()) . Bu yöntem bana boş bir dize döndürdü. Bu yüzden dosya uzantısını korumak için önemsiz bir çözüm yaptım.

Dosya uzantısını döndüren yöntem şunlardır:

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

Ve dosya uzantısını koruduktan sonra, aşağıdaki gibi mime türünü almak mümkündür:

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

Dostum, bu burada bu soruna gönderilen tüm cevapları çiviledi! Tüm Legacy sınıflarıyla aynı sorunu yaşadım. Sorun, bahsettiğinizle aynıydı MimeTypeMap.getFileExtensionFromUrl, a'nın dahili uygulamasına göre geçersiz karakterlere sahip Dosya Adları için boş dize döndürdü PatternMatcher. Bu tamamen benim için çalıştı! Loved it, şimdiye kadar hiçbir sorun!
sud007

@BEN. Shvedenenko String extension = file.getName().split("\\.")[1]da getExtension () yöntemini ortadan kaldırarak çalışmış olurdu.
Shahood ul Hassan

Ancak, dosya oluşturulurken yanlış bir uzantı kullanılırsa ne olur? Uzatma mim türünün tek hakimi olmalı mı?
Shahood ul Hassan


2

For Xamarin Android'de (Gönderen yukarıdaki HoaLe cevabı @)

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

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
    }

1

Varlık / dosyadayken (MimeTypeMap'te birkaç vakanın eksik olduğunu unutmayın).

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 kullanırken

contentResolver.getType(uri)

Http / https isteği yapılırken

    try {
        HttpURLConnection conn = httpClient.open(new URL(uri.toString()));
        conn.setDoInput(false);
        conn.setRequestMethod("HEAD");
        return conn.getHeaderField("Content-Type");
    } catch (IOException e) {
    }

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

Lütfen biraz açıklama yapın. İlk okuyucunun kodunu uyarlamasına ve diğer okuyucuların cevabınızdan en iyi değeri almasına yardımcı olacaktır.
Aurélien B

Cevabınız için teşekkürler. Ben açıklama ile düzenlerim.
iamdhariot

1

Benzer bir sorunla karşılaştım. Şimdiye kadar sonucun farklı isimler için farklı olabileceğini biliyorum, bu yüzden sonunda bu çözüme geldi.

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

0

Yukarıdaki çözüm, URLConnection.guessContentTypeFromName (url) kullanarak .rar dosyası durumunda null döndürdü.


0

yerel dosyadan mime:

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

0

Dosyanın uzantısını almak için birden fazla seçeneğiniz var: beğen: 1- String filename = uri.getLastPathSegment();bu bağlantıya bakın

2-bu kodu da kullanabilirsiniz

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

ama bu iyi bir yaklaşım değil. 3-URI dosyanız varsa, bu Kodu kullanın

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

4-URL'niz varsa şu kodu kullanın:

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


  type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }

return type;
}

kodunuzun tadını çıkarın :)


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

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

0

Ayrıca benim durumumda boş değer döndürdü oldu

/ depolama / benzetilmiş / 0 / Müzik / 01 - Dance Floor'da Hayalet.mp3

kullanım etrafında çalışma olarak

val url = inUrl.replace ("", "")

yani yöntem benziyor

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

sonuç olarak başarı sonucu döndürür:

ses / mpeg

Umarım herkese yardımcı olur


0

Buradaki cevapların hiçbiri mükemmel değil. İşte en iyi cevapların en iyi unsurlarını birleştiren bir cevap:

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

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


0

Neden s ve diğer bazı karakterlerle MimeTypeMap.getFileExtensionFromUrl()ilgili sorunlar olduğunu anlamıyorum , ama ben sadece dosya adını kabul edilebilir bir ile değiştirmek için bu yöntemi yazdım. Sadece s ile oynuyor . Ancak, bu tür işler. Bu yöntem sayesinde, dosya adında mevcut olan s istenen bir karaktere (burada "x") dönüşür ve diğer uygun olmayan karakterler ise uygun bir karaktere dönüştürülür . bu nedenle kullanım (soruda sunulan kodlara ve seçilen cevaba göre) gibi bir şey olmalıdır .space""StringspacereplaceAll(" ", "x")URLEncodergetMimeType(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;
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.