简体   繁体   中英

AlarmManager fires late or doesn't fire at all

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

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM