Simple AlarmManager example for firing an activity in 10 minutes - java

I've found many similar questions to this, but they're too complicated (too much code), at least I think.
Can this thing be done in a few code of lines? I want to fire an activity in 10 (let's say) minutes, that's it. Thank you.

To Set Alarm for 10 Minutes(let's say) Use this code
AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, ShortTimeEntryReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),10*60*1000, pendingIntent);
To Start Activity
public class ShortTimeEntryReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
// Your activity name
Intent newIntent = new Intent(context, ReminderPopupMessage.class);
newIntent.putExtra("alarm_message", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
In your Manifest File Add the following
<receiver android:name=".ShortTimeEntryReceiver"
android:enabled="true"
android:process=":remote">
</receiver>

This function I use sets or cancels an alarm depending on the "Set" parameter
public static void SetAlarm(Context c, long AlarmTime, int ItemID, String Message, Boolean Set) {
Intent intent = new Intent(c, AlarmReceiver.class);
intent.putExtra("Message", Message);
intent.putExtra("ItemID", ItemID);
PendingIntent sender = PendingIntent.getBroadcast(c, 8192 + ItemID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Clear the seconds to 0 for neatness
Calendar ca = Calendar.getInstance();
ca.setTimeInMillis(AlarmTime);
ca.set(Calendar.SECOND, 0);
AlarmTime = ca.getTimeInMillis();
// Get the AlarmManager service
AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
if (Set) {
am.set(AlarmManager.RTC_WAKEUP, AlarmTime, sender);
} else {
am.cancel(sender);
}
}
You would then need a Broadcast Receiver to handle the alarm and do whatever it is you want to do.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String Message = bundle.getString("Message");
int ItemID = bundle.getInt("ItemID");
// Do what you want to do, start an activity etc
} catch (Exception e) {
e.printStackTrace();
}
}
}

Related

Repeated alarm is not accurate

I made an app which has a number picker ranging from 1 to 60 minutes, and I connected it to a repeated alarm manager. When I gave it a try, I noticed that it's not accurate sometimes, it either takes more minutes to work or less.
What could be the problem?
For the start button:
startB.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (startB.isChecked())
{
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.MINUTE, picker2.getValue());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
setAlarm(calSet);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = true;
}
else
{
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = false;
}
}
});
For the alarm:
private void setAlarm(Calendar targetCal ) {
// TODO Auto-generated method stub
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
targetCal.getTimeInMillis(),
TimeUnit.MINUTES.toMillis(picker2.getValue()),
pendingIntent);
}
Receiver:
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer m=MediaPlayer.create(context, R.raw.sound);
m.start();
}
The Android OS is able to shift alarms in order to minimize wakeups and battery consumption (since API 19). Take a look here. I noticed delays up to a few seconds.
A pretty nice tutorial on alarms in general could be found here

Getting Android Alarms Info

Iv'e created several Alarms using an Intent and BroadcastReciever and placed them in an Array of Intents.
For each Intent Iv'e placed a String as in Intent.PutExtra("info", string); to be shown later as a Toast when Alarm is activated,
and gave each a different requestCode.
But when adding multiple Alarms, the Toast shows EVERY other Alarms' info as well.
MainActivity:
Intent newAlarmIntent = new Intent(this,AlarmReceiver.class);
newAlarmIntent.putExtra("info",editText.getText().toString());
alarmsArray[alarmCounter]=newAlarmIntent;
alarm.AlarmListSortAndSetNext(gameArrayList, alarmArray, this,alarmCounter,alarmsArray[alarmCounter]);
Alarm Class:
public void CreateNew (Context context, Long alarmTimeAsLong, int counter, Intent intent)
{
PendingIntent pendingIntent;
pendingIntent = PendingIntent.getBroadcast(context, counter, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager;
manager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP, (alarmTimeAsLong),pendingIntent);
Toast.makeText(context, "Alarm Set", Toast.LENGTH_SHORT).show();
}
public void AlarmListSortAndSetNext (ArrayList<Game> gameArrayList,Long[] alarmArray,Context context,int alarmCounter, Intent intent)
{
Long SystemTimeAsLong = System.currentTimeMillis();
//Sorting Long Array for NEXT ALARM
for (int i=0;i<10;i++)
{if(i<gameArrayList.size()){
alarmArray[i] = gameArrayList.get(i).getDateAndTimeAsLong();
}
else alarmArray[i]= 0L;
}
Arrays.sort(alarmArray);
//Setting next ALARM by Long Size
for(int i=0;i<10;i++)
{
if (alarmArray[i]>SystemTimeAsLong){
CreateNew(context,alarmArray[i],alarmCounter,intent);
alarmCounter++;}
}}
AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();
String gameInfo= intent.getStringExtra("info");
Toast.makeText(context, gameInfo, Toast.LENGTH_SHORT).show();
MediaPlayer mp = MediaPlayer.create(context, R.raw.bipbip);
mp.start();
wakeLock.release();}}
QUESTION: How can I make each Intent to have it's on "info"/PutExtra, or any other way to tell which one has been activate?
* Found the issue *
I had left the AlarmListSortAndSetNext method which initially was supposed to manage the Next Alarm. I no longer have to use this method since I have created multiple Intents. Something in the looping probably created multiple putExtra();
Thank you.

Set Multiple Alarms on BOOT_COMPLETED in Android

I am trying to laod some tasks from DB on BOOT_COMPLETED and set alarm for each of them.
Alarm Manager is configured to receive BOOT_COMPLETED in AndroidMAnifest File.
Sometime I get these task via SMS, so i have a brodcastreceiver for sms receiving and processing, which builds task list and calls AlarmManager.setAlarms().
I am wondering that setAlarams works fine when called from OnReceive() method og SMSReceiver, but does not work properly when called from OnReceive() method of AlarmManager on Boot_Completed. it just sets one Alarm and ignores the rest of the list!
any help on this?
thanks in advance
public class AlarmManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
List <Task> taskList= db.loadFromDB();
setAlarms(context, taskList);
}
public static void setAlarms(Context context, List<Task> taskList) {
for each task in taskList{
int pendingIntentRequestCode = task.getid();;
Intent myIntent = new Intent(context, AlarmReceiver.class);
myIntent.putExtra("taskName", task.getName());
myIntent.putExtra("taskHour", task.getHour));
myIntent.putExtra("taskMinute", task.getMinute());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
pendingIntentRequestCode,
myIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,alarmTime, pendingIntent );
}
}
}
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String taskName = intent.getStringExtra("taskName");
int taskHour = intent.getIntExtra("taskHour", -1);
int taskMinute = intent.getIntExtra("taskMinute", -1);
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, taskName);
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, ataskHour);
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, taskMinute);
alarmIntent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmIntent);
}
}
public class SMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String messageReceived = "";
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
messageReceived += msgs[i].getMessageBody().toString();
sender = msgs[i].getOriginatingAddress();
messageReceived += "\n";
}
List <Task> taskList = MakeTaskListFromReceivedSMS(messageReceived);
AlarmManager.setAlarms(context, taskList);
}
}
}
According to the documentation:
If there is already an alarm scheduled for the same IntentSender, it
will first be cancelled.

Unable to cancel the alarm from AlarmManager

I have an AlarmManager that notifies me every 10 seconds. Everything works just fine but for some reason I can't cancel the alarm. Here's my code.
public class AlarmNotifReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
//things
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10*1000, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
Intent i = new Intent(context, AlarmNotifReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
}
as expected I call this CancelAlarm() method from my other classes but for some reason it does not cancel and keep notifying me like nothing happened.
Note: SetAlarm() also works just fine.
Thanks in advance.
Alarm should be created and cancelled on Same Pending intent.In your case you are creating Pending Intent Twice.
Your code should look like below.
public class AlarmNotifReceiver extends BroadcastReceiver {
PendingIntent pi;
AlarmManager am;
Intent i;
#Override
public void onReceive(Context context, Intent intent) {
pi = PendingIntent.getBroadcast(context, 0, i, 0);
am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
i = new Intent(context, AlarmNotifReceiver.class);
//things
}
public void SetAlarm(Context context) {
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 1000, pi);
}
public void CancelAlarm(Context context) {
am.cancel(pi);
}
}
Try to cancel Pendingintent--
PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT).cancel();
Hope this helps
Try this.
Android: Get all PendingIntents set with AlarmManager
To cancel all alarm, first you have to find all the pending intent for that and cancel alarm using that.
Try like this
public class AlarmNotifReceiver extends BroadcastReceiver {
AlarmManager am = null;
#Override
public void onReceive(Context context, Intent intent)
{
Intent i = new Intent(context, AlarmNotifReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
//things
}
public void SetAlarm(Context context)
{
am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10*1000, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
am.cancel(pi);
}
}
Your problem is that you're creating a NEW intent instead of cancelling the existing one. Function SetAlarm should place the intent into a "global" variable and the CancelAlarm function should just call
am.cancel(global_pi);
The above worked for me in a service, but:
If this is impossible (since that's a Receiver), try setting a new alarm with the (new) intent first.

Alarm Manager is running immediately

Date dat = new Date();
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY, hrs);// set the alarm time
cal_alarm.set(Calendar.MINUTE, min);
cal_alarm.set(Calendar.SECOND, 0);
cal_alarm.set(Calendar.MILLISECOND, 0);
if (cal_alarm.before(cal_now)) {// if its in the past increment
cal_alarm.add(Calendar.DATE, 1);
}
Intent intent = new Intent(ctx, AlarmReceiver.class);
// intent.putExtra("Reminder to Take Photo", "Pixitch!");
PendingIntent sender = PendingIntent.getBroadcast(ctx, 0010000,
intent, 0);
// Get the AlarmManager service
long tmemills = cal_alarm.getTimeInMillis()
- cal_now.getTimeInMillis();
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, tmemills,
AlarmManager.INTERVAL_DAY, sender);
Alarm Receiver Class
public class AlarmReceiver extends BroadcastReceiver {
private static final int MY_NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private Notification myNotification;
// Context ctx = this;
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context context, Intent intent) {
try {
NotificationManager mNM;
mNM = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.ic_launcher, "Pixitch Notification !",
System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, AlarmManage.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(context, "Pixitch Notification!",
"Reminder For TakePhoto", contentIntent);
mNM.notify(0, notification);
} catch (Exception e) {
Toast.makeText(
context,
"There was an error somewhere, but we still received an alarm",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
the value of tmemills is 278,088
the tmemills is around 4.5 minutes but
the alarm Manager is Running immediately
I am not able to find where the problem is because I am beginner for Android. please help me
Try this:
am.setRepeating(AlarmManager.RTC_WAKEUP, tmemills + System.currentTimeMillis(),
AlarmManager.INTERVAL_DAY, sender);
Get rid of tmemills. Use cal_alarm.getTimeInMillis() as the second parameter to your set() call on AlarmManager, as that is the number of milliseconds since the Unix epoch at which you want the event to occur.

Categories

Resources