Reputation:
I need your help. I'm stuck with this problem. Alarms work properly. However, when device is rebooted, and the specified time stored in db is in the past (3pm) and current time is 4pm, how can I check to prevent triggering the alarm immediately?
Docs say:
If the stated trigger time is in the past, the alarm will be triggered immediately. Here's what I've tried so far:
class DeviceBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Check if successful reboot
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
SharedPreferences shared = context.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
// Check if daily notification is enabled
// If yes, call NotificationPublisher to communicate with NotificationAlarmService
if(shared.getBoolean(Constants.KEY_IS_DAILY_NOTIFIED, false)) {
DBHelper dbHelper = new DBHelper(context);
DBConnector.dbConnect(dbHelper);
int DAILY_NOTIFICATION_ID = Constants.DAILY_VERSE_NOTIFICATION_1_ID;
ArrayList<Notification> notificationList = dbHelper.getNotifications();
Log.e("", "notificationList: " + notificationList.size());
for(Notification obj : notificationList) {
Calendar datetime = Calendar.getInstance();
datetime.set(Calendar.HOUR_OF_DAY, obj.getHourOfDay());
datetime.set(Calendar.MINUTE, obj.getMinute());
datetime.set(Calendar.SECOND, 0);
Calendar now = Calendar.getInstance();
if (now.after(datetime)) {
datetime.add(Calendar.DATE, now.get(Calendar.DATE) + 1);
}
Log.e("BOOT RECEIVER", "" + obj.getHourOfDay() + ":" + obj.getMinute());
Intent myIntent = new Intent(context, NotificationPublisher.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
DAILY_NOTIFICATION_ID++,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
datetime.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
pendingIntent);
}
}
}
}
AndroidManifest:
<receiver
android:name=".utils.DeviceBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
What seems to be wrong with my code? I'd appreciate any help. Thanks!
Upvotes: 4
Views: 572
Reputation: 2737
A sample code to set repetition of Alarm at interval day.
I have set the Alarm in MainActivity if your want to set Alarm once you can do it by extending Application class and write code to set Alarm inside onCreate.
public class MainActivity extends AppCompatActivity {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
}
SampleBootReciver - set Alarm after the device is rebooted
public class SampleBootReceiver extends BroadcastReceiver {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent1, 0);
Calendar now = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
if (calendar.before(now))
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
}
}
AlarmReceiver - perform action after Alarm is fired.
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}
}
I'm just displaying a toast.
Lastly the manifest file -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bits.kevz.samplealarm">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".SampleBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I want you to run above code and check onBootCompleted output.
Upvotes: 0
Reputation: 46
I set & check alarm time like this and it works for me now:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if (calendar.before(now))
calendar.add(Calendar.DAY_OF_MONTH, 1);
Upvotes: 1