【问题标题】:Play a sound on my backgrounded app when the phone is in silent mode当手机处于静音模式时,在我的后台应用程序上播放声音
【发布时间】:2017-04-14 00:23:01
【问题描述】:

我已经构建了一个计时器应用程序,但我遇到的一个问题是当它在后台运行时,如果用户关闭音量,我将无法响起计时器。关闭音量或声音也会使通知静音,这是我用来在后台响铃的方法。

我刚买了一块瓷砖,发现了can ring your phone even on silent。我已经对此进行了测试,它可以在 iOS 9 中运行,但我不确定如何复制这种行为。

如何在静音模式下让 iPhone 响铃?后台刷新?运动和活动?还有什么?

现有技术:

  • this answer 以静音模式播放,但在应用程序关闭时不处理。同样here

【问题讨论】:

  • “关闭”是什么意思? Tile 应用程序必须正在运行。
  • 是的,我想我是故意的。当您在后台运行应用程序时,由操作系统决定何时真正关闭它,以及多久唤醒一次,对吗?
  • 要求用户在没有后台锁定他们的手机。 (留在应用内不受打扰)

标签: ios iphone permissions uikit


【解决方案1】:

首先,为了在后台播放声音,您的应用程序必须能够在后台启动响应回调事件的相关代码。仅允许特定应用类型在后台响应回调事件。例如,“Tile”应用程序可以在后台播放声音,以响应应用程序在后台时触发的 BLE 相关回调事件(例如,BLE 外围设备连接和断开连接)。相反,当应用程序进入后台时,一个简单的计时器会暂停,因此不会触发计时器到期回调,并且在这种情况下无法启动任何代码来播放声音。 (您可以阅读here 了解一些详细信息以及在 iOS 中构建闹钟的可能方法)

如果您的应用程序类型在一组特殊的后台模式应用程序中,即使手机处于静音模式,您也可以使用 AVAudioPlayer 在后台播放响应事件的声音。在您的视图控制器中导入 AVFoundation 框架:

import AVFoundation

比声明一个 AVAudioPlayer 变量

var player: AVAudioPlayer?;

为了播放放在 app bundle 中的 mp3 文件:

    func playSound() {
    
        guard let url = Bundle.main.url(forResource: "MY_MP3_FILE", withExtension: "mp3") else {
            print("error");
            return;
        }
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers);
            player = try AVAudioPlayer(contentsOf: url);
            guard let player = player else {
                print("error");
                return;
            }
            player.play();
        } catch let error {
            print(error.localizedDescription);
        }
    }

重要提示:在 Xcode 中的“功能”选项卡中,您还必须启用“音频、AirPlay 和画中画”功能在“后台模式”部分。

(Swift 4 解决方案在不同 iPhone 型号的 iOS 11 和 12 中进行了测试)。

警告:按照这种方法,声音将以手机中设置的当前音量播放,因此如果音量为零,则不会播放声音。您可以通过编程方式将音量设置为给定值in this way

    let volumeView = MPVolumeView();
    if let view = volumeView.subviews.first as? UISlider{
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
            view.value = 0.5; //Set the volume level between 0 and 1
        }
    }

但是,请考虑到这种方法会显示系统音量条,并且可能会导致糟糕的用户体验。

【讨论】:

  • 我认为这个解决方案很可能会被 Apple 拒绝,因为该应用程序没有流式传输音频。这种后台模式类别确实适用于 Spotify、YouTube 等媒体应用。
  • 我已经接受了一个使用此代码的应用程序;)在这种情况下,它是一个用于触发声音的应用程序,以便在与 BLE 外围设备连接相关的特定情况下警告用户(不是“媒体”应用程序)。如果您的应用确实需要后台功能才能运行,则不会拒绝该应用。
  • 在这种情况下 +1 的答案。不过我很好奇——苹果公司表示,如果该应用程序没有积极播放某些内容,它将被暂停。如何让应用在不播放时保持活力
  • 在我的例子中,应用程序在后台运行,因为它连接到 BLE 外围设备。播放声音是为了警告用户外围设备连接或断开。我认为这与引用的“Tile”案例非常相似。
  • 那么在我看来,您可以在后台播放音频的原因实际上是因为您也有 BLE 背景模式。我的猜测是,如果没有您,您将无法在后台播放音频,并且您的应用将被暂停
【解决方案2】:

首先,我认为我们需要澄清一些事情(如果我错了,请纠正我):

  1. 您正在安排计时器到期时的本地通知
  2. 您的应用根本没有在后台运行
  3. 即使手机处于静音状态,您也希望本地通知播放声音。

我实际上不确定这是否可能,您提到了 Tile 应用,重要的区别是 Tile 应用实际上确实在您的应用不运行的后台运行。

Apple 定义了允许在后台运行的特定用例。其中一种允许的模式是与蓝牙 LE 设备通信。所以工作的方式是 iPhone 识别磁贴设备,并向磁贴应用程序发送通知,此时应用程序实际上正在执行。查看更多关于后台执行here

我不相信您可以使用任何已批准的背景模式来实施可以让您解决此问题的解决方案。

我的建议是,当用户在您的应用中设置计时器时,检查手机是否处于静音状态(请参阅here),如果是,请提醒用户应用在计时器完成。

还可以下载其他一些计时器应用程序,看看它们是如何处理的。

【讨论】:

  • 你rec Tile与Apple有什么特别安排吗?
  • @Woodstock 不,我不相信他们会这样做,我认为他们正在使用专为这种情况设计的标准后台执行模式。 Apple 将蓝牙 LE 模式描述为“该应用程序与需要通过核心蓝牙框架定期提供更新的蓝牙配件配合使用。”在此处查看更多信息developer.apple.com/library/archive/documentation/iPhone/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
相关资源
最近更新 更多