UILocalNotification播放自定义声音

时间:2011-08-18 04:53:18

标签: iphone ios uilocalnotification

我在我的应用程序中实现了本地通知,但我只是想知道是否有一种方法可以播放不属于主要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]; 
}

6 个答案:

答案 0 :(得分:3)

我的猜测是你的声音格式不适合操作系统播放。确保您的声音格式为IMA4格式。另外,请确保您的文件在您的应用程序包中,并且您应该很高兴。

有关更多参考和类似问题,请参阅此问题。

Choose custom sound for Local Notifications

以下是Apple's Local and Push Notification Guide的链接。它详细解释了声音和可以使用的默认声音。

答案 1 :(得分:0)

来自soundName属性的描述 -

  

对于此属性,请指定a的文件名(包括扩展名)   应用程序主要包中的声音资源或   UILocalNotificationDefaultSoundName请求默认系统   声音。

似乎不能使用捆绑中存在的声音以外的声音。您确定应用程序正在使用带有自定义声音的本地通知吗?也许他们正在播放带有警报或类似声音的声音。

HTH,

阿克沙伊

答案 2 :(得分:0)

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'是输出文件,将目录更改为您想要输出文件的位置

答案 3 :(得分:0)

确保您的声音文件已添加到"复制捆绑资源"项目设置下的列表 - >(目标) - >构建阶段。 这为我解决了这个问题。起初我只获得默认声音,即使我指定了自定义文件名(并且文件已添加到项目中)。但是在我手动将文件添加到此列表后,它开始工作。

我用我的mac系统声音进行测试。我在控制台中使用此命令转换它:

afconvert /System/Library/Sounds/Basso.aiff ~/Downloads/alert2.caf -d ima4 -f caff -v

答案 4 :(得分:0)

好吧,我遇到了同样的问题,听起来之前不支持或者不能播放App Bundle中未包含的本地通知的自定义声音。但稍后会支持此功能,您可以在App容器中专门为Library / Sounds目录分配自定义声音。它与我合作。您可以将声音从服务器下载到此目录,也可以通过将.caf(Apple表示其他扩展可能正常工作)文件从bundle复制到Library / sounds目录进行测试,然后从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属性,就像文件是捆绑包一样。

答案 5 :(得分:-2)

您是否使用?

清除旧通知
UIApplication* app = [UIApplication sharedApplication];
NSArray*  oldNotifications = [app scheduledLocalNotifications];
if ([oldNotifications count] > 0) {
    [app cancelAllLocalNotifications];
}

否则你可以从手机中删除应用程序(也许还需要重启) 它应该工作: - )

除此之外,上面提到的代码应该是正确的。 这一行localNotification.soundName=@"voice.aif";应足以播放自定义声音。 但如果您在没有添加声音文件的情况下首先测试了通知,则会注册默认声音文件(UILocalNotificationDefaultSoundName)!并重新注册您必须取消之前的通知(cancelAllLocalNotifications)或删除该应用程序,才能“重新”注册您的通知,

除此之外,苹果医生说:

  

不支持持续时间超过30秒的声音。如果你   指定一个播放超过30秒的声音的文件,默认值   而是播放声音。

希望现在有所帮助: - )