我正在开发一个在后台播放音频的iPhone应用程序。如果用户锁定屏幕,我希望音频继续播放,但如果他们决定切换到另一个应用程序(通过按主页按钮)则暂停播放。如何在iOS5上区分屏幕锁定和主页按钮?
在iOS 4上没有问题,因为当屏幕被锁定时,应用程序将进入非活动状态,并且只有在按下主屏幕按钮时才会移动到背景。在iOS 5上,当屏幕被锁定时,应用程序现在也移动到背景中,所以看起来不再可能区分这两种状态。有没有解决这个问题的方法?
我正在开发一个在后台播放音频的iPhone应用程序。如果用户锁定屏幕,我希望音频继续播放,但如果他们决定切换到另一个应用程序(通过按主页按钮)则暂停播放。如何在iOS5上区分屏幕锁定和主页按钮?
在iOS 4上没有问题,因为当屏幕被锁定时,应用程序将进入非活动状态,并且只有在按下主屏幕按钮时才会移动到背景。在iOS 5上,当屏幕被锁定时,应用程序现在也移动到背景中,所以看起来不再可能区分这两种状态。有没有解决这个问题的方法?
有一种方法来获得这种行为,但它带有一个警告。您必须在Info.plist中设置音频背景模式,并禁用应用程序的多任务处理。
设置音频会话类别来AVAudioSessionCategoryPlayback:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &error];
在你Info.plist文件,添加键值“所需的背景模式”,并添加项目“应用程序播放音频”。然后添加键值“应用程序不能在后台运行”,并将其设置为“yes”
现在,锁屏就会把你的应用程序在背景音频模式(音频保持运行),同时按下home键将终止你的应用程序(并沉默音频)。当用户从其他应用程序返回到您的应用程序时,它将再次启动。因此,如果您的应用加载时间不会太长,并且您可以在重新启动后返回到之前的状态,则这可能是一个可行的解决方案。
我已经用iOS 4.3和iOS 5.0.1(在设备上)测试过它。
不幸的是,这种配置现在违反了Apple的验证程序。当我去验证我的应用程序时,我得到了以下问题:“如果UIApplicationExitsOnSuspend的值为Yes,那么您的应用程序不能在UIBackgroundModes键中指定任何值。如果您的应用程序使用后台服务,则UIApplicationExitsOnSuspend的值必须为No.信息,请参阅信息属性列表关键参考。“ – adamcohenrose
太糟糕了。这是一个黑客无论如何 –
您可以通过检查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");
}
}
当applicationDidEnterBackground被触发时,挂起UIApplicationState已经很好地工作了。可悲的是,现在已经改变了。
当我用XCode5编译我的应用程序以支持所有iOS7的东西(但仍然将生成目标设置为5.0)时,锁定屏幕给出了现在的状态UIApplicationStateBackground,当时我之前得到了UIApplicationStateInactive。
我从Apple支持部门询问了他们,他们证实,这是从现在开始的工作方式。因此,无法检测用户是按Home还是屏幕锁定。这很让人伤心,因为我有很好的用例来检测它。
PS。在iOS7上运行时,使用XCode 4构建的应用程序仍旧可以工作。
你可以添加一个链接到你的开发论坛帖子?这对有访问权限的人有用。 – Abizern
我发现了一个更好的方法来做这件事。
Differentiate between screen lock and home button press on iOS7
这不仅可以帮助您在iOS5的& iOS6的& iOS7设备:),但它不会在iPhone模拟器工作。
在iOS7之前,您可以通过[[UIApplication sharedApplication] applicationState]
来判断它是锁定屏幕还是带有UIApplicationStateInactive
和UIApplicationStateBackground
的主页按钮。
但是这些在iOS7上成为相同的状态UIApplicationStateBackground
,您可以通过屏幕亮度来判断它。
锁屏状态下屏幕亮度应为0;否则,它是主页按钮状态。
你可以把代码片段中- (void)applicationDidEnterBackground:(UIApplication *)application
- (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通知中心。理想情况下,我们可以找到我们有能力注册的所有系统通知的列表,并希望弹出一些东西 – Rich86man
只要您相应地配置音频会话,操作系统就会为您解决这个问题,或者看起来如此(我我不是一个音频程序员)。如果您在文档中搜索“屏幕锁定”,您可以在“音频会话编程指南”(音频会话手册)中找到应该对您有帮助的信息。 –
可能重复的[是否有可能区分锁定设备和发送应用程序到背景?](http://stackoverflow.com/questions/7754317/is-it-possible-to-distinguish-between-locking-the -device-and-sending-an-app-to-b) – Pang