Categories
Android

Android and Alarms

Since I joined the Android user groups, there have been a lot of questions about 2 things – databases and alarms. I have already written a post about how to use a database in Android and in this one, I will talk about how to use Alarms. If there are any other topics you would like to see a tutorial on, please feel free to let me know. You can leave your requests in the comments section. Oh, and this post (like previous posts) is for Android 1.0.

Alarms in Android are not used in a conventional way. When your application sets an alarm, it’s just telling that alarm service to wake it up at a certain time. The user won’t hear any sounds and the phone won’t vibrate (unless your application plays a sound or makes the phone vibrate after it wakes up). Alarms will work if the device goes to sleep but they are cleared if the device is turned off or restarted. So, you will need to set the alarm again if you want it to “go off” even after a device re-boot.

Our receiver class will be called “AReceiver” (without the quotes, of course). In the manifest file, we will add this line (which is in bold below):

<application android:icon=”@drawable/icon5″ android:label=”@string/app_name”>
<activity android:name=”.SomeApp” android:label=”@string/app_name”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<receiver android:name=”AReceiver” android:process=”:remote” />

Now, that the alarm receiver is set, lets take a look at the class that will set and cancel the alarms:

package SomeApp.SomeApp;

import java.util.Calendar;

import java.lang.String;

import android.app.AlarmManager;
import android.app.ListActivity;
import android.app.PendingIntent;
import android.os.Bundle;
import android.util.Log;

import android.content.Intent;
import android.widget.Toast;

/**
 * When this code is run only one alert will be displayed even though 2 alerts were
 * were setup (as one of them will be cancelled later on
 */
public class SomeApp extends ListActivity {
	/* for logging - see my tutorial on debuggin Android apps for more detail */
	private static final String TAG = "SomeApp "; 

	protected Toast mToast; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.alert_list);
        try {

		Calendar cal = Calendar.getInstance();

		Intent intent        = new Intent(SomeApp.this, AReceiver.class);
		PendingIntent sender = PendingIntent.getBroadcast(this, 1234567, intent, 0);
		PendingIntent sende2 = PendingIntent.getBroadcast(this, 123123, intent, 0);

		AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
		am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+30000, sender); // to be alerted 30 seconds from now
		am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+15000, sende2); // to be alerted 15 seconds from now

		/* To show how alarms are cancelled we will create a new 		Intent and a new PendingIntent with the
	 	* same requestCode as the PendingIntent alarm we want to cancel. In this case, it is 1234567.
         	* Note: The intent and PendingIntent have to be the same as the ones used to create the alarms.
         	*/
		Intent intent1        = new Intent(SomeApp.this, AReceiver.class);
		PendingIntent sender1 = PendingIntent.getBroadcast(this, 1234567, intent1, 0);
		AlarmManager am1 = (AlarmManager) getSystemService(ALARM_SERVICE);
		am1.cancel(sender1);

        } catch (Exception e) {
        	Log.e(TAG, "ERROR IN CODE:"+e.toString());
        }
    }

}

You will notice that this is only a “one-shot” alarm. If you want to set a repeating alarm, it is explained in Android’s documentation. However, I will write on that too if there is demand for it. Now, let’s examine the code. For setting an alarm, you will need 4 things:

  • The class that’s setting the alarm
  • The class that will be called when the alarm “goes off”
  • The time at which the alarm should go off
  • A requestCode (which will use as a unique ID to identify the alarms) used in PendingIntent.

For cancelling an alarm, you need 3 things:

  • The class that set the alarm
  • The class that was to be called when the alarm “goes off”
  • The requestCode you used for PendingIntent object.

We have covered 2 things – the declaration of the receiver in our manifest file and the class that sets and cancels alarms. Now, we need to look at the class that will be called when the alarm goes off.

package someApp.someApp;

import java.util.Calendar;

import android.content.Context;
import android.content.BroadcastReceiver;
import android.util.Log;
import android.widget.Toast;

/** All receiver classes must extend BroadcastReceiver */
public class AReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context con, Intent in) {
		try {
			/* Display an alert */
			Toast.makeText(con, "hello my jello ", Toast.LENGTH_LONG).show();
		} catch (Exception r) {
			Toast.makeText(con, "You were supposed to do something"
					+" now but I can't retrieve what it was.",
					Toast.LENGTH_SHORT).show();
			Log.e("ALARM_RECEIVER", r.toString());
		}
	}
}