AlarmManager alarm fires immediately - android

I'm testing AlarmManager to use in my app, and it is firing my Broadcast Receiver immediately when I want it to fire after 1 minute. The code is below:
public class SetMealTimersActivity extends Activity {
PendingIntent pi;
BroadcastReceiver br;
AlarmManager am;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_meal_timers);
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Ready to Go!", Toast.LENGTH_LONG).show();
}
};
registerReceiver(br, new IntentFilter("com.ian.mealtimer"));
pi = PendingIntent.getBroadcast(this, 0, new Intent(
"com.ian.mealtimer"), 0);
am = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
am.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +
60 * 1000, pi );
}

try :
am.set(AlarmManager.RTC_WAKEUP,
Calendar.getInstance().getTimeInMillis()+60*1000, pendingIntent);
it is working for me.

If using an exact alarm, make sure it's time is in the future. Otherwise it will fire immediately.

Try changing SystemClock.elapsedRealtime() to System.currentTimeMillis() and AlarmManager.ELAPSED_REALTIME_WAKEUP to AlarmManager.RTC_WAKEUP.

Try to use AlarmManager.setExact(int, long, PendingIntent) if you use Android API > 18 or compile with API < 19, because the time management for this methods changed with API 19. Maybe that helps. Read the documentation for more information.

make id for pendingIntent as this
pendingIntent = PendingIntent.getActivity(this, 999123266,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
All example
public void setAlarm_sat(int dayOfWeek1) {
cal1.set(Calendar.DAY_OF_WEEK, dayOfWeek);
Intent intent = new Intent(this, RemmemberActivity.class);
pendingIntent = PendingIntent.getActivity(this, 999123266,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Long alarmTime = cal1.getTimeInMillis();
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,
alarmTime,7*24 * 60 * 60 * 1000,
pendingIntent);
// am.set(AlarmManager.RTC, cal1.getTimeInMillis(), pendingIntent);
}

Related

Cannot cancel repeating alarm

I am using targetSdkVersion 24. I set up an alarm like this:
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pIntent);
where interval is 15 x 60 x 1000 = 15 min. This alarm is set in a check box in the preferences. On a HTC One running API 23 the alarm goes off as expected. However, when I cancel this alarm by unchecking the preference, the alarm keeps going off. This is my cancel code:
if (alarmMgr != null) {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.cancel(pIntent);
}
What am I missing?
You will need to hold on to the original PendingIntent object you use in alarmMgr.setRepeating(...) instead of creating a new one. Something like this should help;
PendingIntent startAlarm(Context context){
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pIntent);
return pIntent;
}
void stopAlarm(Context context, PendingIntent pIntent) {
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (alarmMgr!= null) {
alarmMgr.cancel(pIntent);
}
}
Then usage in your class would be something like the following (here I used onPause and onResume of an Activity):
PendingIntent alarmIntent;
#Override
protected void onResume() {
super.onResume();
alarmIntent = startAlarm(this);
}
#Override
protected void onPause() {
super.onPause();
if (alarmIntent != null) {
stopAlarm(this, alarmIntent);
alarmIntent = null;
}
}
HTHs!!!
Thanks to Blehi, I found that the code was not called. The part was this:
if (alarmMgr != null) {
alarmMgr.cancel(chewIntent);
}
AlarmReceived is implemented as Singleton, while the AlarmManager is instantiated in my setAlarm. So alarmMgr was null when the alarm was canceled.

Multiple intents but Broadcast receiver only called once

I want to perform a database operation at specific moments in time and use an alarm manager and a pending intent in conjunction with a broadcast receiver.
This works, but when there are multiple intents that the same broadcast receiver has to receive within a short timeframe (f.ex. within a minute), onreceive() only gets called once.
Intent intent2 = new Intent(this, CustomBroadcastReceiver.class);
intent2.putExtra("taskId", currentTask.getTaskId());
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +
((long) dataSource.fetchTask(task.getTaskId()).getTaskTime() * 60 * 1000), pendingIntent1);
and the onreceive method of the broadcastreceiver:
#Override
public void onReceive(Context context, Intent intent) {
dataSource = new DataSourceClass(context);
dataSource.open();
int taskId = intent.getIntExtra("taskId", 0);
dataSource.setTaskStatus(3, taskId);
dataSource.setCatInActive(dataSource.fetchTask(taskId).getTaskCategory())
}
Any suggestions on what I'm doing wrong?
Instead of set() you can use setExact() after KITKAT:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
}
The second parameter in getBroadcast() is the requestCode, which works as if it was an ID, so, each PendingIntent should have a unique requestCode (aka ID). All your pendingIntent1's have the same requestCode (0), I'm not sure if that's what's causing the issue but it could be, you can set a diffrent requestCode for each pendingIntent like this:
int i = sharedPrefs.getInt("i", 0);
Intent intent2 = new Intent(this, CustomBroadcastReceiver.class);
intent2.putExtra("taskId", currentTask.getTaskId());
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, i++, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +
((long) dataSource.fetchTask(task.getTaskId()).getTaskTime() * 60 * 1000), pendingIntent1);
sharedPrefs.edit.putInt("i", i).apply();

Android Notification starting up on launch instead of at the set time

I am currently trying to create a repeating alarm that goes off at the same time everyday following a tutorial however I cannot seem to get it working. It goes off but as soon as the application launches instead of the set time I am not sure what the reason is. I also made sure the service was declared in manifest. Any idea where I am going wrong or if this the right way to go about something like this?
Main acitivty
public class MainActivity extends AppCompatActivity {
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
int i = preferences.getInt("numberofLaunces", 1);
if (i < 2) {
alarmMethod();
i++;
editor.putInt("numberoflaunches", i);
editor.commit();
}
if (savedInstanceState == null) {
return;
}
}
private void alarmMethod() {
Intent myIntent = new Intent(this, NotifyService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.set(Calendar.DAY_OF_MONTH, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
Toast.makeText(MainActivity.this, "start Alarm", Toast.LENGTH_LONG).show();
}
}
Notifyservice
public class NotifyService extends Service {
#Override
public IBinder onBind(Intent Intent) {
return null;
}
#Override
public void onCreate(){
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1,0);
Notification mNotify = new Notification.Builder(this)
.setContentTitle("placeholder tital")
.setContentText("Placeholder text")
.setSmallIcon(R.drawable.ic_cat)
.setContentIntent(pIntent)
.setSound(sound)
.addAction(0,"hello", pIntent)
.build();
mNM.notify(1, mNotify);
}
}
From developer [site](http://developer.android.com/reference/android/app/AlarmManager.html#set(int, long, android.app.PendingIntent))
The alarm is an Intent broadcast that goes to a broadcast receiver that you registered with registerReceiver(BroadcastReceiver, IntentFilter) or through the tag in an AndroidManifest.xml file.
You should define broadcast pending intent instead of service.
Change this
Intent myIntent = new Intent(this, NotifyService.class);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
To this
Intent myIntent = new Intent(this, MyAlarmBroadcastReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
Then implement MyAlarmBroadcastReceiver extends BroadcastReceiver class and fire notification inside onReceive().
The problem is quite simple: If the time a alarm should fire (the second parameter in setRepeating()) is in the past, it will fire immediately. The time you specified is 0:32 am in the night of the 0th (?) day of the month.
This is always in the past (maybe except for 32 minutes every month, though I don't know what the 0th day of the month is).
To fire the alarm every 24 hours at the time of 0:32 am use something like this:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, new Date().after(calendar.getTime()) ? 1 : 0); //if the current time is after 0:32 am, one day is added
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);

AlarmManager Broadcast Receiver

I'm making an app which uses an AlarmManager and a Broadcast Receiver to generate a notification everyday at 8:20 AM.
One issue which I'm facing is that every time I open the app after 8:20 AM, the notification is generated.
I guess this is because I have called the receiver in the onCreate() method.
Is there a way to make sure that the receiver is registered only once?
Here is my code :
public class MainActivity extends AppCompatActivity
{
AlarmManager alarmManager;
private PendingIntent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 00);
calendar.set(Calendar.MINUTE,30);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
}
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context,"Alarm Raised",Toast.LENGTH_SHORT).show();
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent1 = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,intent1,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_account_circle_black_18dp);
builder.setContentTitle("Tracker");
builder.setContentText("Turn on Gps");
builder.setPriority(Notification.PRIORITY_MAX);
builder.setDefaults(Notification.DEFAULT_SOUND);
builder.setLights(0x0000FF,3000,2000);
builder.setContentIntent(pendingIntent);
notificationManager.notify(56, builder.build());
}
}
The second parameter of setInexactRepeating indicates that when should the AlarmManager start its task. So if you give it a time in past it will fire once immediately. You must check if the calendar.getTimeInMillis() is before now and add a day to it if so.
So you should simply change this part of your code
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
to this:
long timeToStart = calendar.getTimeInMillis();
if(System.currentTimeMillis() < timeToStart){
timeToStart += 24 * 60 * 60 * 1000; // one day
}
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, timeToStart, AlarmManager.INTERVAL_DAY, alarmIntent);

What this code does? and Why my alarm is not stopped?

Intent in2 = new Intent(context, ReminderService.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, in2, 0);
AlarmManager alarmManager2 = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
alarmManager2.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), 0, pendingIntent2);
and the reminderservice.java include the following code
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Context context = getApplicationContext();
Intent in = new Intent(this, RemindBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, in, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), 1000, pendingIntent);
}
First of all I suggest you to just use only RemindBroadcastReceiver. There isn't any need of ReminderService
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), 1000, pendingIntent);
Here you have set repeated alarm which triggered after every 1 second. You need to use alarmManager.set instead of alarmManager.setRepeating.
I think bellow code will be helpful for you:
/------------------- CALLING PART
Intent in2 = new Intent("MY_ALARM_ACTION");
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 0, in2, 0);
AlarmManager alarmManager2 = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
//alarmManager2.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), pendingIntent2);
alarmManager2.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (5 * 1000), AlarmManager.INTERVAL_DAY, pendingIntent2);
}
/-------------------
/-------------------------- RemindBroadcastReceiver ----------------
public class RemindBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction() == "MY_ALARM_ACTION")
{
// TODO Enter your code here
}
}
}
You didn't explain what you want this code to do so we can't really know, but these are some errors I see anyway:
I assume that ReminderService is a subclass of Service, therefore you should use PendingIntent.getService rather than PendingIntent.getBroadcast.
In the first piece of code you call setRepeatig with the parameter intervalMillis = 0, and never calling AlarmManager.cancel, which I guess is an error because Android won't trigger your alarm forever, non stop.
Why are you starting a service just so you can set another alarm to trigger something else inside it?
Please explain the purpose of your code.

Categories

Resources