Reputation: 5192
Hi everybody I'm trying to learn how to use AlarmManager
and BroadcastReceiver
in Android.
I'm having some problems with the AlarmManager
:
I'm setting two alarms at 1 minute distance, but only one fires and it is some minutes late (not predictable i guess).
Here's my main activity (i'm setting Alarms by tapping a button)
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Intent intent;
PendingIntent pendingIntent;
AtomicInteger atomicInteger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
intent = new Intent(Constants.EXTENDED_DATA_STATUS);
atomicInteger = new AtomicInteger();
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.start_button);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = atomicInteger.incrementAndGet();
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),id,intent,0);
Calendar firstLullo = Calendar.getInstance();
Calendar secondLullo = Calendar.getInstance();
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE,55);
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
}
Log.d("ALARM","settato con id " + String.valueOf(id));
}
});
}
}
My Receiver simply shows a Toast and makes the phone vibrate.
Constants.EXTENDED_DATA_STATUS
is a string from a Constants
class and it's added to the intent-filter
of my Reveiver in the Android Manifest.
What am i missing? I googled a lot and only found that i have to use setExact()
but no luck..
Thanks in advance
Upvotes: 0
Views: 1308
Reputation: 4500
The reason why only one fires is because your canceling your first one always
From the docs: If there is already an alarm scheduled for the same IntentSender, that previous alarm will first be canceled.
To fix this, use different PendingIntents for both alarms.
- To let your receiver fire multiple times, reschedule it in your onReceive()
Example: Only if u want two receivers apart from eachother!
//Declare AlarmManager
AlarmManager am = (AlarmManager) LayoutActivity.this.getSystemService(ALARM_SERVICE);
//create new calendar instance for your first alarm
Calendar startTime= Calendar.getInstance();
//set the time of your first alarm
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE, 55);
firstLullo.set(Calendar.SECOND, 0);
//create a pending intent
PendingIntent firstPI = PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourFirstAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, firstAlarm.getTimeInMillis(), firstPI);
//----------------------------------------------------
//create new calendar instance for your second alarm
Calendar endCalender = Calendar.getInstance();
//Set the time alarm of your second alarm
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
secondLullo.set(Calendar.SECOND, 0);
//create a pending intent to be
PendingIntent secondPI= PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourSecondAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, secondLullo.getTimeInMillis(), secondPI);
Register alarms in Manifest.XML:
<receiver android:name="firstAlarm" >
<intent-filter>
<action android:name="yourFirstAlarmReceiver" >
</action>
</intent-filter>
</receiver>
<receiver android:name="secondAlarm" >
<intent-filter>
<action android:name="yourSecondAlarmReceiver" >
</action>
</intent-filter>
</receiver>
Now u can call your alarms with:
First Alarm:
public class yourFirstAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when first alarm goes off
}
}
Second Alarm:
public class yourSecondAlarmReceiverextends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when second alarm goes off
}
}
Should help u out.
Upvotes: 5
Reputation: 798
Yes, of course the above code will trigger only one Alarm, because you are setting same id for both alarms.
Alarm are identified and differentiated by their id in pendingintent.
Use different id for different alarms
Update Code:
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1234 ,intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 5678, intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
Upvotes: 1