简体   繁体   English

AlarmManager延迟触发或根本不触发

[英]AlarmManager fires late or doesn't fire at all

Hi everybody I'm trying to learn how to use AlarmManager and BroadcastReceiver in Android. 大家好,我正在尝试学习如何在Android中使用AlarmManagerBroadcastReceiver 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). 我在使用AlarmManager遇到一些问题:我在1分钟的距离处设置了两个警报,但是只有一个会触发,并且延迟了几分钟(我想这是无法预测的)。

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. 我的接收器仅显示一个Toast,并使手机振动。 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. Constants.EXTENDED_DATA_STATUSConstants类中的一个字符串,它已添加到Android清单中我的Reveiver的intent-filter中。

What am i missing? 我想念什么? I googled a lot and only found that i have to use setExact() but no luck.. 我用setExact()搜索了很多,只发现我必须使用setExact()但没有运气。

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. 从文档中:如果已经为同一IntentSender安排了警报,则该先前的警报将首先被取消。

To fix this, use different PendingIntents for both alarms. 要解决此问题,请对两个警报使用不同的PendingIntents

- To let your receiver fire multiple times, reschedule it in your onReceive() -要让您的接收多次触发,请在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 : 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. 是的,上面的代码当然只会触发一个警报,因为您为两个警报设置了相同的ID。

Alarm are identified and differentiated by their id in pendingintent. 警报通过挂起意图中的ID进行标识和区分。

Use different id for different alarms 对不同的警报使用不同的ID

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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