在静音模式下播放声音,应用程序终止状态
Posted
技术标签:
【中文标题】在静音模式下播放声音,应用程序终止状态【英文标题】:Playing sound in silent mode, app killed state 【发布时间】:2018-02-25 08:15:02 【问题描述】:我需要在我的 ios 应用程序中收到推送通知时播放自定义声音。
我知道,苹果不支持静音模式下的声音提示。我试过用自定义声音发送推送通知。它在设备非静音时播放,并在静音模式下振动。
但是,最近我发现了一个应用程序 - Chipolo,它以静音模式显示自定义声音,即使应用程序处于终止状态。
播放声音提示使用什么技术?
非常感谢任何帮助!
【问题讨论】:
你找到解决办法了吗? 还没有。我联系了苹果寻求技术支持,关于这一点,他们的回答是设计的,应该是这样的。无法在静音模式和应用程序终止状态下播放声音。 Apple 的话 - “您描述的行为和由此产生的限制是设计使然。如果您认为 Apple 应该考虑替代方法,我们鼓励您提交增强请求,并提供有关此设计决策如何影响您以及您的内容的信息”希望看到不同的做法。” 但我想知道,像 Chipolo 这样的应用程序是如何做到的。不知道。 【参考方案1】:我们无法在收到推送通知时更改系统声音,但我们可以使用MediaPlayer
和AVFoundation
播放音频。我们需要使用 Notification Service 扩展来处理前台和后台通知
在 NotificationService 扩展中
import UserNotifications
import AVFoundation
import MediaPlayer
class NotificationService: UNNotificationServiceExtension
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
// Properties
var error:NSError?
var audioPlayer = AVAudioPlayer()
let tempInfo = request.content.userInfo as! [String:NSObject]
var songName = ""
if tempInfo.index(forKey: "SoundFileName") != nil
songName = (tempInfo["SoundFileName"] as! String)
var opecode = ""
if tempInfo.index(forKey: "Opcode") != nil
opecode = (tempInfo["Opcode"] as! String)
if opecode == "RingDevice"
var songTitle = ""
var songExtension = ""
if songName == ""
songTitle = "Input"
songExtension = "caf"
else
let testStr = songName.components(separatedBy: ".")
songTitle = "\(testStr[0])"
songExtension = "\(testStr[1])"
if let url = Bundle.main.url(forResource: "\(songTitle)", withExtension: "\(songExtension)")
let volumeView = MPVolumeView()
if let view = volumeView.subviews.first as? UISlider
view.value = 1.0 //---0 t0 1.0---
do
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.caf.rawValue)
audioPlayer.volume = 1.0
DispatchQueue.main.asyncAfter(deadline: .now() + 5) // Give 5 sec delay to play audio or else audio will not hearable
audioPlayer.play()
catch _ as NSError
print("[SoundPlayer] There was an error: \(String(describing: error))")
if (audioPlayer.isPlaying)
audioPlayer.stop()
audioPlayer.play()
if let bestAttemptContent = bestAttemptContent
// Modify the notification content here...
bestAttemptContent.title = "\(bestAttemptContent.title)"
contentHandler(bestAttemptContent)
override func serviceExtensionTimeWillExpire()
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent
contentHandler(bestAttemptContent)
在我的情况下,我需要检查 pushnotification SoundFileName
和 Opcode
中的两个参数。如果Opcode
是RingDevice
表示我正在播放PushNotification 中提到的声音
别忘了开启后台模式
希望对你有帮助:)
【讨论】:
谢谢你。我已经尝试过这种方法。但是当应用程序处于终止状态并且手机处于静音模式时,它没有播放音频。当使用主页按钮最小化应用程序时,我能够在 backgroud.ie 中播放音频 它在 Killed 状态下为我工作。你开启后台模式了吗?回答更新检查一次【参考方案2】:至于在设备处于静音模式时播放声音,您根本无法立即进行。 只有 Apple 可以在寻找设备等紧急情况下覆盖静音开关。您的应用也需要Apple 的特别许可。
Ganesh 的回答是没有它你能做的最好的事情。
【讨论】:
以上是关于在静音模式下播放声音,应用程序终止状态的主要内容,如果未能解决你的问题,请参考以下文章