in alarm ,notification works fine in background as follows:
UILocalNotification *notification1=[[UILocalNotification alloc]init];
notification1.fireDate=alramtime;
notification1.alertBody=#"Training Time";
notification1.repeatInterval=NSDayCalendarUnit;
notification1.soundName=#"Alarm.caf";
///////
previousnotif=[[NSUserDefaults standardUserDefaults]objectForKey:#"notif1"];
previous=[NSKeyedUnarchiver unarchiveObjectWithData:previousnotif];
NSLog(#"alarm %#",previous);
if (previous!= NULL) {
[[UIApplication sharedApplication]cancelLocalNotification:previous];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"notif1"];
}
NSData *alarm1=[NSKeyedArchiver archivedDataWithRootObject:notification1];
[notifdefaults setObject:alarm1 forKey:#"notif1"];
/////////
[[UIApplication sharedApplication] scheduleLocalNotification:notification1];
NSLog(#"new alarm %#",notification1);
but when i modify it to play in foreground too as follows:..its not working..Only alert appears but no sound???
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"KNIP"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Close"
otherButtonTitles:nil];
[alert show];
}
#end
When i log soundfile etc properties of notification..they work fine...but no sound is there...
In foreground you have to provide alert view and play sound if it requires, the notification will just call applicationDidReceiveLocalNotification. You can play the sound using AVAudioPlayer
//Playing sound
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath],notification.soundName]];
AVAudioPlayer *newAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
self.audioPlayer = newAudioPlayer;
self.audioPlayer.numberOfLoops = -1;
[self.audioPlayer play];
[newAudioPlayer release];
If the application is foremost and visible when the system delivers
the notification, no alert is shown, no icon is badged, and no sound
is played. However, the application:didReceiveLocalNotification: is
called if the application delegate implements it. The
UILocalNotification instance is passed into this method, and the
delegate can check its properties or access any custom data from the
userInfo dictionary.
Related
My app currently plays an mp3 audio file while the user is searching for another active user on the app.
In my app delegate, I ask for more background time to continue performing the search:
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"Background handler called. Not running background tasks anymore.");
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}];
}
When the user sends the app to the background, the audio continues to play as the search algorithms continue to work.
However, I would like for there to be the red indicator bar across the top of the screen, similar to what you would see when a VOIP call is performing on an app in the background.
Is this possible?
Here is my audio player code in SearchView.m
NSString *path = [NSString stringWithFormat:#"%#/searchTune.mp3", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[_audioPlayer play];
No, its not possible. No public API for that, iOS uses private API's for their internal use. It is called pulsating status bar.
I have searched, and I found UILocalNotification, but it works only when app is not active and i can not implement custom sound and snooze. Here is my code
UILocalNotification* alarm = [[UILocalNotification alloc] init];
alarm.fireDate = [myPicker date];
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.hasAction = YES;
alarm.alertAction = #"SNOOZE";
alarm.repeatInterval = 0;
alarm.soundName = #"Notification.aif";
alarm.alertBody = #"Alarm";
//[app scheduleLocalNotification:alarm];
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
Help is appreciated.
Your Approach is absolutely correct. but i thought you forgot some things about UILocalNotification .
read documents
A UILocalNotification object specifies a notification that an app can schedule for presentation at a specific date and time. The operating system is responsible for delivering local notifications at their scheduled times; the app does not have to be running for this to happen.
thanks, i have used UILocalNotification with my own sound name made another way to play it when app is active, in didReceiveLocalNotification
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"Received notification");
// Play a sound and show an alert only if the application is active, to avoid doubly notifiying the user.
if ([application applicationState] == UIApplicationStateActive) {
NSLog(#"active");
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"alarm2" ofType:#"wav"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &_mySound);
AudioServicesPlaySystemSound(self.mySound);
}
}
This question already has an answer here:
APN custom notification sound issue
(1 answer)
Closed 9 years ago.
I have a sound file in the app bundle, i want to play that sound file when user will get push notification.
IS it possible in iOS if yes, then please suggest the way to achieve this.
Thanks,
To play this sound you must specify the filename of the sound in the notification payload. For example, lets say you've added a sound file named example.caf into your application, we can play this sound with the notification payload as below:
{
aps =
{
alert = "test example notification message";
sound = "example.caf";
};
}
Then the custom sound will play when your notification arrives.
Use this method in your app delegte class.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive)
{
NSLog(#"User Info : %#", [userInfo description]);
NSLog(#"User Info Alert Message : %#", [[userInfo objectForKey:#"aps"] objectForKey:#"alert"]);
NSString *messageString = [NSString stringWithFormat:#"%#", [[userInfo objectForKey:#"aps"] objectForKey:#"alert"]];
NSString *playSoundOnAlert = [NSString stringWithFormat:#"%#", [[userInfo objectForKey:#"aps"] objectForKey:#"sound"]];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#",[[NSBundle mainBundle] resourcePath],playSoundOnAlert]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
}
}
I'm building a running app that notifies the user by audio that they need to start running or start walking every couple of minutes. I was able to get the sound to run in the background, even with the lock screen on using AVAudioPlayer.
Here's snippets of what I have:
ViewController.h
#property (nonatomic, strong) AVAudioPlayer *audioWalk;
ViewController.m
- (void)viewDidLoad{
[super viewDidLoad];
// Walk Audio File
NSString *soundFile2 = [[NSBundle mainBundle] pathForResource:#"Walk" ofType:#"wav"];
audioWalk = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile2] error:nil];
// Load the audio into memory
[audioWalk prepareToPlay];
// Permit the timer to run in the background
bgTask = 0;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
// Prevent the application from going to sleep while it is running
[UIApplication sharedApplication].idleTimerDisabled = YES;
// Starts recieving remote control events and is the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
// Plays audio
[audioWarmup play];
}
I'm trying to figure out how to play my audio without interrupting the music that is playing in the background. Also, the sounds need to play in the background and when the screen is locked. Any help would be much appreciated!
I was able to fix it. Here's what I did below. This solutions allows an audio file to run in the background, even with the lock screen, while not interrupting or pausing audio from other applications (particularly music).
- (void)viewDidLoad{
[super viewDidLoad];
// Play audio even if lock screen is on, the with options allows audio from other applications to play without interruption
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error: nil];
[[AVAudioSession sharedInstance] setActive: YES error:nil];
// Walk Audio File
NSString *soundFile2 = [[NSBundle mainBundle] pathForResource:#"Walk" ofType:#"wav"];
audioWalk = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile2] error:nil];
// Load the audio into memory
[audioWalk prepareToPlay];
// Permit the timer to run in the background
bgTask = 0;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
// Prevent the application from going to sleep while it is running
[UIApplication sharedApplication].idleTimerDisabled = YES;
// Starts receiving remote control events and is the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
// Plays audio
[audioWarmup play];
}
I'm asking the question like that because a UIAlertView will go off. Just not the AVAudioPlayer. Here's my code:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"MapViewController - didEnterRegion");
LocationReminder *theLocationReminder = [self.locationReminders objectForKey:region.identifier];
NSError *error;
NSURL *theUrl = [NSURL URLWithString:theLocationReminder.audioURI];
NSLog(#"theUrl = %#",theUrl);
AVAudioPlayer *thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:theUrl error:&error];
NSLog(#"thePlayer.url = %#",thePlayer.url);
[thePlayer play];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"entered region..." message:#"You have Entered the Location." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.tag = 2;
[alert show];
}
I checked the logs on the device after testing and while the Alert View does indeed show while I'm walking around testing it, the AVAudioPlayer wont play even though it has the correct URL.
I should mention that while I have enabled audio in the plist under Required Background Modes, I'm still in the app (so backgrounding wouldn't be an issue).
You are not maintaining a reference to thePlayer so it is getting deallocated (assuming you are using ARC). Possibly add a property in your class #interface block like
#property (nonatomic, strong) AVAudioPlayer *player;
and then instead of the line you have do
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:theUrl error:&error];
Hope this helps!