摘要:本文使用底層介面,實現iOS裝置上的連續震動,以及連續播放系統聲音(不是音樂播放器哦)
話不多說,先上程式碼!!!喜歡就點贊
主要功能函式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/*! <a href='http://www.jobbole.com/members/cm00000000mol'>@function</a> AudioServicesAddSystemSoundCompletion @abstract Call the provided Completion Routine when provided SystemSoundID finishes playing. @discussion Once set, the System Sound server will send a message to the System Sound client indicating which SystemSoundID has finished playing. @param inSystemSoundID systemSoundID 自定義的sound(1007系統預設提示音)或者kSystemSoundID_Vibrate(震動) @param inRunLoop 沒有研究 一般寫NULL 有興趣可以自己研究一下跟大家共享 @param inRunLoopMode 同上個屬性 @param inCompletionRoutine 這個是指某次震動播放完成後的回撥 注意是C的函式 一般我們會在回撥中寫播放震動的函式 來實現連續震動 @param inClientData 沒有研究啦!!!NULL就行啦 */ extern OSStatus AudioServicesAddSystemSoundCompletion( SystemSoundID inSystemSoundID, CFRunLoopRef inRunLoop, CFStringRef inRunLoopMode, AudioServicesSystemSoundCompletionProc inCompletionRoutine, void* inClientData) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0); |
首先實現上述函式中的回撥函式(注意是C)
1 2 3 4 |
void soundCompleteCallback(SystemSoundID sound,void * clientData) { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); //震動 AudioServicesPlaySystemSound(sound); // 播放系統聲音 這裡的sound是我自定義的,不要copy哈,沒有的 } |
實現播放聲音或震動的程式碼
1 2 3 4 5 6 7 |
SystemSoundID sound; NSString *path = [[NSBundle mainBundle] pathForResource:soundName ofType:nil]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &_sound); AudioServicesAddSystemSoundCompletion(_soundID, NULL, NULL, soundCompleteCallback, NULL); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); AudioServicesPlaySystemSound(_sound); |
至此,就可以順利的播放聲音和震動了,而且是連續的哦!!!
別忘了! 怎麼讓他停下來
為了方便 我就寫了而一個OC的方法來做了
1 2 3 4 5 |
-(void)stopAlertSoundWithSoundID:(SystemSoundID)sound { AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate); AudioServicesDisposeSystemSoundID(sound); AudioServicesRemoveSystemSoundCompletion(sound); } |
這裡要詳細解說一下需要注意的事項:
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, systemAudioCallback, NULL);
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
這兩個介面的用途是繫結和取消指定soundID對應的回撥方法;kSystemSoundID_Vibrate為soundID
型別,其回撥方法認準的也是這個soundID,在任何地方使用這個id去執行AudioServicesPlaySystemSound(xxxSoundID)
都會呼叫到該回撥方法。而一旦呼叫remove方法取消回撥,同樣的在任何地方使用這個id去執行AudioServicesPlaySystemSound(xxxSoundID)
都不會呼叫到這個回撥。說的這麼繞,其實就是說這倆介面的影響是全域性的,威力很大。
我們只要在回撥方法裡面再呼叫AudioServicesPlaySystemSound介面,就可以實現連續震動了;當我們想要停止震動時,呼叫remove介面,ok,回撥方法就歇火了。
優化:(參考某大神的部落格,名字太長,直接附連結)
http://blog.csdn.net/openglnewbee/article/details/8494598
經過測試發現震動之間太連續,體驗不符合要求;所以我們在c回撥裡面通過單例(全域性變數性質的指標)呼叫到oc的方法進行[self performSelector:@selector(triggerShake) withObject:nil afterDelay:1]
(triggerShake是震動介面);在停止震動時候我們需要呼叫
1 |
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(triggerShake) object:nil]; |
停止之前可能的回撥;這兩個方法的成對使用既好用又簡便,對於需要定時呼叫的場景很適合,也免去維護定時器的麻煩。
這個時候螢幕要是常亮就更好了,不用費腦子了,用這個!!!
1 |
[[UIApplication sharedApplication] setIdleTimerDisabled:YES]; // 設定播放時螢幕常亮 |
同樣,別忘了結束的時候置NO,否則就會一直亮著了!!!
附圖(建議大家想想一下連續震動的感覺):
進一步交流 QQ群:361736344