programing

안드로이드에서 MIME 파일 유형을 결정하는 방법은 무엇입니까?

css3 2023. 8. 23. 21:54

안드로이드에서 MIME 파일 유형을 결정하는 방법은 무엇입니까?

다음과 같은 파일의 전체 경로가 있다고 가정합니다. (/sdcard/tlogo.png)그것의 마임 타입을 알고 싶습니다.

나는 그것을 위한 함수를 만들었습니다.

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

무엇보다도, 당신은 전화하는 것을 고려해야 합니다.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;
}

모든 파일의 MIME 유형 탐지

public String getMimeType(Uri uri) {           
    String mimeType = null;
    if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
        ContentResolver cr = getAppContext().getContentResolver();
        mimeType = cr.getType(uri);
    } else {
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
                .toString());
        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                fileExtension.toLowerCase());
    }
    return mimeType;
}

위의 MimeTypeMap 솔루션이 내 사용에서 null을 반환했습니다.이것은 작동하고 더 쉽습니다.

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

젠스의 응답 최적화 버전은 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()은 소문자에서만 작동합니다!


업데이트 (19.03.2018)

보너스: 덜 장황한 코틀린 확장 함수로서 위의 방법들:

fun File.getMimeType(fallback: String = "image/*"): String {
    return MimeTypeMap.getFileExtensionFromUrl(toString())
            ?.run { 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();

    }

코틀린에서는 훨씬 더 간단합니다.

솔루션 1:

fun getMimeType(file: File): String? = 
    MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)

솔루션 2: (파일 확장자 기능)

fun File.mimeType(): String? = 
    MimeTypeMap.getSingleton().getMimeTypeFromExtension(this.extension)

위의 umerk44솔루션에 매우 세심한 주의를 기울입니다.getMimeTypeFromExtension출호를 합니다.guessMimeTypeTypeFromExtension대소문자를 구분합니다. 후 . - 저는이대오보내자살다습니았펴보세히고를후해것에▁i다니습살았펴▁-보▁spent▁a자▁took히▁then세.getMimeTypeFromExtension돌아올 것입니다NULL하면 "반환됩니다. "를하면 "image/jpeg"가됩니다.JPG"를 전달하면 "image/jpeg"가 반환됩니다.

안드로이드 앱에서 사용한 솔루션은 다음과 같습니다.

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

편집

저는 이것을 위해 작은 도서관을 만들었습니다.하지만 기본 코드는 거의 같습니다.

GitHub에서 사용할 수 있습니다.

마임 매직-안드로이드

솔루션 2020년 9월

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

    val stream = this.inputStream()
    return try {
        URLConnection.guessContentTypeFromStream(stream) ?: catchUrlMimeType()
    } catch (ignored: IOException) {
        catchUrlMimeType()
    } finally {
        stream.close()
    }
}

그것은 이전의 답변들을 결합한 것이기 때문에 가장 좋은 선택인 것 같습니다.

먼저 URL 연결을 사용하여 유형을 가져오려고 합니다.내용 추측FromStream을 입력하지만 실패하거나 null을 반환하면 Android O 이상에서 다음을 사용하여 mimtype을 가져오려고 합니다.

java.nio.file.Files
java.nio.file.Paths

그렇지 않으면 Android 버전이 O 미만이거나 메서드가 실패하면 ContentResolver 및 MimeTypeMap을 사용하여 형식을 반환합니다.

때때로 젭과 젠스의 대답이 작동하지 않고 null을 반환합니다.이 경우에는 다음 솔루션을 사용합니다.파일 헤드에는 일반적으로 형식 서명이 포함되어 있습니다.저는 그것을 읽고 서명 목록에서 알려진 것과 비교합니다.

/**
 *
 * @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 유형을 가져올지 모르는 경우 이 에서 적합한 항목을 찾을 수 있습니다.

다양한 파일 형식에 사용할 수 있습니다.그러나 비디오의 경우 MIME 유형을 얻으려면 비디오 코덱을 알아야 하기 때문에 작동하지 않습니다.비디오의 마임 유형을 가져오려면 MediaMetadataRetriver를 사용합니다.

, 표준메소드사마여유임 결 했 다 를 용 하 없 수 유 습 니 다 할 지 확 을 명 장 파 일 사 여 하 용 을 음 지 만 려 고 하 을 MimeTypeMap.getFileExtensionFromUrl(uri.getPath())이 메서드는 빈 문자열을 반환했습니다.그래서 저는 파일 확장자를 유지하기 위해 간단한 솔루션을 만들었습니다.

다음은 파일 확장명을 반환하는 방법입니다.

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

파일 확장자를 유지하면 아래와 같은 MIME 유형을 얻을 수 있습니다.

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

컨텐츠와 파일 모두에서 유연하게 작동합니다.

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

MimeTypeMapflv, syslog, 3gpp, cpp와 같은 일부 하지 못할 수 .따라서 코드를 유지하기 위해 MimeTypeMap을 확장하는 방법을 생각해야 합니다.여기 그러한 예가 있습니다.

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

또한, 여기 마임 유형의 전체 목록이 있습니다.

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

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

자산/파일에서 보내는 동안(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);
}

Content Resolver를 사용하는 동안

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

왜 그런지 모르겠어요MimeTypeMap.getFileExtensionFromUrl().space및일부다반환다니됩문자가른▁s다ers를 합니다.""파일 이름을 허용 가능한 이름으로 변경하기 위해 이 방법을 썼습니다.그냥 가지고 노는 거예요.String하지만, 그것은 효과가 있습니다.방법을 , 그방을통해법,,space하는 문자는 파일이에존여문재문다통로원자음다변해(여기서 "를 통해 .replaceAll(" ", "x")그리고 다른 부적합한 캐릭터들은 다음을 통해 적합한 캐릭터로 바뀝니다.URLEncoder따라서 (질문에 제시된 코드와 선택된 답변에 따른) 사용법은 다음과 같아야 합니다.

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

위 솔루션은 URLConnection을 사용하여 .rar 파일의 경우 null을 반환했습니다.내용 추측이 경우 TypeFromName(url)이 작동했습니다.

로컬 파일에서 mime:

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

확장자를 수 예를 들어, 1-message 예다 선다 있습니 권 : 1-String filename = uri.getLastPathSegment(); 링크 보기

2-이 코드도 사용할 수 있습니다.

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

하지만 이것은 좋은 접근법이 아닙니다. 3-파일의 URI가 있는 경우 이 코드를 사용합니다.

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

4-URL이 있는 경우 다음 코드를 사용합니다.

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


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

return type;
}

코드를 즐기십시오.

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

또한 내 경우 경로가 null 값을 반환했습니다.

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

사용에 관한 일로서.

valurl = inUrl.replace(" ",")

그래서 방법은 다음과 같습니다.

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

결과적으로 성공 결과를 반환합니다.

오디오/오디오

누구에게 도움이 되길 바랍니다.

여기서 완벽한 답은 하나도 없습니다.다음은 모든 주요 답변의 최상의 요소를 결합한 답변입니다.

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

생각에 가장 쉬운 방법은 다음 리소스 파일을 참조하는 것입니다.

언급URL : https://stackoverflow.com/questions/8589645/how-to-determine-mime-type-of-file-in-android