How to make sound play when I receive a remote notification?

I try to automatically play a sound file (which is not part of my application package and is not a notification sound) after receiving a remote notification. I want this to happen if the application is in the foreground or in the background when receiving a notification.

I use the Amazing Audio Engine as a wrapper around major audio libraries. In my App Delegate didReceiveRemoteNotification I create an Audio Controller and add AEAudioFilePlayer to it AEAudioFilePlayer this:

  NSURL *file = [NSURL fileURLWithPath:sourceFilePath]; AEAudioFilePlayer *notificationPlayer = [AEAudioFilePlayer audioFilePlayerWithURL:file audioController:_notificationController error:NULL]; notificationPlayer.completionBlock = ^{ // Remove self from channel list after playback is complete [_notificationController removeChannels:[NSArray arrayWithObjects:notificationPlayer,nil]] ; }; [_notificationController addChannels:[NSArray arrayWithObjects:notificationPlayer,nil]]; 

However, the sound does not play! My logs display the following errors:

  2014-08-18 06:21:28.003 MyApp[394:60b] TAAE: Setting audio session category to AVAudioSessionCategoryPlayback 2014-08-18 06:21:28.019 MyApp[394:60b] Couldn't activate audio session: Error Domain=NSOSStatusErrorDomain Code=561015905 "The operation couldn't be completed. (OSStatus error 561015905.)" 2014-08-18 06:21:28.024 MyApp[394:60b] TAAE: Audio session initialized (audio route '<AVAudioSessionRouteDescription: 0x178006720, inputs = (null); outputs = ( "<AVAudioSessionPortDescription: 0x1780067f0, type = Speaker; name = Speaker; UID = Speaker; selectedDataSource = (null)>" )>') 2014-08-18 06:21:28.034 MyApp[394:60b] 06:21:28.033 ERROR: [0x1938e42a0] >aurioc> 783: failed: '!pla' (enable 2, outf< 2 ch, 44100 Hz, Int16, non-inter> inf< 2 ch, 0 Hz, Float32, non-inter>) 2014-08-18 06:21:28.037 MyApp[394:60b] 06:21:28.037 ERROR: [0x1938e42a0] >aurioc> 783: failed: '!pla' (enable 2, outf< 2 ch, 44100 Hz, Int16, non-inter> inf< 2 ch, 0 Hz, Float32, non-inter>) 

While viewing the pla error, I found this link: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html

which indicates that this type of error can occur if the list of properties of the application information does not allow the use of audio or if the application is in the background and uses a category that does not allow background sound.

But my plist contains audio as the background mode, my audio sessions category is AVAudioSessionCategoryPlayback, and for the parameters of my category it is AVAudioSessionCategoryOptionMixWith Other.

How to get the sound that will play when you receive a remote notification?

+4
source share
2 answers

You cannot activate an audio session in the background, and you cannot initiate audio playback in the background. Background sound simply means that you can continue to play while your application goes into the background; but as soon as your background sound was interrupted or if your application did not play when you entered the background, you have no way to make a sound.

And this makes sense, because it would be terrible if applications that the user did not use and possibly did not even suspect could start to make noise from nowhere.

Usually you need to either come to the forefront or give the system an immediate local notification that has sound.

+4
source

If you call AVAudioSession:setActive:error: and AVAudioSession:setCatagory:withOptions:error: and create your AVPlayer before in the background, you can play your sound. For instance:

  // Make sure this is run BEFORE entering background. [[AVAudioSession sharedInstance] setActive:YES error:&error]; if(error != nil){ NSLog(@"ERROR: %@", error.localizedDescription); } else { [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]; if(error != nil){ NSLog(@"ERROR: %@", error.localizedDescription); } else { self._player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.urlOfFileToPlay error:&error]; if(error != nil){ [[AVAudioSession sharedInstance] setActive:NO error:&error]; NSLog(@"ERROR: %@", error.localizedDescription); } } } //You can then do this in application:didReceiveRemoteNotification:fetchCompletionHandler: [backgroundPlayer.player play]; 

Of course, I assume that you already have options for the background modes set for background extraction and remote notifications.

I also warn that if you call AVAudioSession:setActive:error: too early, other applications may change you for you.

Also, if you install the application NOT to run in the background (Info.plist: <key>UIApplicationExitsOnSuspend</key> <true/> ) when it receives a “Notification” (local or remote), and you activated AVAudioSession as and the above code, it will play sound in the notification payload regardless of whether the application is set to silent or vibration mode, which is actually how alarms do it. Of course, this will not work if you need to poll the server in response to the remote notification. See here.

+2
source

Source: https://habr.com/ru/post/1265296/


All Articles