在项目中使用AudioServicesPlaySystemSound 这个接口来进行声音和震动的播放, 当然需要在工程中加入AudioToolBox.framework
我们可以写一个文件来封装声音和震动的各项功能,调用时使用单例比较方便。
我写的文件messageSound
在messageSound.h文件中
import <Foundation/Foundation.h>
import <UIKit/UIKit.h>
import <AudioToolbox/AudioToolbox.h>
@interface messageSound : NSObject
{
SystemSoundID soundID;
}
@property (nonatomic,assign) BOOL isON;
//分别为震动和声音设置的系统单列
- (id) sharedInstanceForVibrate;
- (id) sharedInstanceForSound;
/**
*@brief 为震动效果初始化
*@return self
*/
-(id)initForPlayingVibrate;
/**
@brief 为播放系统音效初始化(无需提供音频文件)
@param resourceName 系统音效名称
@param type 系统音效类型
@return self
*/
-(id)initForPlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString )type;
/
@brief 为播放特定的音频文件初始化 (需提供音频文件)
*@param filename 音频文件名(加在工程中)
*@return self
*/
-(id)initForPlayingSoundEffectWith:(NSString )filename;
/
- @brief 播放音效
*/
-(void)play;
-(void)cancleSound;
@end
在message.m文件中代码如下
import "messageSound.h"
@implementation messageSound
static messageSound *_sharedInstance;
static messageSound *_sharedInstanceForSound;
+(id)sharedInstanceForVibrate
{
@synchronized ([messageSound class]) {
if (_sharedInstance == nil) {
_sharedInstance = [[messageSound alloc] initForPlayingVibrate];
}
}
return _sharedInstance;
}
-
(id) sharedInstanceForSound
{
@synchronized ([messageSound class]) {if (_sharedInstanceForSound == nil) { _sharedInstanceForSound = [[messageSound alloc] initForPlayingSystemSoundEffectWith:@"sms-received2" ofType:@"caf"]; }
}
return _sharedInstanceForSound;
}
-(id)initForPlayingVibrate
{
self=[super init];if(self){
soundID=kSystemSoundID_Vibrate;
}
return self;
}
-(id)initForPlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString *)type
{
self=[super init];
if(self){
// NSString *path=[[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] pathForResource:resourceName ofType:type];
NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@.%@",resourceName,type];
if(path){
SystemSoundID theSoundID;
OSStatus error =AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&theSoundID);
if(error == kAudioServicesNoError){
soundID=theSoundID;
}else{
NSLog(@"Failed to create sound");
}
}
}
return self;
}
-(id)initForPlayingSoundEffectWith:(NSString *)filename
{
self=[super init];
if(self){
NSURL *fileURL=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];
if(fileURL!=nil){
SystemSoundID theSoundID;
OSStatus error=AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID);
if(error ==kAudioServicesNoError){
soundID=theSoundID;
}else{
NSLog(@"Failed to create sound");
}
}
}
return self;
}
-(void)play
{
AudioServicesPlaySystemSound(soundID);
}
-(void)cancleSound
{
_sharedInstance=nil;
//AudioServicesRemoveSystemSoundCompletion(soundID);
}
-(void)dealloc
{
AudioServicesDisposeSystemSoundID(soundID);
}
@end
至于怎么使用,我是这么用的,在appdelegate.m文件中开启系统音效设置的单例
//设置系统音效
[messageSound sharedInstanceForSound];
//设置系统震动
[messageSound sharedInstanceForVibrate];
在app设置中,把声音和震动着两个开关的状态保存在本地设置文件中,在播放系统音效的地方,读取本地设置文件的开关状态,根据状态来判断播放声音还是播放震动或者二者兼有,代码如下。(音效文件我是通过yyCache保存在本地的)
messageSound *ms=[messageSound sharedInstanceForVibrate];
messageSound *ms1=[messageSound sharedInstanceForSound];
NSDictionary *localDict;
if([[YYCache sharedInstance]containsObjectForKey:[NSString stringWithFormat:@"%@%@",[AccountTools sharedAccountTools].currentAccount.uid,@"messageSoundSetting"]]==YES)
{
localDict=[[YYCache sharedInstance] objectForKey:[NSString stringWithFormat:@"%@%@",[AccountTools sharedAccountTools].currentAccount.uid,@"messageSoundSetting"]];
if([[localDict objectForKey:@"Sound"] intValue]==1)
{
[ms1 play];
}
if([[localDict objectForKey:@"Vibrate"] intValue]==1)
{
[ms play];
}
}
这样就实现了,微信设置中那种单独设置声音和震动的效果。
//示例
pragma mark - 震动
-
(void)vibratesStateWith:(BOOL)isStart{
isStart ? AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) : AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
}
pragma mark - 声音
-
(void)voiceStateWith:(BOOL)isStart{
isStart ? AudioServicesPlaySystemSound(1007) : AudioServicesDisposeSystemSoundID(1007);
}