項目中有一個地方需要用戶從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 電信版。