【问题标题】:How to determine MIME type of file in android?如何确定android中文件的MIME类型?
【发布时间】:2012-01-25 06:06:37
【问题描述】:

假设我有一个完整的文件路径,例如:(/sdcard/tlogo.png)。我想知道它的 mime 类型。

我为它创建了一个函数

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

【问题讨论】:

    标签: android filesystems mime-types


    【解决方案1】:

    首先,您应该考虑致电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;
    }
    

    【讨论】:

    • 感谢为我工作,我的问题的另一个解决方案是: public static String getMimeType(String path, Context context) { String extension = path.substring(path.lastIndexOf(".") ); String mimeTypeMap =MimeTypeMap.getFileExtensionFromUrl(extention);字符串 mimeType = MimeTypeMap.getSingleton() .getMimeTypeFromExtension(mimeTypeMap);返回 mimeType;}
    • 如果文件没有好的扩展名?一个人可以制作一个.mp3,它包含文本
    • 然后您需要实际打开文件并检查导入中的幻数(取决于 c 的格式) - 但是,这也假定将 txt-files 重命名为的人mp3 不只是在他的文本开头写ID3 来更惹你。
    • 这是不可靠的。依赖文件扩展名并从中确定文件类型是很糟糕的。我不敢相信@throrin19 提到的这么重要的事情被忽略了。
    • 如果您的文件路径为 /storage/emulated/0/Download/images (4).jpg 并且您要求 mimetype,它会返回 null。
    【解决方案2】:

    上面的 MimeTypeMap 解决方案在我的使用中返回 null。这行得通,而且更容易:

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

    【讨论】:

    • 这个方法也可以返回null。
    • 根据 URI,它看起来可以返回 null 或不返回。似乎没有人知道为什么;-(
    • 如果媒体是从 android 库中选择的,则返回 TYPE。如果从文件管理器中选择,则返回 null。
    • 我可以肯定地确认 Rahul 所说的话,只是测试了一下,他是对的
    • 在某些设备中,如果我从图库中选择图像,它也会返回 null
    【解决方案3】:

    上述解决方案在 .rar 文件的情况下返回 null,在这种情况下使用 URLConnection.guessContentTypeFromName(url) 有效。

    【讨论】:

      【解决方案4】:

      这是我在 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;
          }
      

      【讨论】:

      • 网址?很多网址没有扩展名。例如,此页面没有扩展名。对于 url,您应该使用 new URL(url).openConnection().getRequestProperty("Content-type");
      【解决方案5】:
      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();
      
          }
      

      【讨论】:

      • 非常适合我!但是使用 FilenameUtils.getExetension(path) 来获取文件扩展名怎么样?
      【解决方案6】:

      密切关注umerk44solution 以上。 getMimeTypeFromExtension 调用 guessMimeTypeTypeFromExtension 并且区分大小写。我花了一个下午的时间仔细看了看 - getMimeTypeFromExtension 如果你传递它“JPG”,它将返回 NULL,而如果你传递它“jpg”,它将返回“image/jpeg”。

      【讨论】:

        【解决方案7】:

        MimeTypeMap 可能无法识别某些文件扩展名,例如 flv、mpeg、3gpp、cpp。所以你需要考虑如何扩展 MimeTypeMap 来维护你的代码。这是一个这样的例子。

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

        另外,这里是 mime 类型的完整列表

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

        【讨论】:

          【解决方案8】:

          有时 Jeb 和 Jens 的答案不起作用并返回 null。在这种情况下,我使用以下解决方案。文件头通常包含类型签名。我读了它并与list of 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 是签名数组中的签名索引。例如,

          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 类型,可以在 this table 中找到合适的。

          它适用于很多文件类型。但是对于视频,它不起作用,因为您需要知道视频编解码器才能获得 mime 类型。要获取视频的 mime 类型,我使用 MediaMetadataRetriever

          【讨论】:

            【解决方案9】:

            来自本地文件的 mime:

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

            【讨论】:

              【解决方案10】:

              检测任何文件的 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;
              }
              

              【讨论】:

              • 这应该是正确的答案。 toLowerCase() 成功了。
              • 这是迄今为止最好的答案,但如果文件名有一个特殊字符(在我的例子中是apostrophe),它会惨遭失败。例如。文件名 = Don't go baby.mp3MimeTypeMap.getFileExtensionFromUrl()里面的PatternMatcher不能处理文件名,返回空String; null 出来是 mimetype 字符串!
              • I. Shvedenenko 下面有一个类似但无错误的解决方案,解决了我上面指出的问题。但这个答案是正确方向的指针。
              • 这段代码返回空字符串“/storage/emulated/0/dcim/screenshots/screenshot_20190319-123828_ubl digital app.jpg”。
              • @Abdul 这是因为该路径没有 Uri 方案。它应该以file://content:// 开头。
              【解决方案11】:

              您有多种选择来获取文件的扩展名:如: 1-String filename = uri.getLastPathSegment(); 看到这个link

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

              享受你的代码吧:)

              【讨论】:

                【解决方案12】:
                // 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);}
                

                【讨论】:

                  【解决方案13】:
                  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
                      }
                  

                  【讨论】:

                    【解决方案14】:

                    虽然来自资产/文件(请注意,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);
                    }
                    

                    使用 ContentResolver 时

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

                    【讨论】:

                      【解决方案15】:

                      我尝试使用标准方法来确定 mime 类型,但我无法使用 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;
                      }
                      

                      【讨论】:

                      • 伙计,这确定了此处发布的有关此问题的所有答案!我对所有 Legacy 课程都有同样的问题。问题与您提到的相同,MimeTypeMap.getFileExtensionFromUrl 根据PatternMatcher 的内部实现返回了具有无效字符的文件名的空字符串。这对我完全有用!喜欢它,到目前为止没有问题!
                      • @I. Shvedenenko String extension = file.getName().split("\\.")[1] 也可以工作,从而消除 getExtension() 方法。
                      • 但问题是,如果在创建文件时使用了错误的扩展名怎么办?扩展是否应该是 mime 类型的唯一判断?
                      • 如果文件名中有多个.,您似乎对此解决方案有问题。在 Kotlin 中,val extension: String = file.name.split(".").last() 消除了对getExtension 的需求以及不止一个. 问题。
                      • 如果你还在使用 Java:file.getName().substring(file.getName().lastIndexOf("."))
                      【解决方案16】:

                      Jens' answere 的优化版本,具有 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)

                      奖励:上述方法作为一个不太冗长的Kotlin 扩展函数

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

                      【讨论】:

                      • 这行得通。虽然有点过于冗长,但我喜欢。
                      • 当然这可以写得更短一些。 Kotlin 可能只有两三行,但是 foxus 处于零安全和toLoverCase 部分。
                      • @filthy_wizard,为您添加了优化版本 ;-)
                      • 至于我用 getPath() 方法而不是 toString() 更清楚,只是路径使用 kotlin 属性访问语法。
                      • 我很欣赏彻底,但后备类型无法达到目的。如果您在失败时设置任意值,为什么还要检查?
                      【解决方案17】:

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

                      【讨论】:

                        【解决方案18】:
                        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);
                        }
                        

                        【讨论】:

                          【解决方案19】:

                          也有返回空值 在我的情况下,路径是

                          /storage/emulated/0/Music/01 - 舞池上的幽灵.mp3

                          作为变通使用

                          val url = 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
                              }
                          

                          作为结果返回成功结果:

                          音频/mpeg

                          希望对大家有帮助

                          【讨论】:

                            【解决方案20】:

                            这里没有一个答案是完美的。这是一个结合所有热门答案的最佳元素的答案:

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

                            【讨论】:

                              【解决方案21】:
                              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());
                                                      }
                              

                              【讨论】:

                                【解决方案22】:
                                // 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);
                                }
                                

                                【讨论】:

                                • 请提供一些解释。它将帮助最初的读者调整她/他的代码,并帮助进一步的读者从你的答案中获得最大的价值。
                                • 感谢您的回复。我用解释编辑它。
                                【解决方案23】:

                                我遇到了类似的问题。到目前为止,我知道不同名称的结果可能会有所不同,所以终于找到了这个解决方案。

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

                                【讨论】:

                                  【解决方案24】:

                                  【讨论】:

                                  • 链接失效
                                  【解决方案25】:

                                  我不明白为什么MimeTypeMap.getFileExtensionFromUrl()spaces 和其他一些字符有问题,返回"",但我只是写了这个方法来将文件名更改为允许的文件名。它只是在玩Strings。但是,它有点工作。通过该方法,将文件名中存在的spaces通过replaceAll(" ", "x")转为合适的字符(这里为“x”),其他不合适的字符通过URLEncoder转为合适的字符。所以用法(根据问题中提供的代码和选择的答案)应该类似于 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;
                                      }
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    编辑

                                    我为此创建了一个小型库。 但底层代码几乎相同。

                                    在 GitHub 上可用

                                    MimeMagic-Android

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

                                    这似乎是最好的选择,因为它结合了之前的答案。

                                    首先它会尝试使用 URLConnection.guessContentTypeFromStream 获取类型,但如果失败或返回 null,它会尝试使用 Android O 及更高版本获取 mimetype

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

                                    否则,如果 Android 版本低于 O 或方法失败,则使用 ContentResolver 和 MimeTypeMap 返回类型

                                    【讨论】:

                                    • 关闭InputStream
                                    【解决方案27】:

                                    它对我有用,对内容和文件都很灵活

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

                                    【讨论】:

                                      【解决方案28】:

                                      在 kotlin 中它更简单。

                                      解决方案 1:

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

                                      方案二:(文件扩展功能)

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

                                      【讨论】:

                                        猜你喜欢
                                        • 2013-04-21
                                        • 2016-05-23
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2013-02-09
                                        • 2015-10-22
                                        • 2012-07-26
                                        相关资源
                                        最近更新 更多