1

I'm working on an app in which I need the user to schedule an event. I am using TimePicker and DatePicker Dialogs to set the time of the event and an AlarmManager with a BroadcastReceiver to execute the action when the time is reached. On testing I have come to a conclusion that my time and date picker dialogs are working fine and I am able to pick a date and time. However the BroadcastReceiver isn't being triggered by the AlarmManager when the time is reached.

Here is my MainActivity.class that schedules the event:

public class MainActivity extends Activity {

Button setTime;
Button scheduleEvent;
static final int DATEPICKER_DIALOG_ID = 0;
static final int TIMEPICKER_DIALOG_ID = 1;
int dpYear, dpMonth, dpDay, tpHour, tpMinute;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Calendar calendar = Calendar.getInstance();
    dpYear = calendar.get(Calendar.YEAR);
    dpMonth = calendar.get(Calendar.MONTH);
    dpDay = calendar.get(Calendar.DAY_OF_MONTH);
    tpHour = calendar.get(Calendar.HOUR_OF_DAY);
    tpMinute = calendar.get(Calendar.MINUTE);

    setTime = (Button) findViewById(R.id.button1);
    scheduleEvent = (Button) findViewById(R.id.button2);

    setTime.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            showDialog(DATEPICKER_DIALOG_ID);
        }
    });

    scheduleEvent.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = new Intent("com.ohs.example.myEvent");
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager alarmMgr = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));

            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.YEAR, dpYear);
            cal.set(Calendar.MONTH, dpMonth);
            cal.set(Calendar.DAY_OF_MONTH, dpDay);
            cal.set(Calendar.HOUR_OF_DAY, tpHour);
            cal.set(Calendar.MINUTE, tpMinute);
            cal.set(Calendar.SECOND, 0);
            long mills = cal.getTimeInMillis();

            alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent);
            Toast.makeText(this, "Event scheduled at " + tpHour + ":" + tpMinute + " " + dpDay + "/" + dpMonth + "/" + dpYear, Toast.LENGTH_LONG).show();

        }
    });

}

@Override
protected Dialog onCreateDialog(int id) {
    if (id == DATEPICKER_DIALOG_ID) {
        return new DatePickerDialog(this, datePickerListener, dpYear, dpMonth, dpDay);
    } else if (id == TIMEPICKER_DIALOG_ID) {
        return new TimePickerDialog(this, timePickerListener, tpHour, tpMinute, false);
    } else {
        return null;
    }
}

private DatePickerDialog.OnDateSetListener datePickerListener =
        new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
                dpYear = i;
                dpMonth = i1 + 1;
                dpDay = i2;
                showDialog(TIMEPICKER_DIALOG_ID);
            }
        };

protected TimePickerDialog.OnTimeSetListener timePickerListener =
        new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int i, int i1) {
                tpHour = i;
                tpMinute = i1;
            }
        };
}

AlarmReceiver.class:

public class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Toast.makeText(context, "Broadcast Received", Toast.LENGTH_LONG).show();
    eventMethod();

}

protected void eventMethod() {

//Do something...

}
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ohs.example" >

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <receiver android:name=".AlarmReceiver" android:enabled="true">
        <intent-filter>
            <action android:name="com.ohs.example.myEvent" />
        </intent-filter>
    </receiver>
</application>

</manifest>

I have previously worked on other apps where I had to set a repeating alarm for every 6 hours. I used the exact same code as above (with an AlarmManager and BraodcastReceiver), only instead of:

    cal.set(Calendar.YEAR, dpYear);
    cal.set(Calendar.MONTH, dpMonth);
    cal.set(Calendar.DAY_OF_MONTH, dpDay);
    cal.set(Calendar.HOUR_OF_DAY, tpHour);
    cal.set(Calendar.MINUTE, tpMinute);
    cal.set(Calendar.SECOND, 0);

All I had was:

    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.HOUR_OF_DAY, 18);

And it works perfectly. So are the "YEAR", "MONTH", and "DAY_OF_MONTH" the ones that are causing problems here. If so, what's the solution?

I have looked a lot for solutions to my problem and I've found similar questions on stackoverflow, but none have helped me. Any help would be much appreciated.

OHS
  • 185
  • 1
  • 2
  • 12
  • this answer might be helpful http://stackoverflow.com/questions/4459058/alarm-manager-example – raktale Aug 28 '15 at 13:08
  • I can give it a try... But I'd rather not use a Service class, it's not really recommended. I know there is a way to achieve what I want using just an AlarmManager and BroadcastReceiver because I've done it before but only using "Calendar.SECOND", "Calendar.MINUTE", and "Calendar.HOUR"... Now that I've added "YEAR", "MONTH", and "DAY_OF_MONTH", it's not working. Any ideas why that is? – OHS Sep 05 '15 at 15:50

2 Answers2

2

After lots and lots of trying... I realized that the problem is that Calendar.DAY_OF_MONTH takes months starting from 0 to 11 (0 being Jan and 11 being December)... And I unfortunately did not know that, so I added 1 to the value of month obtained from the datePicker. So I just removed the + 1 and now it's working perfectly.

OHS
  • 185
  • 1
  • 2
  • 12
0

i have this problem once. is the phenomenon happen in all your test phone? my problem appear because one of my test phone have modified the phone Hardware to solve the Power saving. so the alarmReceiver in evey five minute

leo
  • 204
  • 3
  • 15
  • Yes I have tried it in two different devices and it didn't work in either of them. I didn't quite understand what you mean by power saving, but I have tested the app with power saving mode both on and off without any luck. – OHS Aug 28 '15 at 08:29
  • alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent); the mills you set the currenttime. when the time past ,it can't fire broadcast. you can set the time after the currenttime – leo Aug 28 '15 at 08:42
  • But the mills is set to the Calendar's time, not currentTime. – OHS Aug 28 '15 at 09:07
  • but the Calendar's time you set is curentTime.You can try write code like this Calendar cal = Calendar.getInstance(); long mills = cal.getTimeInMillis() + 10000; alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent); see broadcast can receive in 10s? – leo Aug 28 '15 at 09:31
  • I've tried that and the broadcast didn't receive it after 10 seconds – OHS Sep 05 '15 at 15:41