UILocalNotifications 播放自定义声音
Posted
技术标签:
【中文标题】UILocalNotifications 播放自定义声音【英文标题】:UILocalNotifications playing Custom sound 【发布时间】:2011-08-18 04:53:18 【问题描述】:我在我的应用程序中实现了本地通知,但我只是想知道是否有办法播放不属于 iPhone 应用程序主包的声音。 基本上在我的应用程序中,我希望用户录制在生成本地通知时播放的声音,而不是播放预先录制的或默认的声音。 据我所知,这是可以实现的,因为我在应用商店中看到了 2-3 个应用,它们正在做我想做的事情
- (void)alertSelector:(NSString *)AlertTitle WithFiringTime:(NSDate *)date
UILocalNotification *localNotification = [[[UILocalNotification alloc] init] autorelease];
[localNotification setFireDate:date];
[localNotification setTimeZone:[NSTimeZone defaultTimeZone]];
NSDictionary *data = [NSDictionary dictionaryWithObject:date forKey:@"payload"];
[localNotification setUserInfo:data];[localNotification setAlertBody:AlertTitle];
[localNotification setAlertAction:@"View"]; [localNotification setHasAction:YES];
localNotification.soundName=@"voice.aif";
if (!localNotification)
return;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
【问题讨论】:
您能否链接到其中一个正在执行此操作的应用程序?谢谢。 @ArtGillespie 这是允许为 UILocalNotification 设置录制声音的众多应用之一。 itunes.apple.com/in/app/record-alarm-free/id418511936?mt=8 对我来说问题是因为我们有多个目标,而我添加的音频文件只添加到 1 个目标。基本上我必须将它添加到我们所有的目标中...... 【参考方案1】:我的猜测是您的声音格式不适合操作系统播放。确保您的声音以 IMA4 格式格式化。另外,请确保您的文件在您的应用程序包中,您应该可以继续使用。
有关更多参考和类似问题,请参阅此 SO 问题。
Choose custom sound for Local Notifications
这是Apple's Local and Push Notification Guide 的链接。它详细解释了声音以及可以使用的默认声音。
【讨论】:
是否有任何代码可以按要求播放 UILocalNotification 的“Documents”目录中录制的声音? 我相信你只需要用 UILocalNotificaionDefaultSoundName 替换你的声音名称 我已经用另一个指向 Apple 文档的链接更新了我的答案,这应该可以帮助你。 正如问题中提到的“基本上在我的应用程序中,我希望用户录制在生成本地通知时播放的声音,而不是播放预先录制或默认的声音。至于我知道这是可以实现的,因为我在应用商店中看到了 2-3 个应用,它正在做我想做的同样的事情”你提到的页面没有任何设置录制声音的示例。由于一些应用程序会这样做,因此我们确信必须解决此问题。 这里有一些很好的信息。 tuaw.com/2007/08/06/iphone-coding-recording-audio【参考方案2】:来自soundName
属性的描述-
对于这个属性,指定一个文件名(包括扩展名) 应用程序主包中的声音资源或
UILocalNotificationDefaultSoundName
请求默认系统 声音。
似乎无法使用捆绑包中存在的声音以外的声音。您确定这些应用程序正在使用带有自定义声音的本地通知吗?也许他们正在播放带有警报的声音或类似的东西。
HTH,
阿克谢
【讨论】:
嗨 Akshay 谢谢您的回复,是的,我确定他们正在使用 UIlocalnotification 我应该给您这些应用程序的链接吗?他们是免费的应用程序,做着我想做的事情。我认为堆栈溢出不允许共享这些链接? 您是安排通知还是立即显示? 我正在使用 NSLocalnotification 安排它。 你能添加你用来显示通知的代码吗? - (void)alertSelector:(NSString *)AlertTitle WithFiringTime:(NSDate *)date UILocalNotification *localNotification = [[[UILocalNotification alloc] init] autorelease];[localNotification setFireDate:date]; [localNotification setTimeZone:[NSTimeZone defaultTimeZone]];NSDictionary *data = [NSDictionary dictionaryWithObject:date forKey:@"payload"]; [localNotification setUserInfo:data];[localNotification setAlertBody:AlertTitle]; [localNotification setAlertAction:@"View"]; [localNotification setHasAction:YES]; localNotification.soundName=@"voice.aif"; if (!localNotification) 返回;【参考方案3】:notif.soundName = @"sound.caf";
应该可以。确保声音确实在您的应用程序包中,格式正确(线性 PCM 或 IMA4 — 几乎任何解释如何为 ios 转换声音的地方都会告诉您如何做到这一点),并且小于 30 秒。
您可以使用终端从 wav 和 mp3 转换:
afconvert -f caff -d LEI16@44100 -c 1 in.wav sound.caf
'in.wav' 是你要转换的输入声音,'sound.caf' 是输出文件,改变目录到你想要输出文件的地方
【讨论】:
【参考方案4】:确保您的声音文件已添加到项目设置->(目标)->构建阶段下的“复制捆绑资源”列表中。 这为我解决了这个问题。起初我只得到默认声音,即使我指定了自定义文件名(并且文件已添加到项目中)。但在我手动将文件添加到此列表后,它开始工作。
我使用来自我的 mac 的系统声音进行测试。我在控制台中使用此命令对其进行了转换:
afconvert /System/Library/Sounds/Basso.aiff ~/Downloads/alert2.caf -d ima4 -f caff -v
【讨论】:
【参考方案5】:好吧,我遇到了同样的问题,听起来以前不支持此功能,或者无法为 App Bundle 中未包含的本地通知播放自定义声音。但后来支持此功能,您可以从 App 容器中分配自定义声音,特别是在 Library/Sounds 目录中。它对我有用。您可以将声音从服务器下载到此目录,也可以通过将 .caf(Apple 表示其他扩展名可能有效)文件从 bundle 复制到 Library/sounds 目录来测试它,然后从 bundle 中删除该文件的引用,以便您可以确保如果播放的声音来自 bundle 之外的目录。这一切都很好,我的主要问题是,如果用户强制引用应用程序,它会停止为本地通知工作,而它仍然适用于推送工具包通知,我会在推送工具包推送到达时安排本地通知。 下面是测试目录播放声音的代码:
func copyFileToDirectoryFromBundle()
// get reference to library directory
let LibraryDirectoryPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)
// see what is in there
for path in LibraryDirectoryPaths
print("di=\(path)")
// prepare for sound directory
let libraryDirectoryPath: AnyObject = LibraryDirectoryPaths[0]
let soundsDirectoryPath = libraryDirectoryPath.stringByAppendingPathComponent("Sounds")
// create sounds directory under library if not there already
if !NSFileManager.defaultManager().fileExistsAtPath(soundsDirectoryPath)
do
try NSFileManager.defaultManager().createDirectoryAtPath(soundsDirectoryPath, withIntermediateDirectories: false, attributes: nil)
print("sounds library created,,,")
catch let error as NSError
print("creating sounds directory error = \(error.localizedDescription)");
else
print("Sounds directory is there already under Library")
do
// sounds directory should have been added under library
let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( NSURL(string: libraryDirectoryPath as! String)!, includingPropertiesForKeys: nil, options: [])
print("Library directs=\(directoryContents)")
// prepare for adding subdirectory with file name from bundle
// here is where you should save files if downloaded from server
// here im just moving one from bundle
let subDirectoryPath = directoryContents.last!
if let pathFromBundle = NSBundle.mainBundle().pathForResource("notification", ofType:"caf")
let myFilePathUnderSounds = "\(subDirectoryPath.path!)\("/notification.caf")"
if !NSFileManager.defaultManager().fileExistsAtPath(myFilePathUnderSounds)
do
print("bundle path=\(pathFromBundle)and datacontainer path=\(subDirectoryPath.path!)")
try NSFileManager.defaultManager().copyItemAtPath(pathFromBundle, toPath:myFilePathUnderSounds )
print("item copied")
catch let error as NSError
print(error.localizedDescription);
else
print("Your file from bundle path = \(pathFromBundle) is already there under Sounds")
else
print("Item not found in bundle")
// see item there after you add it
let subDirectories = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( subDirectoryPath, includingPropertiesForKeys: nil, options: [])
print("files under sounds")
for fileDirectory in subDirectories
print(fileDirectory)
catch let error as NSError
print(error.localizedDescription)
确保 .caf 文件位于 Library/Sounds 目录下。您所要做的只是将带有扩展名的文件名分配给本地通知 soundName 属性,就像文件在捆绑包中一样。
【讨论】:
【参考方案6】:你在清理旧通知吗?
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
您也可以,从手机中删除应用程序(可能也需要重新启动) 它应该工作:-)
除此之外,上面提到的代码应该是正确的。
这条线localNotification.soundName=@"voice.aif";
应该足以播放自定义声音。
但如果您先测试了通知而没有添加声音文件,则默认声音文件 (UILocalNotificationDefaultSoundName
) 已注册!要重新注册,您必须取消之前的通知 (cancelAllLocalNotifications
) 或删除应用程序,才能“重新”注册您的通知,
除此之外,苹果文档说:
不支持持续时间超过 30 秒的声音。如果你 指定一个声音超过 30 秒的文件,默认 而是播放声音。
希望它现在有所帮助:-)
【讨论】:
不相关——问题是关于如何让 UILocalNotification 播放自定义声音。以上是关于UILocalNotifications 播放自定义声音的主要内容,如果未能解决你的问题,请参考以下文章
我想在 Firebase onMessage 接收方法上播放自定义通知音,当锁定屏幕 android 手机时
使用 Cloud Functions 播放自定义通知声音 - iOS