了解我的 AlarmManager 逻辑

Posted

技术标签:

【中文标题】了解我的 AlarmManager 逻辑【英文标题】:Understanding My AlarmManager Logic 【发布时间】:2017-01-01 10:00:27 【问题描述】:

我需要帮助来理解我使用 AlarmManager 在我的应用程序中实现的逻辑,因为该逻辑没有按我预期的那样工作。我是 android 开发新手和自学者。

逻辑:

用户使用按钮在主活动中选择时间。

该时间值用于在另一个活动中设置重复警报。

报警时出现A对话框。

主要活动:

static long ATfrom_to_millisec;

case R.id.ATfrom:

        final Calendar ATfromC = Calendar.getInstance();
        ATfromHour = ATfromC.get(Calendar.HOUR_OF_DAY);
        ATfromMinute = ATfromC.get(Calendar.MINUTE);

        // Launch Time Picker Dialog
        TimePickerDialog ATfromtpd = new TimePickerDialog(MainActivity.this,
                new TimePickerDialog.OnTimeSetListener() 

                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) 

                        //Converting to milli seconds to use in AlarmManager

                        ATfrom_to_millisec = ((hourOfDay * 60 * 60 * 1000) + (minute * 60 * 1000));

                        String AM_PM;
                        if (hourOfDay < 12) 
                            AM_PM = "AM";
                         else 
                            AM_PM = "PM";
                            if (hourOfDay > 12) 
                                hourOfDay = hourOfDay - 12;
                            
                        

                        if (minute < 10) 
                            ATfrom.setText(hourOfDay + ":0" + minute + " " + AM_PM);
                         else 
                            ATfrom.setText(hourOfDay + ":" + minute + " " + AM_PM);
                        

在上述逻辑中,用户选择的时间被转换为毫秒,并存储在一个公共静态变量中,以便其他活动使用。

警报活动:

public void onClick(View arg0) 
    // TODO Auto-generated method stub

    switch (arg0.getId())

    case R.id.bReminder:
         try 
          //Receiving the static variable's value from MainActivity
             long AT_from = MainActivity.ATfrom_to_millisec;
             float cov = (float)(AT_from/1000/60/60);
          //Toast to check if the time value is passed correctly 
             toast.makeText(getApplicationContext(), String.valueOf(cov), toast.LENGTH_SHORT).show();

             Intent intent = new Intent(this, Notifier.class);
             PendingIntent pendingIntent = PendingIntent.getActivity(this.getApplicationContext(),
                 12345, intent, 0);
    //Logic for Repeating Alarm that uses the time value from MainActivty as starting time and repeating it every 10 seconds.
    // i.e. the alarm should go off after 10 seconds from the use selected time and repeat after 10 seconds.
             AlarmManager am =
                 (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
             am.setRepeating(AlarmManager.RTC_WAKEUP, AT_from + (10*1000), 10*1000, pendingIntent);


            catch (Exception e) 

         break; 

    case R.id.bReminderStop:
        AlarmManager am =
        (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
        am.cancel(pendingIntent);

        break;

    

当使用上述实现的逻辑设置警报时,警报一旦设置就会立即消失,并以1分钟的间隔重复。 但是我实现了我的逻辑,期望警报从用户设置的时间开始 10 秒,并在每 10 秒后重复 我无法理解我的逻辑中实施的错误。 同样在吐司中,我没有得到 float cov 的十进制值 (eg : 11:30 PM 必须显示为 23.5,但显示为 23.0)

闹钟响起时的对话活动:

public class Notifier extends Activity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);


    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

    alertDialogBuilder.setTitle("HydrateTime");
    alertDialogBuilder.setMessage("Enter the amount of water");
    alertDialogBuilder.setPositiveButton("Update", null);

    AlertDialog alertDialog = alertDialogBuilder.create();
    alertDialog.show();

    

我希望在警报响起时调用上述活动。上面实现的逻辑是否足以让一个 Dialog 窗口在 Activity 结束时出现?

注意:我使用的是 Android Manifest 中的通用活动定义。

喜欢:

<activity 
        android:name=".Notifier" 
        android:label="@string/app_name">
</activity

请回答以下问题:

    我是否将 MainActivity 中设置的时间值正确传递给了另一个 Activity 中的 AlarmManager? 我的警报逻辑有什么错误以及如何纠正它以使警报按我的要求发出? 对话框的定义是否正确?清单中应该有更多定义吗?我应该为对话框活动创建任何布局文件吗?我应该使用 Dialog 类而不是 Activity 类来扩展我的 Notifier 类吗?

【问题讨论】:

注意:如果手机开启DOZE功能,报警管理器可能无法按时执行。 developer.android.com/training/monitoring-device-state/… 警报正在执行但不在预期的时间和间隔内 我的设备没有打盹功能 【参考方案1】:

逻辑有一个小缺陷。你看,如果开火时间已经过去了,那么警报就会立即响起。例如:如果我为 1983 年 1 月 2 日设置毫秒警报,它会立即触发。如果您注意到,您正在做类似的事情。

要修复它,只需将其添加到您的Alarm Activity

// Will trigger after 10 secs from set time
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AT_from + (10*1000), 10*1000, pendingIntent);

我不确定是什么导致了间隔问题。我觉得很好。

【讨论】:

感谢您的想法。你能验证我用于对话框的逻辑吗? @AkashDev 你不需要任何额外的对话框声明。 感谢您的宝贵时间和建议 :)

以上是关于了解我的 AlarmManager 逻辑的主要内容,如果未能解决你的问题,请参考以下文章

alarmManager 设置警报以在准确时间而不是分数工作

android alarmmanager如果设置过去的时间就会触发广播?

在alarmmanager中点击通知后打开活动并广播Kotlin

alarm系统调用过程

24 AlarmManagerService机制

Android中Alarm的机制