0

I am having some problem with Alarm Manager in Android. I am setting the alarm manager to execute every midnight at 12am. Here are my codes:

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0 ); 
notificationCount = notificationCount + 1;
AlarmManager mgr = (AlarmManager) context
                    .getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context,
                    ReminderAlarm.class);
notificationIntent.putExtra("RecurID", recurID);    
notificationIntent.putExtra("RecurStartDate", _recurlist.get(position)
                    .getRecurringStartDate());  
notificationIntent.putExtra("Date", dateFormat.format(new Date()));
notificationIntent.putExtra("Type", _recurlist.get(position).getRecurringType());
notificationIntent.putExtra("Amount", formatAmount);
notificationIntent.putExtra("NextPaymentDate", viewHolder.txt_ddate.getText());
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);
ComponentName receiver = new ComponentName(context, BootReceiver.class);
            PackageManager pm = context.getPackageManager();

            pm.setComponentEnabledSetting(receiver,
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);          
return convertView;

And when onReceive, the program will execute the insert and update SQL statement if it matches the conditions:

ReminderAlarm class

public void onReceive(Context context, Intent intent) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    String recurID = intent.getStringExtra("RecurID");
    String recurStartDate = intent.getStringExtra("RecurStartDate");
    String date = intent.getStringExtra("Date");
    String type = intent.getStringExtra("Type");
    String amount = intent.getStringExtra("Amount");
    String nextPaymentDate = intent.getStringExtra("NextPaymentDate");
    String currentDate = "Next Payment On: "
            + dateFormat.format(new Date());

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

        trm.setDate(date);
        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
        RecurringController rc1 = new RecurringController(mDbHelper.open());
        boolean recurExist = rc1.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(date);

                    RecurringController rc = new RecurringController(
                            mDbHelper.open());
                    if (rc.updateRecurringDate(rm)) {
                        mDbHelper.close();
                    }
                }
            }
        }
    }

In my manifest file:

<receiver android:name="ReminderAlarm"></receiver>
<receiver
        android:name="BootReceiver"
        android:enabled="false" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" >
            </action>
        </intent-filter>
    </receiver>

Boot Receiver class:

public void onReceive(Context context, Intent i) {
    scheduleAlarms(context);
}

static void scheduleAlarms(Context context) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 1);
    AlarmManager mgr = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
    Intent notificationIntent = new Intent(context, ReminderAlarm.class);
    PendingIntent pi = PendingIntent.getService(context, 0,
            notificationIntent, 0);

    mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}

However, the alarm manager does not execute when it get passed 12am everyday. The insert and update SQL statement will only be execute when I run the applications.

Any ideas? Thanks in advance.

  • did your `txt_ddate` contains the date with string `"Next Payment On: "` ..? – Ranjit Sep 24 '14 at 05:58
  • Yeah. The SQL statements has no problem just that if I never run the application it wont be execute. Let's say I set a recurring yesterday and the frequency is daily. When the next day 12am, it should execute the SQL but it doesnt. It will only execute it when I run the apps next day –  Sep 24 '14 at 06:00
  • @RanjitPati in short sentence, if I do not run the apps, the SQL will not be execute so I was thinking is the problem with the alarm manager? –  Sep 24 '14 at 06:01
  • I think its helpful if you bind one service with your alarm activity, so it can run in the background. – Ranjit Sep 24 '14 at 06:03
  • I did put a receiver tag in the manifest file as the edited portion. Is that the service you mentioned above? –  Sep 24 '14 at 06:04
  • did you try printing logs to see if it is going in onReceive but failing the check? Print log as first statement of onReceive, Also checking by putting manual time to see if you are not adding wrong time. – AAnkit Sep 24 '14 at 06:06
  • you may check it once again ..https://developer.android.com/training/scheduling/alarms.html – Ranjit Sep 24 '14 at 06:09
  • For my situation now let's say I set a recurrring record for yesterday it runs the SQL immediately but I thought I only setRepeating at around 12am everyday. –  Sep 24 '14 at 06:09
  • @IWasSoLost So I suggest you to check that link..It has the total information which will solve your problem.. Not only when app closed, but also when reboot.. – Ranjit Sep 24 '14 at 06:25
  • @RanjitPati I changed my codes as above and I am getting error message as Unable to start receiver, Java Null Pointer Exception error message. Any ideas? –  Sep 24 '14 at 06:42

2 Answers2

0

Problem is in setting time for alarm to execute. replace the top three lines with this code

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
Sats
  • 875
  • 6
  • 12
  • What does it do? setting the alarm manager to execute at 12:01 am? –  Sep 24 '14 at 06:43
  • Yes , you use calendar.setTimeInMillis(System.currentTimeMillis()); , and not set minute , so this might create problem in fire alarm. try that code , hope it works. – Sats Sep 24 '14 at 06:46
  • Okay sure but I have another problem which is in the question. I am getting NullPointerException at the if statement: if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) in ReminderAlarm class. Any ideas? –  Sep 24 '14 at 06:47
  • because intent.getStringExtra in ReminderAlarm class return null after reboot . – Sats Sep 24 '14 at 06:55
  • So how should I fix this? –  Sep 24 '14 at 07:00
  • Create a new broadcast receiver that is use to set alarm , and execte on reboot – Sats Sep 24 '14 at 07:03
  • But would you mind to post me a solution according to my situation? Because when I setAlarm I have to pass along the values as well so I not sure how should I call it from the new broadcast receiver –  Sep 24 '14 at 07:07
  • @IWasSoLost this link will heps you http://stackoverflow.com/questions/12512717/android-alarmmanager-after-reboot – Sats Sep 24 '14 at 07:11
  • So basically I just modify the codes as in the question and it would be fine? Could you please help me take a look when you free? –  Sep 24 '14 at 07:19
  • Can you please help me take a look at this? http://stackoverflow.com/questions/27102164/alarm-manager-not-running-in-background –  Nov 24 '14 at 11:05
0

Change your calendar value to Calendar calendar = Calendar.getInstance(); calendar .set(Calendar.HOUR_OF_DAY, 0); calendar .set(Calendar.MINUTE, 0); calendar .set(Calendar.SECOND, 0); and set alarm.

NIPHIN
  • 1,071
  • 1
  • 8
  • 16
  • Why need to set minutes and seconds? –  Sep 24 '14 at 06:43
  • because 12 am means 0 hours, 0 minutes and 0 seconds, thats why – NIPHIN Sep 24 '14 at 06:45
  • Okay sure thanks a lot! but could you please help me take a look at the question again because I am encountering another problem –  Sep 24 '14 at 06:50
  • I think you want to update your db every day at midnight to account for next days transaction and you are using alarm manager to schedule Alarm manager itself is a service no need to bind any other service. update your manifest as /> and schedule your alarm as mentioned above. it will definitely work,put a Log onReeceive to indicae alarm has received. – NIPHIN Sep 24 '14 at 07:20
  • also add – NIPHIN Sep 24 '14 at 07:22
  • But there's some problem when I reboot or kill apps right? I have updated my codes. So far if I test with yesterday's date, it's working fine as it will add into transaction immediately. Do you think it's okay? –  Sep 24 '14 at 07:23
  • I created another receiver because if I don't, it will hit NullPointerException at the if statement in BootReceiver class if I put that part of codes into my ReminderAlarm class –  Sep 24 '14 at 07:25
  • Unfortunately, it still not running in background. Any ideas? –  Sep 25 '14 at 10:58