【ios】ios7以上 使用MPVolumeView獲取系統音量

衆所周知,ios7已經廢棄了MPMusicPlayerControllerios

ios7如下使用[[MPMusicPlayerController applicationMusicPlayer] setVolume:value];app

那麼ios7以上呢?使用MPVolumeView。ide

然而MPVolumeView有其侷限性,MPVolumeView的subviews中的MPVolumeSlider的value值,即系統音量值(取值[0,1])post

當我第一次在viewWillAppear的時候,獲取其中的MPVolumeSlider,會獲取不到;atom

因此嘗試在viewDidAppear,這一次很開心,獲取到了;spa

然而,以後發如今某些設備的一倍屏下,仍然獲取不到,或第一次獲取不到,第二次能夠獲取到code

因此,本文采用將MPVolumeView加入window.subview的形式,提早將MPVolumeView加入視圖,做爲全局的一個視圖。server

 

 

這樣的作法有助於分離音量與主業務邏輯,充分解耦blog

 

KEVolumeUtil.h
#define Volume_Change_Notification @"Volume_Change_Notification"

@interface KEVolumeUtil : NSObject

@property (nonatomic,assign) CGFloat volumeValue;

+ (KEVolumeUtil *) shareInstance;

-(void)loadMPVolumeView;

- (void)registerVolumeChangeEvent;

- (void)unregisterVolumeChangeEvent;

@end

  

KEVolumeUtil.m
#import "KEVolumeUtil.h"
#import "KEAppDelegate.h"
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>

@interface KEVolumeUtil()

@property (nonatomic, strong) MPVolumeView *mpVolumeView;

@property (nonatomic, strong) UISlider *slider;

@end

@implementation KEVolumeUtil

@synthesize volumeValue = _volumeValue;

#pragma mark public methods
+(KEVolumeUtil *) shareInstance
{
    static KEVolumeUtil *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once (&predicate, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (void) loadMPVolumeView
{
    UIWindow *window = [KEAppDelegate globalAppDelegate].window;
    [window addSubview:self.mpVolumeView];
  
  [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:NULL];

}

- (void)registerVolumeChangeEvent
{
    NSError *error;
    [[AVAudioSession sharedInstance] setActive:YES error:&error];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChangedNotification:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}

- (void)unregisterVolumeChangeEvent
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}

#pragma mark private methods
-(void) generateMPVolumeSlider
{
    for (UIView *view in [self.mpVolumeView subviews]){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            self.slider = (UISlider*)view;
            break;
        }
    }
}

#pragma mark setters
-(void) setVolumeValue:(CGFloat) newValue
{
    _volumeValue = newValue;
    
    //確保self.slider != nil
    if (!self.slider) {
        [self generateMPVolumeSlider];
    }
    self.slider.value = newValue;
}

#pragma mark getters
-(CGFloat) volumeValue
{
    //確保self.slider != nil
    if (!self.slider) {
        [self generateMPVolumeSlider];
    }
    return self.slider.value;
}

-(MPVolumeView *) mpVolumeView
{
    if (!_mpVolumeView) {
        _mpVolumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(0, 50, 100, 100)];
        _mpVolumeView.hidden = YES;
    }
    return _mpVolumeView;
}

#pragma mark notification
- (void)volumeChangedNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = notification.userInfo;
    float value = [[userInfo objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
    self.volumeValue = value;
    
    [[NSNotificationCenter defaultCenter] postNotificationName:Volume_Change_Notification object:nil];
}

@end
相關文章
相關標籤/搜索