在 iOS 設(shè)備中法严,主要有以下兩種類型的聲音:
鈴聲和提醒:包括電話肥哎、短信、通知等系統(tǒng)類的聲音(也包括按鍵音坐榆、鎖定聲拴魄,這兩者可在設(shè)置中設(shè)置是否開啟),它們受物理靜音開關(guān)鍵的控制席镀,也就是說(shuō)匹中,當(dāng)設(shè)備開啟靜音時(shí),這些聲音是不會(huì)播放的豪诲。
媒體聲音:一般為 App 播放音視頻時(shí)的聲音顶捷,音量大小可通過(guò)物理音量 + - 鍵來(lái)控制,但它不受設(shè)備靜音開關(guān)鍵的控制屎篱,即當(dāng)靜音鍵開啟時(shí)服赎,我們?nèi)匀豢梢酝ㄟ^(guò)相關(guān) API 正常播放聲音。
因此交播,這里說(shuō)的靜音分為兩種情況重虑,“通過(guò)物理靜音鍵開啟靜音” 和 “將媒體音量調(diào)小至 0”。對(duì)于后者比較簡(jiǎn)單秦士,我們可以通過(guò)?[AVAudioSession sharedInstance].outputVolume?獲取當(dāng)前音量大小是否為 0 來(lái)判斷缺厉。
下面我們介紹一下如何檢測(cè)設(shè)備靜音開關(guān)鍵的狀態(tài)。
在 iOS 5 之前隧土,我們可以使用以下方式判斷靜音鍵的開關(guān):
- (BOOL)isMuted {
CFStringRefroute;
UInt32routeSize =sizeof(CFStringRef);
? ? OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routeSize, &route);
if(status == kAudioSessionNoError) {
if(route ==NULL|| !CFStringGetLength(route))
returnYES;
? ? }
returnNO;
}
但蘋果在 iOS 5 之后禁止了這種方式的使用提针,并且也沒(méi)有提供相關(guān)新的 API 來(lái)判斷,于是網(wǎng)上有一種曲線救國(guó)的方式曹傀,大致實(shí)現(xiàn)為:
使用 AudioServicesPlaySystemSound 函數(shù)播放一段極短的空白音頻(假設(shè)為 0.2s)关贵,并監(jiān)聽音頻播放完成事件,如果從開始播放到回調(diào)完成方法的間隔時(shí)間小于 0.1s卖毁,則意味當(dāng)前靜音開關(guān)為開啟狀態(tài)揖曾。這是因?yàn)槁湮珹udioServicesPlaySystemSound 有一個(gè)特性是:它播放的聲音屬于系統(tǒng)音效,所以是受靜音按鍵控制的炭剪,且如果當(dāng)前處于靜音模式的話练链,調(diào)用此函數(shù)后會(huì)立即執(zhí)行播放完成的回調(diào),這樣計(jì)算得到的時(shí)間間隔會(huì)很小奴拦,就可以用來(lái)判斷設(shè)備是否靜音了媒鼓。代碼大致如下:
staticCFTimeIntervalstartPlayTime;
- (void)monitorMute {
// 記錄開始播放的時(shí)間
startPlayTime =CACurrentMediaTime();
// 假設(shè)本地存放一個(gè)長(zhǎng)度為 0.2s 的空白音頻,detection.aiff
CFURLRefsoundFileURLRef =CFBundleCopyResourceURL(CFBundleGetMainBundle(),CFSTR("detection"),CFSTR("aiff"),NULL);
? ? SystemSoundID soundFileID;
? ? AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileID);
AudioServicesAddSystemSoundCompletion(soundFileID,NULL,NULL, PlaySoundCompletionBlock, (__bridgevoid*)self);
? ? AudioServicesPlaySystemSound(soundFileID);
}
staticvoidPlaySoundCompletionBlock(SystemSoundID SSID,void*clientData) {
? ? AudioServicesRemoveSystemSoundCompletion(SSID);
// 播放結(jié)束時(shí)错妖,記錄時(shí)間差绿鸣,如果小于 0.1s,則認(rèn)為是靜音
CFTimeIntervalplayDuring =CACurrentMediaTime() - startPlayTime;
if(playDuring <0.1) {
NSLog(@"靜音");
}else{
NSLog(@"非靜音");
? ? }
}