iOS 系统声音和振动控制SystemSoundServices的使用

特点

1.限制:用于播放不超过30秒的声音
2.支持格式:CAF、AIF和使用PCM或IMA/ADPCM数据的WAV文件
3.其他:没有提供操纵声音和控制音量的功能

功能

  1. 声音:播放声音文件。如果手机被设置为静音,用户什么也听不到
  2. 提醒:播放一个声音文件且震动,如果手机被设置为静音或震动,将通过震动提醒用户
  3. 震动:手机震动

准备工作

导入框架:#import 

要实现的功能

iOS 系统声音和振动控制SystemSoundServices的使用_第1张图片

如上图,通过上面的UISiwtch控件来控制打开或关闭对应的功能,通过下面UIButton控件来检测该功能的有效性。
这里主要实现的是四个功能:控制声音,控制震动,控制提醒,自定义提示声音

实现过程

一般在项目中,使用到通知提示,都是全局的,在工程中全局可用,所以在这里使用单例,将声音的获取方法,初始化方法,播放方法,释放方法都写在单独的类中,并把这个类写成单例。而在外部,只需要调用单例的获取,和播放/释放方法就可以了

先写单例类

先看单例类SoundControlSingle.h文件中的代码

#import 
#import //引入头框架的文件
@interface SoundControlSingle : NSObject
@property(nonatomic,assign)SystemSoundID soundID;//播放文件标识
//获取震动、声音、自定义声音对象的方法
+ (id) sharedInstanceForVibrate;
+ (id) sharedInstanceForSound;
+ (id) sharedInstanceForProjectSound;
/**
 *  @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;
//播放声音或者震动
-(void)play;
//播放提醒
-(void)playRemind;
//取消声音
-(void)cancleSound;

在SoundControlSingle.m文件中实现个方法

#import "SoundControlSingle.h"

@implementation SoundControlSingle
static SoundControlSingle *_sharedInstance;//震动对象全局变量
static SoundControlSingle *_sharedInstanceForSound;//声音对象全局变量
static SoundControlSingle *_sharedInstanceForProjectSound;//自定义声音对象全局变量
#pragma mark -- 实现获取各对象的方法
//获取震动对象
+(id)sharedInstanceForVibrate
{
    @synchronized ([SoundControlSingle class]) {
        if (_sharedInstance == nil) {
            _sharedInstance = [[SoundControlSingle alloc] initForPlayingVibrate];
        }
    }
    return _sharedInstance;
}
//获取声音
+ (id)sharedInstanceForSound
{
    @synchronized ([SoundControlSingle class]) {
        if (_sharedInstanceForSound == nil) {
            _sharedInstanceForSound = [[SoundControlSingle alloc] initForPlayingSystemSoundEffectWith:@"sms-received2" ofType:@"caf"];
        }
    }
    return _sharedInstanceForSound;
}
//播放自定义声音
+ (id)sharedInstanceForProjectSound{
    @synchronized ([SoundControlSingle class]) {
        if (_sharedInstanceForProjectSound == nil) {
            _sharedInstanceForProjectSound = [[SoundControlSingle alloc] initForPlayingSoundEffectWith:@"unbelievable.caf"];
        }
    }
    return _sharedInstanceForProjectSound;
}
#pragma mark -- 各对象的初始化方法
-(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 = [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)playRemind{
    AudioServicesPlayAlertSound(_soundID);//提醒功能
}
//单例对象置为空
-(void)cancleSound
{
    _sharedInstance=nil;
    _sharedInstanceForSound = nil;
    _sharedInstanceForProjectSound = nil;
}
//释放声音对象
-(void)dealloc{
    AudioServicesDisposeSystemSoundID(_soundID);
}
使用单例类

因为是四个功能,所以创建四个BOOL值,记录四个功能的开启关闭状态

@property(nonatomic,assign)BOOL isSoundOpen;//声音打开
@property(nonatomic,assign)BOOL isProjectSoundOpen;//声音打开
@property(nonatomic,assign)BOOL isShakeOpen;//震动打开
@property(nonatomic,assign)BOOL isRemindOpen;//提醒控制

初始化四个变量

self.isShakeOpen = self.isSoundOpen = self.isProjectSoundOpen = self.isRemindOpen =  YES;

获取开关的状态,并用布尔值记录

//声音控制
- (IBAction)soundControlAction:(UISwitch *)sender {
    if (sender.on) {
        self.isSoundOpen = YES;
    } else {
        self.isSoundOpen = NO;
    }
}
//震动控制
- (IBAction)shakeControlAction:(UISwitch *)sender {
    if (sender.on) {
        self.isShakeOpen = YES;
    } else {
        self.isShakeOpen = NO;
    }
}
//项目中的音频文件
- (IBAction)projectSound:(UISwitch *)sender {
    if (sender.on) {
        self.isProjectSoundOpen = YES;
    } else {
        self.isProjectSoundOpen = NO;
    }
    
}
//提醒控制
- (IBAction)remindControlAction:(UISwitch *)sender {
    if (sender.on) {
        self.isRemindOpen = YES;
    } else {
        self.isRemindOpen = NO;
    }
}

点击对应按钮进行播放对应的提示

//声音测试
- (IBAction)soundText:(UIButton *)sender {
    SoundControlSingle * single1 = [SoundControlSingle sharedInstanceForSound];//获取声音对象
    SoundControlSingle * single2 = [SoundControlSingle sharedInstanceForProjectSound];//获取自定义声音对象
    if (self.isProjectSoundOpen) {//如果播放自定义提示音的开关是打开的
        [single2 play];//播放
        return;
    }
    if (self.isSoundOpen) {//播放提示音的开关是打开的
        [single1 play];//播放
    }
}
//震动测试
- (IBAction)shakeText:(UIButton *)sender {
    SoundControlSingle * single = [SoundControlSingle sharedInstanceForVibrate];
    if (self.isShakeOpen) {
        [single play];
    }
}
//提醒测试
- (IBAction)remindText:(UIButton *)sender {
    SoundControlSingle * single = [SoundControlSingle sharedInstanceForSound];
    if (self.isRemindOpen) {
        [single playRemind];//播放提示
    }
}
注意

1.使用自定义音频文件,则需要把音频文件拖入到工程
2.手机静音状态下,声音提示是无效的,震动有效,提醒也有效(只有震动无声音);手机正常状态下,声音提示有效,震动有效,提醒也有效(震动+声音)

Demo下载

你可能感兴趣的:(iOS 系统声音和振动控制SystemSoundServices的使用)