I am working on an app,i have set timer in app, after that i went in background and when time is over i want to play music in background.but music is not play?
refer a ios-sdk_background-audio. You'll be very helpful. Good luck
Use this Timer Code for set the Timer
UIBackgroundTaskIdentifier bgTask =0;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
self.secondsTimer = [NSTimer
scheduledTimerWithTimeInterval:1
target:self
selector:#selector(timerFireMethod:)
userInfo:nil
repeats:NO];
fire Method-- (void) timerFireMethod:(NSTimer *) theTimer
{}
In This fire Method use Below Code for Playing media file-
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"tujhbinjena"
ofType:#"mp3"]];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
audioPlayer.delegate=self;
audioPlayer.volume=1.0;
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play]
}`
[self becomeFirstResponder];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
- (BOOL)canBecomeFirstResponder {
return YES;
}
and in ViewDidUnload you need to do these following lines
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
you need to handle the AVAudioPlayerDelegate delegate methods as per and for playing audio in background you need to add one Parameter in Info.plist That is "Required background modes" and value for this key is "App plays audio". Please let me know if any doubt.
for this function you can use this method:--
-(void)notificationSchedue
{
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
//---------remainingTime NSUserDefaults contain the future date--------//
NSString *datevalueremaining= [[NSUserDefaults standardUserDefaults]valueForKey:#"remainingTime"];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSDate *dateremaining=[dateFormat dateFromString:datevalueremaining];
NSDate *pickerDate = dateremaining;
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit )
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
if (localNotif)
{
[[UIApplication sharedApplication] cancelLocalNotification:localNotif];
[localNotif release];
}
localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Your Time is Over";
localNotif.alertAction = #"View";
NSString *stringvalue=[[NSUserDefaults standardUserDefaults]valueForKey:#"goodNight"];
//-----music should be less then or equal to 30 sec---//
localNotif.soundName=#"s1.mp3";
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
Related
I have a local notification set up. Once its fired, lets say my app is in "sleep" mode that is home button pressed or i quit it. Now the notification is received. I see red tag on my app and when I click on the app, it should fire didReceiveLocalNotification but it does't. How can I make it do that when I open my app?
The didReceiveLocalNotification method is only called when your application is running in the foreground. If you see a badge and click on the App to start it, then you need to process the local notification using application:willFinishLaunchingWithOptions: (or application:didFinishLaunchingWithOptions:) To get at your local notification in either of these two methods, use UIApplicationLaunchOptionsLocalNotificationKey as a key to the options dictionary.
[edit] From the UILocalNotification documentation:
if the local notification only badges the application icon, and the
user in response launches the application, the
application:didFinishLaunchingWithOptions: method is invoked, but no
UILocalNotification object is included in the options dictionary.
-(void)alarmNotification
{
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *newdate = timePicker.date;
NSLog(#"pickerdate:%#",newdate);
NSDate *pickerDate =[newdate dateByAddingTimeInterval:-60*1];
NSLog(#"pickerdate:%#",timePicker.date);
// Break the date up into components
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit )
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
// Notification will fire in one minute
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = txtMeetingName.text;
// Set the action button
localNotif.alertAction = NSLocalizedString(#"View!", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
localNotif.userInfo = infoDict;
localNotif.applicationIconBadgeNumber =1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
Then implement this code......
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
// Handle the notificaton when the app is running
NSDateComponents *comps = [[NSCalendar currentCalendar] components:notif.repeatInterval fromDate:notif.fireDate toDate:[NSDate date] options:0];
// you can set your own sound
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/win.wav", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
UIAlertView *alertView =
[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"move on", nil)
message:[NSString stringWithFormat:#"You have to start %# meeting within 5 minute",notif.alertBody]
delegate:self
cancelButtonTitle:nil
otherButtonTitles:NSLocalizedString(#"OK", nil), nil];
notif.soundName = UILocalNotificationDefaultSoundName;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog(#"error%#",[error description]);
else
[audioPlayer play];
[alertView show];
[alertView release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex{
if (buttonIndex==0) {
[audioPlayer stop];
}
NSLog(#"U HAVE CLICKED BUTTON");
}
hope this will help you.....
When you are setting fire date then there have you set the userInfo property of your notification object???
& r u checking it on device or on simulator??
Do you know how to play an alarm sound when the iPhone is sleeping,
like the built-in Clock app in iPhone?
VERY IMPORTANT EDIT:
in the built-in Clock app in iPhone
when the alarm sound is playing, if user switch the Silent switch to Silent (Vibrate mode),
the alarm sound still continue to play.
Do you know how to do the same?
this code will help you to play music in background:
the sound file of the music should be only 30 sec
notification support 30 sec sound file and it should be in the bundle folder if it is in the document folder then you have to put the path of the sound file
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSString *dateValueRemaining =[NSString stringWithFormat:#"23/08/2012 11:30:33"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSDate *dateRemaining = [dateFormat dateFromString:dateValueRemaining];
NSDate *pickerDate = dateRemaining;
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit
| NSMonthCalendarUnit
| NSDayCalendarUnit)
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:(NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit)
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
NSLog(#"itemDate: %#", itemDate);
if (localNotif) {
[[UIApplication sharedApplication] cancelLocalNotification:localNotif];
}
localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil) {
return;
}
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Your Time is Over";
localNotif.alertAction = #"View";
//---THIS SONG FILE IN THE NSBUNDLE FOLDER---------//
localNotif.soundName = #"s1.mp3";
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
The set button is wired up to run a method called scheduleNotification in the view controller which uses the UILocalNotification class to schedule a notification. The code looks as follows:
(void)scheduleNotification
{
[reminderText resignFirstResponder];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil)
{
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = [datePicker date];
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Did you forget something?";
notif.alertAction = #"Show me";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
NSDictionary *userDict = [NSDictionary dictionaryWithObject:reminderText.text
forKey:kRemindMeNotificationDataKey];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[notif release];
}
}
Before the app enters the background, play a silent sound with AVAudioPlayer and keep it play infinite number of times. And when your notification kicks in, again use AVAudioPlayer to play your notification sound, not the UILocalNotification object. It worked for me.
So looking at i-qi app, most likely they've set their UIBackgroundModes to "audio" in their info.plist. This means that they're able to play audio in the background. They're probably playing silent audio until the timer ends because background audio sessions will get cut if they're not in use.
In terms of the silent switch, thats probably based on the session category they're using. Check out this resource:
http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategories/AudioSessionCategories.html#//apple_ref/doc/uid/TP40007875-CH4-SW1
Only method is to use local Notifications or Push notifications..both allow sounds to be played for 30 seconds
Programmers, I am new to objective C.
I am working on local notifications task and my task is that when user quits the applications and he doesn't run application again, suppose for one day, then the app icon badge number should auto increment to one. If it doesn't run for 48 hours, then it should increment and become 2 (means I have to repeat notification) and so on.
I am using local notifications for that. This how I am doing it:
- (void)applicationWillResignActive:(UIApplication *)application
{
[self launchNotification];
}
-(void)launchNotification
{
NSDate *todaydate = [NSDate date];
NSDate *firedates = [todaydate dateByAddingTimeInterval:10.0];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = firedates;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
fromDate:firedates];
[dateComps setHour:[timeComponents hour]];
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]+10];
localNotif.repeatInterval = NSSecondCalendarUnit;
localNotif.soundName = UILocalNotificationDefaultSoundName;
// Specify custom data for the notification
//NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
//localNotif.userInfo = infoDict;
// Schedule the notification
localNotif.applicationIconBadgeNumber = +1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
I am working from long time and finding no way out.
i am saving selected date from picker in array in userdefaults. So when i select a particular date and click on save that particular date is getting saved in userdefaults.This is done properly.But now i have problem.I need to compare each and every date and time of userdefaults with the current time .If an object gets equivalent to the current date and time then the notification should be shown.How is this possible.Thanks. This is my code
Here i am selecting my date through date picker and saving date in userdefaults.
this is my timepickercontroller.m
- (void)viewDidLoad {
time = [[NSString alloc] init];
CGRect pickerFrame = CGRectMake(0,40,0,0);
datePicker = [[UIDatePicker alloc] initWithFrame:pickerFrame];
datePicker.datePickerMode = UIDatePickerModeTime;
datePicker.date = [NSDate date];
[datePicker addTarget:self action:#selector(convertDueDateFormat) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
[datePicker release];
}
-(void)convertDueDateFormat{
app = (StopSnoozeAppDelegate*)[[UIApplication sharedApplication]delegate];
app.timerdate = [self.datePicker date];
NSLog(#"picker date:%#",selecteddate);
if ([[NSUserDefaults standardUserDefaults] valueForKey:#"time"]==nil)
{
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:#"time"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#",[[NSUserDefaults standardUserDefaults] objectForKey:#"time"]);
}
else
{
NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:#"time"];
NSMutableArray *array_dates = [[NSMutableArray alloc] init];
for(int i =0;i<[array count];i++)
{
[array_dates addObject:[array objectAtIndex:i]];
}
[array_dates addObject:app.timerdate];
[[NSUserDefaults standardUserDefaults] setObject:array_dates forKey:#"time"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#",[[NSUserDefaults standardUserDefaults] objectForKey:#"time"]);
}
}
this is the controller where i am setting notification
-(IBAction)save{
dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSDate *currentime = [NSDate date];
currentcheck = [NSString stringWithFormat:#"%#",[dateFormatter stringFromDate:currentime] ];
NSLog(#"currenttime:%#",currentcheck);
timepicker = [[TTimePickerController alloc]init];
if (app.timerdate == NULL && interval == NULL && newsound == NULL)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"UIAlertView" message:#"Set Date,interval,sound for alarm" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
alert = nil;
}
else
{
[self scheduleNotification];
[self saveInDatabase];
}
}
-(void)scheduleNotification
{
[[UIApplication sharedApplication]cancelAllLocalNotifications];
timepicker = [[TTimePickerController alloc]init];
NSDate *newtestdate = [[NSUserDefaults standardUserDefaults]objectForKey:#"time"];
NSLog(#"fireDate=%#", newtestdate);
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:newtestdate];
NSDateComponents *timeComponents = [calendar components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:newtestdate];
NSDateComponents *dateComps = [[NSDateComponents alloc]init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
Class cls = NSClassFromString(#"UILocalNotification");
if (cls!= nil) {
UILocalNotification *notif = [[cls alloc]init];
notif.fireDate = itemDate;
[app.dateFormatter setDateFormat:#"hh:mm a"];
newstring = [app.dateFormatter stringFromDate:notif.fireDate];
NSLog(#"new fire date:%#",newstring);
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Alarm";
notif.alertAction = #"View";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber=1;
notif.repeatInterval = 0;
[[UIApplication sharedApplication]scheduleLocalNotification:notif];
[notif release];
}
}
Supposing ur time format is like this hh:mm:ss
NSDate *currentTime=[NSDate date];
NSArray *timeArray=[[NSUserDefaults standardUserDefaults]objectForKey:#"time"];
NSDateFormatter* tempFormat = [[[NSDateFormatter alloc]init]autorelease];
[tempFormat setDateFormat:#"h:mm a"];
NSString* tempStr = [NSString stringWithFormat:#"%#",[tempFormat stringFromDate:date]];
if([tempStr isEqualToString:[NSString stringWithFormat:#"%#",[timeArray objectAtIndex:0]]]){
//Make any decision
//Similarly compare all the time in the array by changing the index using for-loop.
}
I suspect that what you really want to do is not to compare the dates, but to set the fire date of the notification to the date you got from the array.
To do that, you enumerate the array and launch an NSNotification for each timerDate:
NSArray *timerDates = [NSUser Defaults standardUserDefaults] objectforKey:#"time"];
NSDate *now = [NSDate date];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
// .... general setup of all notifs here.
for (NSDate * aDate in timerDates) {
localNotif.fireDate = aDate;
//... further setup of each individual notif here....
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
[localNotif release];
However, from your code, it looks like you're getting a single date from defaults:
NSDate *newtestdate = [[NSUserDefaults standardUserDefaults]objectForKey:#"time"];
but you save an array there in the method
-(void)convertDueDateFormat{
...
[[NSUserDefaults standardUserDefaults] setObject:array_dates forKey:#"time"];
So which one is it?
If you have an array, you can test its values as dates:
NSArray *timerDates = [NSUser Defaults standardUserDefaults] objectforKey:#"time"];
NSDate *now = [NSDate date];
_block int timerIndex; // can be changed inside the block
// use a block to enumerate the array
[timerDates enumerateObjectsUsingBlock:^(id obj,NSUInteger index, BOOL *stop){
if(fabs([(NSDate *)obj timeIntervalSinceDate:now])< 1.0) {
*stop=YES;
timerIndex = index;
}
} ];
Then use timerIndex to get the right date:
localNotif.firedate = [timerDates objectAtIndex:timerIndex];
Definitely also look at the documentation for comparing dates (Apple class documentation for NSDate is good). This is just one way to do it, and probably not the best.
(sorry about my formatting. I'm kinda new at this)
In my app i want to set up a local notification on everyday at a particular time.Time is the one that selected from a Time picker.Is there any method for this.Plese help me.
Just specify the firedate as the date from your UIDatePicker and NSDayCalendarUnit as the repeatinterval:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = datePicker.date;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"This is the Alert-Body Text"];
localNotif.alertAction = #"Button-Text";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
localNotif.repeatInterval = NSDayCalendarUnit;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
you can set Local Notifications.
Right out of apple's sample code:
- (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:item.day];
[dateComps setMonth:item.month];
[dateComps setYear:item.year];
[dateComps setHour:item.hour];
[dateComps setMinute:item.minute];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [itemDate addTimeInterval:-(minutesBefore*60)];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(#"%# in %i minutes.", nil),
item.eventName, minutesBefore];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
you can set a local notification for a specific timstamp.
you have to check userinfo dictionary in applicationDidFinishedLaunching for any notification data.
you have to handle:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification