iOS-使用AudioServices相关接口的连续震动

点击上方“程序员大咖”,选择“置顶公众号”

关键时刻,第一时间送达!640?640?wx_fmt=gif


作者:煜寒了  來源:简书

文:https://www.jianshu.com/p/dded314dd920

程序员大咖整理发布,转载请联系作者获得授权


本文使用底层接口,实现 iOS 设备上的连续震动,以及连续播放系统声音(不是音乐播放器)

主要功能函数

/*!
    @function       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)

void soundCompleteCallback(SystemSoundID sound,void * clientData) {
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);  //震动
    AudioServicesPlaySystemSound(sound);  // 播放系统声音 这里的sound是我自定义的,不要 copy 哈,没有的
}

实现播放声音或震动的代码

    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);

至此,就可以顺利的播放声音和震动了,而且是连续的!!!
别忘了! 怎么让他停下来
为了方便 我就写了而一个 ObjC 的方法来做了

-(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,回调方法就停止。

经过测试发现震动之间太连续,体验不符合要求;所以我们在 C 回调里面通过单例(全局变量性质的指针)调用到 ObjC 的方法进行

[self performSelector:@selector(triggerShake) withObject:nil afterDelay:1]

triggerShake 是震动接口,在停止震动时候我们需要调用下面的方法

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(triggerShake)  object:nil];

停止之前可能存在的回调;这两个方法的成对使用既好用又简便,对于需要定时调用的场景很适合,也免去维护定时器的麻烦。

这个时候屏幕要是常亮就更好了

[[UIApplication sharedApplication] setIdleTimerDisabled:YES];   // 设置播放时屏幕常亮

同样,别忘了结束的时候设置为 NO


640?wx_fmt=gif640?【点击成为源码大神】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值