iOS 监听物理音量键按键操作 拍照键适配

想监听点击机身音量键的时候,推荐使用“SystemVolumeDidChange”来进行监听。

2025.03.28 更新:
在iOS17.2以上,可直接使用AVCaptureEventInteraction来监测音量键及iPhone16系列的拍照键。

 if (@available(iOS 17.2, *)) {
        __weak typeof(self) weakSelf = self;
        self.captureInteraction = [[AVCaptureEventInteraction alloc] initWithEventHandler:^(AVCaptureEvent * _Nonnull event) {
            if (event.phase == AVCaptureEventPhaseEnded) {
                //...
            }
        }];
        self.captureInteraction.enabled = YES;
        [self.view addInteraction:self.captureInteraction];
    }
       

这个方式可以与下面的通知形式并存。当添加了AVCaptureEventInteraction后,将不会有由于音量变化带来的通知。

添加监听事件

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(systemVolumeDidChange:) name:@"SystemVolumeDidChange" object:nil];

事件触发回调

- (void)systemVolumeDidChange:(NSNotification *)notification {
    BOOL isResign = ;//这里需要去记录是否在后台挂起,由于控制面板的音量调节会触发这个通知
    
    if (isResign) {
        return;
    }
    
    NSDictionary * userInfo = notification.userInfo;
    NSInteger sequenceNumber = [(NSNumber *)[userInfo valueForKey:@"SequenceNumber"] integerValue];
    NSString * audioCategory = [userInfo valueForKey:@"AudioCategory"];
    NSString * reason = [userInfo valueForKey:@"Reason"];
    NSTimeInterval timeCurrent = [[NSDate date] timeIntervalSince1970];

    //过滤重复通知:由于音量调节会有两次通知,两次通知的sequenceNumber是一样的,所以需要过滤掉重复通知。通过记录lastSequenceNum来过滤,同时可以记录lastVolumeNotiTime来限制回调频率
    if (sequenceNumber != self.lastSequenceNum && [reason isEqualToString:@"ExplicitVolumeChange"] && (timeCurrent - self.lastVolumeNotiTime > 1) && [audioCategory isEqualToString:@"Audio/Video"]) {
        self.lastVolumeNotiTime = timeCurrent;
        self.lastSequenceNum = sequenceNumber;
        
        dispatch_async(dispatch_get_main_queue(), ^{
            //进行UI操作
        });
    }
}

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 共2条

请登录后发表评论