Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android Alarm Manager设置在特定时间重复_Java_Android_Date_Alarmmanager_Recurring - Fatal编程技术网

Java Android Alarm Manager设置在特定时间重复

Java Android Alarm Manager设置在特定时间重复,java,android,date,alarmmanager,recurring,Java,Android,Date,Alarmmanager,Recurring,我对Android中的alarm manager有一些问题。所以我要做的是将警报设置为重复,以便在每天12:01左右运行DB插入 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 0 ); calendar.set(Calendar.MINUTE, 1);

我对Android中的alarm manager有一些问题。所以我要做的是将警报设置为重复,以便在每天12:01左右运行DB插入

Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0 );
    calendar.set(Calendar.MINUTE, 1);
        notificationCount = notificationCount + 1;
        AlarmManager mgr = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        Intent notificationIntent = new Intent(context,
                ReminderAlarm.class);

        notificationIntent.putExtra("NotifyCount", notificationCount);
        PendingIntent pi = PendingIntent.getBroadcast(context,
                notificationCount, notificationIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
所以基本上我已经想出了这些代码。但是,报警管理器在我设置它的那一分钟后再次执行

假设我在2014年10月1日下午5:48运行这些应用程序。我希望在我将其设置为仅在凌晨12点01分左右后,在onReceive每天运行DB插入。但不知怎的,报警管理器在2014年10月1日下午5时49分执行,这是我设置它后的一分钟,它停止工作

我不知道我做错了哪一部分

提前谢谢

编辑

定期课程 对于该类,它将每天触发报警管理器,并将变量传递给提醒报警类以插入DB

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.recurring);
    context = this;
    buildListView();
    if(!alarmInitialized(this)) { 
        scheduleAlarms(this); 
    }
}

// And the few methods you suggested to schedule the alarm
public static void scheduleAlarms(Context context) {
    Calendar calendar = Calendar.getInstance();
    if (hasRunnedToday(context)) { // if the alarm has run this day
        calendar.add(Calendar.DATE, 1); // schedule it to run again starting
                                        // tomorrow
    }

    long firstRunTime = calendar.getTimeInMillis();
    AlarmManager mgr = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
    Intent notificationIntent = new Intent(context, ReminderAlarm.class);
    PendingIntent pi = PendingIntent.getActivity(context, 0,
            notificationIntent, 0);
    mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstRunTime,
            AlarmManager.INTERVAL_DAY, pi);

    ComponentName receiver = new ComponentName(context, BootReceiver.class);
    PackageManager pm = context.getPackageManager();

    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
}
引导接收器类

public void onReceive(Context context, Intent i) {
    if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        Recurring.scheduleAlarms(context);
    }
}
ARM类的提醒 基本上,对于这个类,它只是获取从循环类传递的变量并执行DB插入。我确实插入了一些Toast.makeText来测试它是否正在检索,但测试失败

public class ReminderAlarm extends BroadcastReceiver {
private NotificationManager mNotificationManager;
private Notification notification;

@Override
public void onReceive(Context context, Intent intent) {
    String recurID = null;
    String recurStartDate = null;
    String currentDate = null;
    String description = null;
    String type = null;
    String amount = null;
    String categoryName = null;
    String frequencyStr = null;
    String nextPaymentDate = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

    DatabaseAdapter mDbHelper = new DatabaseAdapter(context);
    mDbHelper.createDatabase();
    mDbHelper.open();
    RecurringController rc = new RecurringController(mDbHelper.open());
    ArrayList<RecurringModel> recur_list = rc.getAllRecurring();

    // THIS PART TO GET DATA FROM DATABASE
    for (int i = 0; i < recur_list.size(); i++) {
        recurID = recur_list.get(i).getRecurringID();
        recurStartDate = recur_list.get(i).getRecurringStartDate();
        currentDate = dateFormat.format(new Date());
        description = recur_list.get(i).getRecurringDesc();
        type = recur_list.get(i).getRecurringType();
        amount = Float.toString(recur_list.get(i).getRecurringAmount());
        categoryName = recur_list.get(i).getCategoryID();
        frequencyStr = recur_list.get(i).getFrequency();

        Toast.makeText(context,
                    description, Toast.LENGTH_LONG)
                    .show();
        Toast.makeText(context,
                    recurStartDate Toast.LENGTH_LONG)
                    .show();

        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(dateFormat.parse(recurStartDate));
            if (frequencyStr.equals("Daily")) {
                cal.add(Calendar.DAY_OF_MONTH, 1);
                nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                cal.add(Calendar.DAY_OF_MONTH, -1);
            } else if (frequencyStr.equals("Weekly")) {
                cal.add(Calendar.WEEK_OF_YEAR, 1);
                nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                cal.add(Calendar.WEEK_OF_YEAR, -1);
            } else if (frequencyStr.equals("Monthly")) {
                cal.add(Calendar.MONTH, 1);
                nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                cal.add(Calendar.MONTH, -1);
            } else if (frequencyStr.equals("Yearly")) {
                cal.add(Calendar.YEAR, 1);
                nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
                cal.add(Calendar.YEAR, -1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // If dates match then execute the SQL statements
        if (currentDate.equals(nextPaymentDate)) {
            // mDbHelper.createDatabase();
            // mDbHelper.open();
            TransactionRecModel trm = new TransactionRecModel();
            CategoryController cc = new CategoryController(mDbHelper.open());

            trm.setDate(currentDate);
            trm.setTransDescription(description);
            trm.setType(type);
            trm.setAmount(Float.parseFloat(amount));

            // Get the categoryID based on categoryName
            String catID = cc.getCatIDByName(categoryName);
            trm.setCategory(catID);

            // Check if the recurring record exists before insert new
            // transaction record
            boolean recurExist = rc.checkRecurExist(recurStartDate,
                    description, catID);
            if (recurExist == true) {
                TransactionRecController trc = new TransactionRecController(
                        mDbHelper.open());
                // Check if the transaction record exists to prevent
                // duplication
                boolean moveNext = trc.checkTransExist(trm);
                if (moveNext == false) {

                    if (trc.addTransactionRec(trm)) {
                        // Update recurring start date after insertion of
                        // transaction
                        RecurringModel rm = new RecurringModel();
                        rm.setRecurringID(recurID);
                        rm.setRecurringStartDate(currentDate);

                        if (rc.updateRecurringDate(rm)) {
                            mNotificationManager = (NotificationManager) context
                                    .getSystemService(Context.NOTIFICATION_SERVICE);
                            PendingIntent contentIntent = PendingIntent
                                    .getActivity(
                                            context,
                                            Integer.parseInt(intent
                                                    .getExtras()
                                                    .get("NotifyCount")
                                                    .toString()),
                                            new Intent(), 0);
                            notification = new Notification(
                                    R.drawable.ic_launcher, "Notification",
                                    System.currentTimeMillis());
                            notification.setLatestEventInfo(context,
                                    description, nextPaymentDate,
                                    contentIntent);
                            mNotificationManager
                                    .notify(Integer.parseInt(intent
                                            .getExtras().get("NotifyCount")
                                            .toString()), notification);
                            mDbHelper.close();
                        }
                    }
                }
            }
            mDbHelper.close();
        }
    }
    mDbHelper.close();
    Recurring.updateAlarmLastRun(context);
}
}

问题出在calendar.getTimeInMillis()中

mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
setInexactRepeating
引用文档的第二个参数

TriggeratMills使用适当的时钟(取决于报警类型),以毫秒为单位,表示报警首次响起的时间。这是不准确的:在此时间之前警报不会触发,但在第一次调用警报之前,可能会有几乎整个警报间隔的延迟

这意味着它将在您设置它大约一分钟后第一次运行,因为

calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0 );
calendar.set(Calendar.MINUTE, 1);
如果你不想在第二天第一次报警,那就做一个 日历.添加(日历.日期,1)`

至于it停止工作,您是否重新启动了de设备? AlarmCalendar报警不会持续到设备重新启动,您可以注册一个
BroadcastReceiver
来接收
BOOT\u COMPLETED
事件并再次注册报警检查

更新:根据您的要求,在查看代码后,这里提供了一些帮助

在您的
引导\u已完成
接收器类:

public void onReceive(Context context, Intent i) {
    if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        ReminderAlarm.scheduleAlarms(this);
    }
}
在你的课堂上

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recurring);

if(!alarmInitialized(this) { 
    scheduleAlarms(this); 
}
}

注:

  • 如果上下文是类字段,则不应执行
    context=this
    ,因为对象持有对其字段的引用
    context
    ,而
    context
    字段持有对可能泄漏的对象的引用
  • 您的
    接收器
    'onReceive`没有您假设的额外功能,如设备完成引导时系统接收到的“notificationCount”
  • 警报运行后,请调用
    updateAlarmLastRun

  • 希望这些都有帮助

    问题出在
    日历中。getTimeInMillis()

    mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
    
    setInexactRepeating
    引用文档的第二个参数

    TriggeratMills使用适当的时钟(取决于报警类型),以毫秒为单位,表示报警首次响起的时间。这是不准确的:在此时间之前警报不会触发,但在第一次调用警报之前,可能会有几乎整个警报间隔的延迟

    这意味着它将在您设置它大约一分钟后第一次运行,因为

    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0 );
    calendar.set(Calendar.MINUTE, 1);
    
    如果你不想在第二天第一次报警,那就做一个 日历.添加(日历.日期,1)`

    至于it停止工作,您是否重新启动了de设备? AlarmCalendar报警不会持续到设备重新启动,您可以注册一个
    BroadcastReceiver
    来接收
    BOOT\u COMPLETED
    事件并再次注册报警检查

    更新:根据您的要求,在查看代码后,这里提供了一些帮助

    在您的
    引导\u已完成
    接收器类:

    public void onReceive(Context context, Intent i) {
        if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            ReminderAlarm.scheduleAlarms(this);
        }
    }
    
    在你的课堂上

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.recurring);
    
    if(!alarmInitialized(this) { 
        scheduleAlarms(this); 
    }
    
    }

    注:

  • 如果上下文是类字段,则不应执行
    context=this
    ,因为对象持有对其字段的引用
    context
    ,而
    context
    字段持有对可能泄漏的对象的引用
  • 您的
    接收器
    'onReceive`没有您假设的额外功能,如设备完成引导时系统接收到的“notificationCount”
  • 警报运行后,请调用
    updateAlarmLastRun

  • 希望这些都能有所帮助。“…报警管理器在2014年10月1日下午5时49分执行,这是我设置它并停止工作后的一分钟。”您可以通过将
    日历.HOUR of_DAY
    设置为0来设置时间。这会立即触发报警,直到第二天00:01才会再次触发。@Squonk您对如何解决此问题有什么想法吗?因为根据我的研究,我认为这样做能够在特定时间触发警报。@Squonk那么我应该把这些代码放在哪里呢?您是否介意将整个部分作为答案发布?@Squonk我是否应该在您之前提供的if语句中包装setInExactRepeating?我其实不太清楚:)把我建议的代码放在
    calendar.set(calendar.MINUTE,1)之后。看看它是否解决了您的问题,如果解决了,我将发布完整的答案。“…报警管理器在2014年10月1日下午5时49分执行,这是我设置它后的一分钟,它停止工作。”您通过将
    日历.HOUR OF_DAY
    设置为0来设置时间倒退。这会立即触发报警,直到第二天00:01才会再次触发。@Squonk您对如何解决此问题有什么想法吗?因为根据我的研究,我认为这样做能够在特定时间触发警报。@Squonk那么我应该把这些代码放在哪里呢?您是否介意将整个部分作为答案发布?@Squonk我是否应该在您之前提供的if语句中包装setInExactRepeating?我其实不太清楚:)把我建议的代码放在
    calendar.set(calendar.MINUTE,1)之后。看看它是否能解决您的问题,以及