zoukankan      html  css  js  c++  java
  • MediaMetadataRetriever : 华为手机上使用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 电信版。

  • 相关阅读:
    Spire.Barcode好用的条码生在组件
    jQuery、js操作页面
    设计模式---简介
    设计模式---策略设计模式
    POI生成Excel文件:Excel,工具类,背景色,边框,居中,合并单元格
    设计模式---模板设计模式(java)
    maven打包不打lib目录里面的jar包解决办法
    MySQL库表操作
    Linux环境根据data目录文件恢复MySQL数据
    Linux 安装 mysql 与 mysql在Linux环境本地使用,但windows远程连不了问题处理
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/13043769.html
Copyright © 2011-2022 走看看