Objective c 在iOS5上如何区分屏幕锁定和主页按钮按下?

Objective c 在iOS5上如何区分屏幕锁定和主页按钮按下?,objective-c,ios,ios4,ios5,Objective C,Ios,Ios4,Ios5,我正在开发一款iPhone应用程序,可以在后台播放音频。如果用户锁定屏幕,我希望音频继续播放,但如果他们决定切换到其他应用程序(按home按钮),则暂停播放 在iOS 4上没有问题,因为当屏幕被锁定时,应用程序将进入非活动状态,只有在按下home(主页)按钮时才会移动到后台。在iOS 5上,当屏幕被锁定时,应用程序现在也被移动到后台,因此似乎无法再分辨这两种状态之间的差异。有解决这个问题的方法吗?有一种方法可以解决这个问题,但是有一个警告。您必须在Info.plist中设置音频背景模式,并禁用应

我正在开发一款iPhone应用程序,可以在后台播放音频。如果用户锁定屏幕,我希望音频继续播放,但如果他们决定切换到其他应用程序(按home按钮),则暂停播放


在iOS 4上没有问题,因为当屏幕被锁定时,应用程序将进入非活动状态,只有在按下home(主页)按钮时才会移动到后台。在iOS 5上,当屏幕被锁定时,应用程序现在也被移动到后台,因此似乎无法再分辨这两种状态之间的差异。有解决这个问题的方法吗?

有一种方法可以解决这个问题,但是有一个警告。您必须在Info.plist中设置音频背景模式,并禁用应用程序的多任务处理

将音频会话类别设置为AVAudioSessionCategoryPlayback:

[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &error];
在Info.plist文件中,添加键“Required background modes”并添加项“App plays audio”。然后添加键“应用程序不在后台运行”,并将其设置为“是”

现在,锁定屏幕将使你的应用程序处于音频背景模式(音频保持运行),同时按下主页按钮将终止你的应用程序(并使音频静音)。当用户从另一个应用返回到您的应用时,它将再次启动。因此,如果你的应用程序加载时间不太长,并且你可以在重新启动后返回到以前的状态,这可能是一个可行的解决方案


我已经用iOS 4.3和iOS 5.0.1(在设备上)对其进行了测试。

您可以通过检查
UIApplication
applicationState
属性来区分这两种情况。对于由于锁屏而进入后台的应用程序,它将设置为
UIApplicationStateInactive
,否则将设置为
UIApplicationStateBackground

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIApplicationState state = [application applicationState];
    if (state == UIApplicationStateInactive) {
        NSLog(@"Sent to background by locking screen");
    } else if (state == UIApplicationStateBackground) {
        NSLog(@"Sent to background by home button/switching to other app");
    } 
}

在启动ApplicationIdentinterBackground时查找UIApplicationState工作得很好。可悲的是,这种情况现在已经改变了

当我使用XCode5编译我的应用程序以支持所有iOS7内容(但构建目标仍设置为5.0)时,锁定屏幕显示的是现在的状态UIApplicationStateBackground,而之前我确实将UIApplicationStateInactive设置为Inactive

我问过苹果的技术支持人员,他们确认,从现在起,这就是它的工作方式。所以,无法检测用户是否按下了Home键或Screen lock键。这是可悲的,因为我有很好的用例来检测它


另外,使用XCode 4构建的我的应用程序在iOS7上运行时仍然以旧方式工作

我找到了更好的方法来做这件事

这可以在iOS5&iOS6&iOS7设备上帮助您,但在iOS模拟器上不起作用

您可以在iOS7之前获取
[[UIApplication sharedApplication]applicationState]
来判断它是锁屏还是主页按钮,并使用
UIApplicationStateInactive
UIApplicationStateBackground

但在iOS7上,它们变成了相同的状态
UIApplicationStateBackground
,您可以通过屏幕亮度来判断

在锁屏状态下,屏幕亮度应为0;否则,它是主按钮状态

您可以将代码段放入
-(void)applicationidenterbackground:(UIApplication*)应用程序中

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIApplicationState state = [[UIApplication sharedApplication] applicationState];
    if (state == UIApplicationStateInactive) {
        NSLog(@"Sent to background by locking screen");
    } else if (state == UIApplicationStateBackground) {
        CGFloat screenBrightness = [[UIScreen mainScreen] brightness];
        NSLog(@"Screen brightness: %f", screenBrightness);
        if (screenBrightness > 0.0) {
            NSLog(@"Sent to background by home button/switching to other app");
        } else {
            NSLog(@"Sent to background by locking screen");
        }
    }
}

这是一个恼人的问题,因为任何谷歌搜索都会返回ios5通知中心。理想情况下,我们可以找到所有系统通知的列表,我们有能力注册,并希望操作系统能够为您解决这些问题,只要您相应地配置音频会话,或者看起来是这样(我不是音频程序员)。如果你在文档中搜索“屏幕锁定”,你会在音频会话编程指南(音频会话食谱)中找到对你有帮助的信息。不幸的是,这种配置现在违反了苹果的验证程序。当我去验证我的应用程序时,我遇到了以下问题:“如果UIApplicationExitsOnSuspend的值为是,你的应用程序不得在UIBackgroundModes键中指定任何值。如果你的应用程序使用后台服务,UIApplicationExitsOnSuspend的值必须为否。有关更多信息,请参阅信息属性列表键引用。”太糟糕了。这是一个有点黑客无论如何,这将工作在iOS5太,如果是这样,我建议编辑到您的答案。另外,您能否解释一下在对您的帖子进行编辑时代码在做什么?最好的堆栈溢出答案提供解释以及显示代码。如果你能做到这一点,我将能够删除此向下投票,因为编辑后的帖子有资格更改投票。至于dup的帖子,我怀疑它可能会被合并到这个帖子中,并且会自行解决,因为有几个人标记了它。希望这对您有所帮助,欢迎使用Stack Overflow!:)@我把它改了,可能是我英语上的错误。这对我不起作用。你把这段代码放在哪里?您使用的是哪种设备?@Spectravideo328我已经更新了答案。我已经用iOS7在iPhone5和iOS6在ipodtouch上测试了这段代码。但是它不能在iOS模拟器和iOS7上运行,很抱歉我以前没有提到过。你能给你的开发者论坛帖子添加一个链接吗?它将对那些能够访问的人有用。