华为手机上使用MediaMetadataRetriever. extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO) 无法equals的问题
项目中有一个地方需要用户从SDcard上选择文件,要求选择的文件类型必须是音频文件类型,起初打算直接以判断后缀名的方式去做,后来觉得这种方式太过草率,几经折腾找到了 MediaMetadataRetriever 这个API,这个API有一个很重要的功能就是能够获取音频或视频文件的meta data 信息(比如拿歌曲的比特率,时长),也包含有判断当前文件是否包含视频或音频数据的接口。
于是直接使用:
String hasAudioStr = mMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO);
String hasVideoStr = mMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
上面的Code来判断用户选择的文件是否包含音频数据。通过测试发现如果选择的文件包含有音频数据,那么 hasAudioStr 会返回yes, 注意,这里返回的是字符串形式的yes, 不是布尔值,如果没有包含音频数据,则返回 null, 这个null, 同样也是字符串形式,不是布尔值,
所以我直接使用:
if (hasAudioStr).equals("yes"){}
的形式去判断,这个时候问题来了,代码只要一走到上面的地方,程序就直接闪退了!字符串居然不能通过equals函数比较了!
一时想不出所以然,看了下AOSP的源码:它这个方法是一个native方法,所以这里返回的应该是JNI部分new 的 一个 string:
/** * Call this method after setDataSource(). This method retrieves the * meta data value associated with the keyCode. * * The keyCode currently supported is listed below as METADATA_XXX * constants. With any other value, it returns a null pointer. * * @param keyCode One of the constants listed below at the end of the class. * @return The meta data value associate with the given keyCode on success; * null on failure. */ public native String extractMetadata(int keyCode);
但是不知道怎么回事它这里返回的String, 没办法和java上的String 做比较,看了下别人的示例都是好的,难道就我的手机不行?
一时不想在上面浪费太多时间,便想了个折衷的法子,自己在这个返回的String基础上再new一个String去做比较:
String hasAudioStr = mMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO); String hasVideoStr = mMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO); String fileName = FileUtil.getFileRealNameFromUri(getApplicationContext(), fileUri); Log.w(TAG, "select file uri: " + fileUri + ", fileName: " + fileName + ", hasAudio: " + hasAudioStr + ", hasVideo: " + hasVideoStr); String EXIST_FLAG = "=yes", NOT_EXISTS_FLAG = "=null"; String hasAudioFlag = String.format(Locale.getDefault(), "%s%s", "=", hasAudioStr); String hasVideoFlag = String.format(Locale.getDefault(), "%s%s", "=", hasVideoStr); if (hasAudioFlag.equalsIgnoreCase(EXIST_FLAG) && hasVideoFlag.equalsIgnoreCase(NOT_EXISTS_FLAG)) { Log.w(TAG, "select file is an audio file"); }
这样就可以了,再次运行没有闪退,判断 hasVideoFlag为null 的原因是因为视频里面也包含有音频流,而我只是单纯的想获取音频文件。
不知道是不是只有华为手机有这个问题,我测试的华为手机型号是:华为G9 Plus 电信版。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库