Android中无扩展名Content URI的文件类型精准识别方案咨询
解决方案
1. 优化系统MIME类型获取逻辑
首先可以简化并优化获取系统MIME类型的代码——Android的ContentResolver.getType(Uri)方法已经封装了查询COLUMN_MIME_TYPE的逻辑,比手动操作Cursor更简洁可靠:
ContentResolver contentResolver = getContentResolver(); String mimeType = contentResolver.getType(uri);
这个方法会优先从内容提供者的元数据中获取MIME类型,是最优先的可靠来源。
2. 改进Apache Tika的类型检测逻辑
你遇到的Tika将CSS/JS/JSON识别为text/plain的问题,是因为默认Tika实例仅启用了基础检测器,未加载针对文本子类的细分检测器。可以通过以下两种方式修复:
方式一:加载Tika完整配置(推荐)
使用TikaConfig初始化检测器,它会加载所有内置类型检测器,包括JSON、CSS、JS等细分类型:
import org.apache.tika.TikaConfig; import org.apache.tika.detect.Detector; import org.apache.tika.metadata.Metadata; import org.apache.tika.exception.TikaException; public static String detectMimeTypeUsingTika(Uri uri, ContentResolver contentResolver) { try (InputStream inputStream = contentResolver.openInputStream(uri)) { // 加载Tika默认完整配置 TikaConfig config = TikaConfig.getDefaultConfig(); Detector detector = config.getDetector(); Metadata metadata = new Metadata(); // 执行类型检测 return detector.detect(inputStream, metadata); } catch (IOException | TikaException e) { e.printStackTrace(); } return null; }
方式二:手动添加特定细分检测器
如果仅需针对目标类型(JSON/CSS/JS)优化,可以手动组合对应检测器:
import org.apache.tika.detect.CompositeDetector; import org.apache.tika.detect.Detector; import org.apache.tika.metadata.Metadata; import org.apache.tika.parser.json.JsonDetector; import org.apache.tika.parser.css.CssDetector; import org.apache.tika.parser.javascript.JavaScriptDetector; import org.apache.tika.parser.text.TextDetector; public static String detectMimeTypeUsingTika(Uri uri, ContentResolver contentResolver) { try (InputStream inputStream = contentResolver.openInputStream(uri)) { // 组合目标检测器,TextDetector作为兜底 Detector detector = new CompositeDetector( new JsonDetector(), new CssDetector(), new JavaScriptDetector(), new TextDetector() ); Metadata metadata = new Metadata(); return detector.detect(inputStream, metadata); } catch (IOException e) { e.printStackTrace(); } return null; }
3. 完整的类型检测流程
将两种方式结合,形成可靠的检测逻辑:
- 优先获取系统提供的MIME类型
- 当系统返回
null、application/force-download或text/plain时,调用优化后的Tika方法二次检测
public String getReliableMimeType(Uri uri) { ContentResolver contentResolver = getContentResolver(); String mimeType = contentResolver.getType(uri); // 需要二次检测的场景 if (mimeType == null || "application/force-download".equals(mimeType) || "text/plain".equals(mimeType)) { mimeType = detectMimeTypeUsingTika(uri, contentResolver); } // 最终兜底返回text/plain return mimeType != null ? mimeType : "text/plain"; }
注意事项
- Tika依赖:确保项目引入正确的Tika依赖,比如通过Gradle/Maven引入
tika-core和tika-parsers-standard-package(完整包),或对应的子模块(如tika-parser-json、tika-parser-css等)。 - 资源泄漏:使用
try-with-resources语法自动关闭InputStream,避免资源泄漏(你之前的代码未处理流关闭,这是需要修复的问题)。
内容的提问来源于stack exchange,提问作者David Feldman
相关产品推荐
相关产品推荐

