Bagaimana cara menentukan jenis file MIME di android?


176

Misalkan saya memiliki path lengkap file seperti: (/ sdcard / tlogo.png). Saya ingin tahu tipe pantomimnya.

Saya membuat fungsi untuk itu

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

tetapi ketika saya menyebutnya, itu mengembalikan nol.

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

Jawaban:


323

Pertama dan terpenting, Anda harus mempertimbangkan untuk menelepon MimeTypeMap#getMimeTypeFromExtension(), seperti ini:

// 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
terima kasih bekerja untuk saya dan solusi lain dari masalah saya adalah: public getMimeType String statis (String path, Konteks konteks) {String extention = path.substring (path.lastIndexOf (".")); String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl (extention); String mimeType = MimeTypeMap.getSingleton () .getMimeTypeFromExtension (mimeTypeMap); return mimeType;}
Sushant Bhatnagar

13
Dan jika file tersebut tidak memiliki ekstensi yang baik? seseorang dapat membuat .mp3 dan itu berisi teks
throrin19

2
Maka Anda harus benar-benar membuka file & memeriksa nomor ajaib (tergantung pada format ofc) di lead-in - ini, bagaimanapun, juga mengasumsikan bahwa orang yang mengubah nama file txt ke mp3 tidak hanya menulis ID3di mulai dari teksnya untuk lebih mengacaukan Anda.
Jens

1
Jika file memiliki ekstensi yang tidak dikenal. Apakah metode kembali */*?

3
Jika Anda memiliki path file sebagai / storage / emulated / 0 / Download / images (4) .jpg dan Anda meminta mimetype, ia mengembalikan null.
Kalaiselvan

165

Mendeteksi tipe pantomim dari file apa pun

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
Ini seharusnya jawaban yang benar. toLowerCase()melakukan trik.
Rajat Saxena

1
Sejauh ini ini adalah jawaban terbaik tetapi gagal total jika nama file memiliki karakter khusus, dalam kasus saya sebuah apostrophe! Misalnya. nama file = Don't go baby.mp3. Bagian PatternMatcherdalam MimeTypeMap.getFileExtensionFromUrl()tidak dapat menangani nama file dan mengembalikan String kosong; null menjadi String mimetype!
sud007

Ada solusi serupa namun bebas kesalahan di bawah ini oleh I. ShvedenenkoBekerja untuk masalah yang telah saya sebutkan di atas. Tetapi jawaban ini adalah penunjuk ke arah yang benar.
sud007

kode ini mengembalikan null dengan String "/ storage / emulated / 0 / dcim / screenshots / screenshot_20190319-123828_ubl digital app.jpg".
Abdul

@Abdul Itu karena jalur itu tidak memiliki skema Uri. Ini harus dimulai dengan file://atau content://.
HB.

33

Solusi MimeTypeMap di atas mengembalikan nol dalam penggunaan saya. Ini berfungsi, dan lebih mudah:

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

19
Metode ini juga dapat mengembalikan null.
Tuan Smith

Sepertinya itu dapat mengembalikan nol atau tidak, menurut URI. Sepertinya tidak ada orang yang tahu mengapa ;-(
Thomas Decaux

10
Jika media dipilih dari galeri android maka TYPE dikembalikan. Jika dipilih dari File Manager maka null dikembalikan.
Rahul Rastogi

Saya bisa secara positif mengkonfirmasi apa yang dikatakan Rahul, baru mengujinya dan dia benar
Chris

Di beberapa perangkat jika saya memilih gambar dari galeri juga mengembalikan nol
Ghanshyam Nayma

21

Versi Jens yang dioptimalkan menjawab dengan keamanan nol dan tipe mundur.

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

Penting : getFileExtensionFromUrl () hanya berfungsi dengan huruf kecil !


Pembaruan (19.03.2018)

Bonus: Metode di atas sebagai fungsi ekstensi Kotlin yang kurang verbose :

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

ini berhasil. sedikit terlalu verbose untuk seleraku.
filthy_wizard

Tentu saja ini bisa ditulis dengan cara yang lebih singkat. Dengan Kotlin mungkin hanya dua atau tiga baris, namun rubah berada di bagian nol keamanan dan toLoverCasebagian.
Tobias

@filthy_wizard, menambahkan versi yang dioptimalkan hanya untuk Anda ;-)
Tobias

Sedangkan bagi saya menggunakan metode getPath () daripada toString () lebih jelas, dan hanya jalan menggunakan sintaks akses properti kotlin.
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
Berfungsi sempurna untuk saya! Tetapi bagaimana dengan menggunakan FilenameUtils.getExetension (path) untuk mendapatkan ekstensi file?
peterb

7

Perhatikan solusi umerk44 di atas. memanggil dan SENSITIF KASUS. Saya menghabiskan sore ini untuk melihat lebih dekat - akan kembali jika Anda melewatinya "JPG" sedangkan itu akan mengembalikan "image / jpeg" jika Anda meneruskannya "jpg".getMimeTypeFromExtensionguessMimeTypeTypeFromExtensiongetMimeTypeFromExtensionNULL


5

Inilah solusi yang saya gunakan di aplikasi Android saya:

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? Banyak url tidak memiliki ekstensi. Misalnya halaman ini tidak memiliki ekstensi. Untuk url Anda harus menggunakan URL baru (url) .openConnection (). GetRequestProperty ("Tipe konten");
barwnikk

5

Terkadang jawaban Jeb dan Jens tidak bekerja dan menghasilkan nol. Dalam hal ini saya menggunakan solusi ikuti. Kepala file biasanya berisi tipe tanda tangan. Saya membacanya dan membandingkannya dengan yang dikenal dalam daftar tanda tangan .

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

signatureIdadalah indeks tanda tangan dalam berbagai tanda tangan. Sebagai contoh,

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

Sekarang saya memiliki tipe file bahkan jika file URI belum. Selanjutnya saya mendapatkan tipe mime berdasarkan tipe file. Jika Anda tidak tahu tipe mime mana yang harus Anda dapatkan, Anda dapat menemukan yang tepat di tabel ini .

Ini berfungsi untuk banyak jenis file. Tetapi untuk video itu tidak berfungsi, karena Anda perlu tahu codec video untuk mendapatkan tipe mime. Untuk mendapatkan video mime ketik saya menggunakan MediaMetadataRetriever .


4

Saya mencoba menggunakan metode standar untuk menentukan tipe mime, tetapi saya tidak dapat mempertahankan ekstensi file menggunakan MimeTypeMap.getFileExtensionFromUrl(uri.getPath()). Metode ini mengembalikan saya string kosong. Jadi saya membuat solusi non-sepele untuk mempertahankan ekstensi file.

Berikut adalah metode mengembalikan ekstensi file:

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

Dan setelah mempertahankan ekstensi file, dimungkinkan untuk mendapatkan tipe mime seperti di bawah ini:

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

Sobat, ini memakukan semua jawaban yang diposting di sini untuk masalah ini! Saya memiliki masalah yang sama dengan semua kelas Legacy. Masalah sama dengan yang Anda sebutkan, MimeTypeMap.getFileExtensionFromUrlmengembalikan string kosong untuk Nama File yang memiliki karakter tidak valid sesuai implementasi internal a PatternMatcher. Ini bekerja untuk saya sepenuhnya! Menyukainya, tidak ada masalah sejauh ini!
sud007

@SAYA. Shvedenenko String extension = file.getName().split("\\.")[1]juga akan bekerja, dengan demikian, menghilangkan metode getExtension ().
Shahood ul Hassan

Tapi masalahnya, bagaimana jika ekstensi yang salah digunakan saat membuat file? Haruskah ekstensi menjadi satu-satunya hakim tipe mime?
Shahood ul Hassan


2

Untuk Xamarin Android (Dari @ HoaLe jawaban di atas)

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

Sementara dari aset / file (Perhatikan bahwa beberapa kasus hilang dari 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);
}

Saat menggunakan ContentResolver

contentResolver.getType(uri)

Sementara permintaan 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) {
    }

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

Tolong berikan beberapa penjelasan. Ini akan membantu pembaca awal untuk mengadaptasi kodenya dan pembaca selanjutnya untuk mendapatkan nilai maksimal dari jawaban Anda.
Aurélien B

Terimakasih atas tanggapan Anda. Saya mengeditnya dengan penjelasan.
iamdhariot

1

Saya menghadapi masalah yang sama. Sejauh ini saya tahu hasilnya mungkin berbeda untuk nama yang berbeda, jadi akhirnya datang ke solusi ini.

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

Solusi di atas menghasilkan null dalam kasus file .rar, menggunakan URLConnection.guessContentTypeFromName (url) yang berfungsi dalam kasus ini.


0

pantomim dari file lokal:

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

0

Anda memiliki banyak pilihan untuk mendapatkan ekstensi file: seperti: 1- String filename = uri.getLastPathSegment();lihat tautan ini

2-Anda dapat menggunakan kode ini juga

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

tapi ini tidak bagus aproch. 3-jika Anda memiliki file URI maka gunakan Kode ini

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

4-jika Anda memiliki URL maka gunakan kode ini:

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


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

return type;
}

nikmati kode kamu :)


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

Juga mengembalikan nilai nol di jalur kasus saya

/ storage / emulated / 0 / Music / 01 - Ghost on the Dance Floor.mp3

sebagai bekerja di sekitar digunakan

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

jadi sepertinya metode

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

sebagai hasilnya mengembalikan hasil sukses:

audio / mpeg

Semoga ini bisa membantu siapa saja


0

Tidak ada jawaban di sini yang sempurna. Berikut adalah jawaban yang menggabungkan elemen terbaik dari semua jawaban teratas:

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

Saya tidak menyadari mengapa MimeTypeMap.getFileExtensionFromUrl()ada masalah dengan karakter spaces dan beberapa karakter lain, yang muncul "", tetapi saya hanya menulis metode ini untuk mengubah nama file menjadi yang dapat diterima. Itu hanya bermain dengan Strings. Namun, ini semacam bekerja. Melalui metode ini, yang spaceada dalam nama file diubah menjadi karakter yang diinginkan (yang, di sini, adalah "x") melalui replaceAll(" ", "x")dan karakter tidak cocok lainnya diubah menjadi yang sesuai melalui URLEncoder. jadi penggunaan (sesuai dengan kode yang disajikan dalam pertanyaan dan jawaban yang dipilih) harus seperti getMimeType(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;
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.