Android Developer Tutorials and Blog

Here we will set a notification to be popped up at a specific time in the future that the user has chosen. We will follow on from the Basic Date Picker Tutorial to use this Date Picker to allow the user to set a reminder.

It is a quite interesting scenario and this is just a taster of what is possible, but say you have just created a todo list and you want to notify the user to do that item, you can prompt the user to select a date then have the system pop up a notification when that date comes around. When they then select your notification it will take them back into your application.

As usual all the source code below is well commented allowing you to ignore my ramblings and dive straight in. Source code files are at the bottom of the post.

What we’re going to do:

Create an activity to select a date in the future

After selecting a date, pass it to a service to deal with it

Create an alarm for the date selected

When this alarm is raised pop up a notification in the system bar

Clicking the notification will bring the user back into your app

So here … we .. go

First comes the MainActivity, this just shows the user a datepicker allowing them to select a date in the future that you are going to use as the alarm reminder date:
MainActivity.java

package com.blundell.tut.ui.phone;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.DatePicker;
import android.widget.Toast;
import com.blundell.tut.R;
import com.blundell.tut.service.ScheduleClient;
/**
* This is the Main Activity of our app.
* Here we allow the user to select a date,
* we then set a notification for that date to appear in the status bar
*
* @author paul.blundell
*/
public class MainActivity extends Activity {
// This is a handle so that we can call methods on our service
private ScheduleClient scheduleClient;
// This is the date picker used to select the date for our notification
private DatePicker picker;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create a new service client and bind our activity to this service
scheduleClient = new ScheduleClient(this);
scheduleClient.doBindService();
// Get a reference to our date picker
picker = (DatePicker) findViewById(R.id.scheduleTimePicker);
}
/**
* This is the onClick called from the XML to set a new notification
*/
public void onDateSelectedButtonClick(View v){
// Get the date from our datepicker
int day = picker.getDayOfMonth();
int month = picker.getMonth();
int year = picker.getYear();
// Create a new calendar set to the date chosen
// we set the time to midnight (i.e. the first minute of that day)
Calendar c = Calendar.getInstance();
c.set(year, month, day);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
// Ask our service to set an alarm for that date, this activity talks to the client that talks to the service
scheduleClient.setAlarmForNotification(c);
// Notify the user what they just did
Toast.makeText(this, "Notification set for: "+ day +"/"+ (month+1) +"/"+ year, Toast.LENGTH_SHORT).show();
}
@Override
protected void onStop() {
// When our activity is stopped ensure we also stop the connection to the service
// this stops us leaking our activity into the system *bad*
if(scheduleClient != null)
scheduleClient.doUnbindService();
super.onStop();
}
}

When the above activity is created it starts a new service. This service is how we organise our alarm tasks. When you want to do a new task, you don’t want to use the UI thread, as this means the system can’t draw anything if you do. So we start a new service, bind to this service and then tell the service to set an alarm for the reminder date.

We connect to our service in two steps, using a client and a service, this allows the separation of concerns over binding to the service and managing its resources. Just remember to unbind from your service when the activity is finished.

Below is the service client, this connects to the service then passes on a reference of the service to the activity (so that we can tell the service to do stuff from the activity). It’s a middle man for communication.

ScheduleClient.java:

package com.blundell.tut.service;
import java.util.Calendar;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
/**
* This is our service client, it is the 'middle-man' between the
* service and any activity that wants to connect to the service
*
* @author paul.blundell
*/
public class ScheduleClient {
// The hook into our service
private ScheduleService mBoundService;
// The context to start the service in
private Context mContext;
// A flag if we are connected to the service or not
private boolean mIsBound;
public ScheduleClient(Context context) {
mContext = context;
}
/**
* Call this to connect your activity to your service
*/
public void doBindService() {
// Establish a connection with our service
mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/**
* When you attempt to connect to the service, this connection will be called with the result.
* If we have successfully connected we instantiate our service object so that we can call methods on it.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with our service has been established,
// giving us the service object we can use to interact with our service.
mBoundService = ((ScheduleService.ServiceBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
/**
* Tell our service to set an alarm for the given date
* @param c a date to set the notification for
*/
public void setAlarmForNotification(Calendar c){
mBoundService.setAlarm(c);
}
/**
* When you have finished with the service call this method to stop it
* releasing your connection and resources
*/
public void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
mContext.unbindService(mConnection);
mIsBound = false;
}
}
}

The ScheduleClient talks to the ScheduleService, within the ScheduleService we call our task, the task runs on another thread so that the service can run the task then return immediately.

ScheduleService.java

package com.blundell.tut.service;
import java.util.Calendar;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.blundell.tut.service.task.AlarmTask;
public class ScheduleService extends Service {
/**
* Class for clients to access
*/
public class ServiceBinder extends Binder {
ScheduleService getService() {
return ScheduleService.this;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ScheduleService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
private final IBinder mBinder = new ServiceBinder();
/**
* Show an alarm for a certain date when the alarm is called it will pop up a notification
*/
public void setAlarm(Calendar c) {
// This starts a new thread to set the alarm
// You want to push off your tasks onto a new thread to free up the UI to carry on responding
new AlarmTask(this, c).run();
}
}

The Schedule service starts our AlarmTask. Within the Alarm Task we set a reminder for the Android system to inform us when that future date is hit. For this we use the systems AlarmManager service, the AlarmManager takes an intent to fire at this date. Our intent starts another service called the NotifyService. The NotifyService is how we will show a notification. The only caveat with the system AlarmManager is if the phone is turned off and on your alarm is lost. Quickly thinking, the way round this would be to have your app be notified of the phone starting up and re-starting your alarms.

AlarmTask.java

package com.blundell.tut.service.task;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.blundell.tut.service.NotifyService;
/**
* Set an alarm for the date passed into the constructor
* When the alarm is raised it will start the NotifyService
*
* This uses the android build in alarm manager *NOTE* if the phone is turned off this alarm will be cancelled
*
* This will run on it's own thread.
*
* @author paul.blundell
*/
public class AlarmTask implements Runnable{
// The date selected for the alarm
private final Calendar date;
// The android system alarm manager
private final AlarmManager am;
// Your context to retrieve the alarm manager from
private final Context context;
public AlarmTask(Context context, Calendar date) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.date = date;
}
@Override
public void run() {
// Request to start are service when the alarm date is upon us
// We don't start an activity as we just want to pop up a notification into the system bar not a full activity
Intent intent = new Intent(context, NotifyService.class);
intent.putExtra(NotifyService.INTENT_NOTIFY, true);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Sets an alarm - note this alarm will be lost if the phone is turned off and on again
am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent);
}
}

When the Android system fires our alarm, the intent we set starts our NotifyService. This NotifyService is pretty similar in setup to our ScheduleService, however because we don’t want to bind the service to an activity we just start the service up (not using a client), then call our reminder method and shut it down again. The notification will pop into the system menu informing the user. Notifications can have different properties like, sounds, text, images. You’ll find a whole chapter on them here.

NotifyService.java

package com.blundell.tut.service;
import android.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.blundell.tut.ui.phone.SecondActivity;
/**
* This service is started when an Alarm has been raised
*
* We pop a notification into the status bar for the user to click on
* When the user clicks the notification a new activity is opened
*
* @author paul.blundell
*/
public class NotifyService extends Service {
/**
* Class for clients to access
*/
public class ServiceBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}
// Unique id to identify the notification.
private static final int NOTIFICATION = 123;
// Name of an intent extra we can use to identify if this service was started to create a notification
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
// The system notification manager
private NotificationManager mNM;
@Override
public void onCreate() {
Log.i("NotifyService", "onCreate()");
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// If this service was started by out AlarmTask intent then we want to show our notification
if(intent.getBooleanExtra(INTENT_NOTIFY, false))
showNotification();
// We don't care if this service is stopped as we have already delivered our notification
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients
private final IBinder mBinder = new ServiceBinder();
/**
* Creates a notification and shows it in the OS drag-down status bar
*/
private void showNotification() {
// This is the 'title' of the notification
CharSequence title = "Alarm!!";
// This is the icon to use on the notification
int icon = R.drawable.ic_dialog_alert;
// This is the scrolling text of the notification
CharSequence text = "Your notification time is upon us.";
// What time to show on the notification
long time = System.currentTimeMillis();
Notification notification = new Notification(icon, text, time);
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, title, text, contentIntent);
// Clear the notification when it is pressed
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Send the notification to the system.
mNM.notify(NOTIFICATION, notification);
// Stop the service when we are finished
stopSelf();
}
}

And thats it, we have our notification! When this notification is pressed it starts a new activity bringing the user back into your app.

I tried to reply your code, but I not have success with that.. In your “onDateSelectedButtonClick” I have “Cannot make a static reference to the non-static method setAlarmForNotification(Calendar) from the type ScheduleClient” ( in my code, do not have onDate… I just create a class for that and I call in onCreate. Have you any clue for that?
Thank you for this tutorial!

thank you so much for such a nice tutorial and I know its bit old post, I just started android dev :). I am facing a problem with this code. My notifications getting fired instantly. this what I am doing.

Very nice tutorial…
I want to set dynamic multiple alarms for notifications…
they can be on same time…
How to do that… Right now in this example only last alarm is notifying..
Please help me I need urgent help…

Dear Sir,
I want to provide notification on particular date and time, How to set all date in java file, i do not want to insert date or time from user side but i want to set already in application which provides notification to user on that date and time with any kind of message. Please Help me How to sort out this problem ?

Hi blundell i want to set the alarm from time picker..how do i do that…i need to use both date picker and time picker…i have to schedule alarm based on the date and time given by the user…any help would be appreciated…

Dear Sir.. Thanks For Usefull Tutorial. I Want quick answer. I Want to generate notification automatically without use interface. Like AS Example. I want to set notification in application for perticular days of any month and den user will get notification at that day without use interface. like i want to provide notification without set notification by user. Please Reply me here or mail me. how it can be possible.

Wow great tutorial thank You very much!
I do have a little question though. I would like to pick a time when the alarm notification should pop up. However, this time will be time embedded into the app not by the actual user. Moreover, I don’t need to pass date, just time. How would I approach this?

you would have to remove the datepicker, and just set the alarm on app startup, because you want time and not just date, what you should do is set an alarm for tomorrow, then when that alarm is set off, reset it for the next etc etc.

Thanks for the tutorial – after a long search I finally found what I was looking for

However I still have an issue: I want to reset the alarm once it has been triggered. If the app has been closed (by the task manager) in the meantime I can’t bind the service, mContext.bindService(…) [ScheduleClient line 35 in the example] throws a NullPointerException. Does anyone know a way around that? Help would be greatly appreciated

Hi, thankz for the great tutorial. I’ve actually used it in an app that I’m developing. I have a little problem though. I was thinking if you have already an update of this notification tutorial? It seems I cant get the app to work with multiple notifications and on start-up. Can you help me? Thanks.

You would need a different notification ID for each notification to get them to show simultaneously. Yes this tutorial drops notifications if the phone is turned off. You would need to persist them in preferences and have a broadcast receiver for the phone being turned on to set them up again.

when i run this code with onDateSelectedButtonClick(View v) there is not any error. but when i write a new method then fill inside with “onDateSelectedButtonClick” content. And calling new method gives me null pointer exception on:

1. Ensure the package names in manifest, and the NotifyService.java (for “INTENT_NOTIFY”) are correct.
2. I could not get mConnection to be created whenever I am debugging the code. The solution was to override onCreate for the service, and add the following lines:

Hello. Very nice tutorial. Now, im having problems settings 2 different notification. If i set for ex 2 notification of 2 different appointments, it just fires the first one, at the time of the second. I set for each of em different ids, but this doesnt works. Any issue?

I do not fully understand why we need the ScheduleService and do not call run the AlarmTask directly from the Activity. In the description, blundell states ” .. you don’t want to use the UI thread, as this means the system can’t draw anything … So we start a new service, “. But the AlarmTask runs in it’s own thread anyway, so I do not see the why the ScheduleClient & ScheduleService is needed to start a Runnable Task.

Just because something is a `runnable` does not mean it is in it’s own Thread. Runnable just means it implements the interface that you can ‘run’ this class. You need to start a thread and pass it a ‘runnable’ the thread understands what to do with classes that implement runnable i.e. call there run method. If you call run yourself say from ‘onCreate’ this would still be ‘ran’ on the UI thread.

Hi,
This has helped me alot thank you very much for that pal. i was just wandring im creating location based reminder app so any suggetion that you could give me as in what to keep in mind and so on Please.

Thank you for this helpful tuto
But when i added services to create a notification at a specific time which is choosen by the user i usually get Java.Lang.NullPointerException in scheduleClient.setAlarmNotification(c).
ideclared all service in Manifest and i call doBindService and i change the context when i define scheduleClient.
Any idea please???

Good tutorial, i’m sure it will work but my eclipse does not suppost the ScheduleClient handler. Whenever i enter ScheduleClient it suggests other tags like ScheduledExecutorService, ScheduledThreadPoolExecutor etc. I there some problem with my eclipse ADT ot something else? Kindly suggest a solution. Thannks!

Hi, thanks again for all your help! Is there something that I can do to your code in order to make the notifications persist even after the phone has been switched off and switched back on/rebooted? Thank you!

Sure you’ll need to add a Broadcast receiver that listens for phone restarts, you then reset the notification then. I suppose if you kept notification ids and the date of the alarm in sharedpreferences you could retrieve them from there.

Hey, thank you so much for your tutorial! It really really really helps. 😀 I have a quick question, kind of like an add-on to your tutorial: How do we delete a notification and prevent it from occurring? Let’s say that the user deletes a reminder before it goes off… How would you prevent the notification from going off because the user deleted the reminder? Thanks again! 😀

Hi blendell, I have solved the problem of using custom layout for notifications. But now i am stuck into another problem. Actually i am generating notifications on button’s click event. So its works fine for the first time. but when we click the button again then i am getting null value of IBinder object in onServiceConnected method of ServiceConnection in ServiceClient.java, waiting for your suggestions and thanks in advance.

Liked your tutorial a lot. I’m facing a problem that I have FragmentActivity as the Main Activity . I am unable to trigger the pendingIntent of the alarmTask.The notification never shows up because the notifySerive is never started by the alarm task.
Can you please let me know how do I solve this problem.I’ve been stuck with this for over 3 days now.

Hi blundell
I know that it’s long since you last posted on this forum. I have been working on an application that requires reminders and thus have been using your example. I ran it on its own and it worked perfectly but when I try to incorporate it into my app it’s giving me a problem of NullPointerException with my mBoundService. I tried debugging it and it shows that the intent that is being passed in the doBindServices is null. I copied everything including the declerations in the manifest but still the error is there. Have been getting the same error for more than a week and would be grateful if could help me.

This is an amazing tutorial, it helped me a lot while trying to get the main idea of notification services.
I’m trying to add it to one of my projects but i have a problem.
I add your main activity to a new tab from my app. I didnt change anything. My other tabs work properly but when i set the date for the notification and click on the button “Set notification” my app stops working. Here’s a printScreen from LogCat: http://img405.imageshack.us/img405/3060/errorsa.jpg

Yes, I call doBindservice() and I have declared the ScheduleService in the manifest file. I didnt change anything of your code, just add it to a new tab from my app.
Ive been trying to fix it for 2 days but no success.
Thanks again.

Hi, I’ve come across a problem with my phone. Sometimes in the morning my phone will randomly not wake up properly by pressing the on button. If I send texts to it it sounds but the screen wont light and I cannot turn it off. I need to remove the battery.

It first happened the night I had my app using the alarm notification installed, I use RTC.wakeUp . I’m wondering if this could be causing this?

Please help i have run the code and iam getting force close error.Logcat says it is Caused by: java.lang.ClassNotFoundException: com.service.ui.phone.MainActivity in loader dalvik.system.PathClassLoader[/data/app/com.service-1.apk]

Hi, check your manifest and ensure the name of each of your Activities is declared correctly. Then check your imports or your intents where you are switching activites. It’s something to do with your activity names!

Well thats your problem, that the service is never bound , do you call doBindService in your constructor? Double check the spelling of your service class and the name in your manifest. If your still struggling download the example project and ensure that that works on your device.

Yes I call doBindService in onCreate for my main activity in the same position as in this code. Still in the onCreate method I set up the Calendar details.

I got the sample running fine, I put it all into 1 package and changed the manifest from .service.ScheduleService to just .ScheduleService etc. I then copied each of the source files into my project and copied the relevant manifest lines.

doBindService is called as I set up a Log at the end of the method. I’ve checked class names and they are fine, so confused haha.

Thanks blundell, but in your advice, alarm is still setted. In due time, alarm is raised up and notification is appearing to the screen. After this, notification is canceled automatically. For this reason, alarm must be cancelled.

Thanks blundell, but in your advice, alarm is still setted. In due time, alarm is raised up and notification is appearing to the screen. After this, notification is canceled automatically. For this reason, alarm must be cancelled.

I would just set one notification and when this is fired in your service set the next notification that way you only need to manage one at a time. If you want multiple notifications for mutual exclusive activities it all depends on the idea of your app, but using a SQLite table with the name/date of each would help you manage them.

Thank you very much blundell! I have to make for my final exam an application like birthday reminder and this tutorial was very helpfull for me to understand the main ideea. I need more information like how to add sound alarm when the notification appear? Thank you again for your interest!

This tutorial will notify the user when the app isn’t running. However if you want to restart your alarm for after the phone going off and on. You will have to setup a broadcast receive that receives the ACTION_BOOT_COMPLETED then if you have the time of the alarm saved in your SavedPreferences you can just reset it.