repeatDays) {
- //Log.e(this.getClass().getSimpleName(), "addOrActivateAlarm() method called.");
+
+ ConstantsAndStatics.cancelScheduledPeriodicWork(this);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
@@ -331,14 +315,12 @@ private void addOrActivateAlarm(int mode, AlarmEntity alarmEntity,
alarmID = result[0];
- //alarmAdapter.add(alarmDateTime, alarmEntity.isRepeatOn, repeatDays, alarmEntity.alarmType);
alarmAdapter = new AlarmAdapter(viewModel.getAlarmDataArrayList(), this, this);
alarmsRecyclerView.swapAdapter(alarmAdapter, false);
alarmsRecyclerView.scrollToPosition(result[1]);
} else {
viewModel.toggleAlarmState(alarmDatabase, alarmEntity.alarmHour, alarmEntity.alarmMinutes, 1);
- //alarmAdapter.toggleAlarmState(alarmEntity.alarmHour, alarmEntity.alarmMinutes, 1);
alarmAdapter = new AlarmAdapter(viewModel.getAlarmDataArrayList(), this, this);
alarmsRecyclerView.swapAdapter(alarmAdapter, false);
alarmID = alarmEntity.alarmID;
@@ -359,34 +341,10 @@ private void addOrActivateAlarm(int mode, AlarmEntity alarmEntity,
ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime.withSecond(0), ZoneId.systemDefault());
- /*Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, alarmDateTime.getYear());
- calendar.set(Calendar.MONTH, alarmDateTime.getMonthValue() - 1);
- calendar.set(Calendar.DAY_OF_MONTH, alarmDateTime.getDayOfMonth());
- calendar.set(Calendar.HOUR_OF_DAY, alarmDateTime.getHour());
- calendar.set(Calendar.MINUTE, alarmDateTime.getMinute());
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);*/
-
alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
pendingIntent), pendingIntent);
- /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
- pendingIntent);
- } else {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
- }*/
-
- Log.e(this.getClass().getSimpleName(), "alarmID = " + alarmID);
-
- /*PendingIntent pi = PendingIntent.getBroadcast(Activity_AlarmsList.this, alarmID, intent,
- PendingIntent.FLAG_NO_CREATE);
- if (pi == null) {
- Log.e(this.getClass().getSimpleName(), "addOrActivateAlarm() pending intent not found.");
- } else {
- Log.e(this.getClass().getSimpleName(), "addOrActivateAlarm() pending intent found.");
- }*/
+ ConstantsAndStatics.schedulePeriodicWork(this);
}
//------------------------------------------------------------------------------------------------------
@@ -399,7 +357,8 @@ private void addOrActivateAlarm(int mode, AlarmEntity alarmEntity,
* @param mins The alarm minutes.
*/
private void deleteOrDeactivateAlarm(int mode, int hour, int mins) {
- //Log.e(this.getClass().getSimpleName(), "deleteOrDeactivateAlarm() called");
+
+ ConstantsAndStatics.cancelScheduledPeriodicWork(this);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
@@ -409,41 +368,25 @@ private void deleteOrDeactivateAlarm(int mode, int hour, int mins) {
int alarmID = viewModel.getAlarmId(alarmDatabase, hour, mins);
- //Log.e(this.getClass().getSimpleName(), "id = " + alarmID);
-
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(Activity_AlarmsList.this, alarmID, intent,
- PendingIntent.FLAG_NO_CREATE);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(Activity_AlarmsList.this, alarmID, intent,
+ PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
- //Log.e(this.getClass().getSimpleName(), "Alarm cancelled.");
- } /*else {
- Log.e(this.getClass().getSimpleName(), "Alarm not found.");
- }*/
+ }
+
if (mode == MODE_DELETE_ALARM) {
viewModel.removeAlarm(alarmDatabase, hour, mins);
alarmAdapter = new AlarmAdapter(viewModel.getAlarmDataArrayList(), this, this);
alarmsRecyclerView.swapAdapter(alarmAdapter, false);
- //alarmAdapter.remove(hour, mins);
} else {
viewModel.toggleAlarmState(alarmDatabase, hour, mins, 0);
- //alarmAdapter.toggleAlarmState(hour, mins, 0);
- //No need to swap adapter again.
}
-
- //////////////////////////////////////////////////////////
- // Kill any foreground service based on this alarm
- /////////////////////////////////////////////////////////
- /*if (Service_RingAlarm.isThisServiceRunning) {
- if (Service_RingAlarm.alarmHour == hour && Service_RingAlarm.alarmMinute == mins) {
- Intent intent1 = new Intent(this, Service_RingAlarm.class);
- stopService(intent1);
- }
- }*/
+ // Kill any foreground service based on this alarm:
ConstantsAndStatics.killServices(this, alarmID);
+ ConstantsAndStatics.schedulePeriodicWork(this);
}
//--------------------------------------------------------------------------------------------------
@@ -471,17 +414,17 @@ private void toggleAlarmState(int hour, int mins, final int newAlarmState) {
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
+
if (requestCode == NEW_ALARM_REQUEST_CODE) {
- /*if (resultCode == RESULT_CANCELED) {
- Log.e(this.getClass().getSimpleName(), "No new alarm.");
- }*/
if (resultCode == RESULT_OK) {
+
if (intent != null) {
- //Log.e(this.getClass().getSimpleName(), "Received new alarm.");
+
Bundle data = Objects.requireNonNull(intent.getExtras())
.getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS);
assert data != null;
+
AlarmEntity alarmEntity = new AlarmEntity(data.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_HOUR),
data.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_MINUTE),
true,
@@ -502,13 +445,9 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent i
}
}
} else if (requestCode == EXISTING_ALARM_REQUEST_CODE) {
- /*if (resultCode == RESULT_CANCELED) {
- Log.e(this.getClass().getSimpleName(), "No changes made in existing alarm.");
- }*/
if (resultCode == RESULT_OK) {
if (intent != null) {
- //Log.e(this.getClass().getSimpleName(), "Changes were made in existing alarm.");
Bundle data = Objects.requireNonNull(intent.getExtras())
.getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS);
assert data != null;
@@ -545,7 +484,6 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent i
@Override
public void onOnOffButtonClick(int rowNumber, int hour, int mins, int currentAlarmState) {
- //Log.e(this.getClass().getSimpleName(), "OnOff Btn clicked.");
toggleAlarmState(hour, mins, currentAlarmState);
}
@@ -553,7 +491,6 @@ public void onOnOffButtonClick(int rowNumber, int hour, int mins, int currentAla
@Override
public void onDeleteButtonClicked(int rowNumber, int hour, int mins) {
- //Log.e(this.getClass().getSimpleName(), "Delete button clicked.");
deleteOrDeactivateAlarm(MODE_DELETE_ALARM, hour, mins);
}
@@ -561,7 +498,6 @@ public void onDeleteButtonClicked(int rowNumber, int hour, int mins) {
@Override
public void onItemClicked(int rowNumber, int hour, int mins) {
- //Log.e(this.getClass().getSimpleName(), "Row clicked. Row number: " + rowNumber);
Intent intent = new Intent(this, Activity_AlarmDetails.class);
intent.setAction(ConstantsAndStatics.ACTION_EXISTING_ALARM);
@@ -636,7 +572,6 @@ private boolean isInstalledOnInternalStorage() {
//--------------------------------------------------------------------------------------------------
private void checkForPlugin() {
- //Log.e(this.getClass().getSimpleName(), "Checking for plugin");
if (! isInstalledOnInternalStorage()) {
try {
getPackageManager().getApplicationInfo("in.basulabs.shakealarmclockplugin", 0);
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Activity_Settings.java b/app/src/main/java/in/basulabs/shakealarmclock/Activity_Settings.java
index b300d41..e05a4d9 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/Activity_Settings.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Activity_Settings.java
@@ -79,7 +79,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
defaultTheme = ConstantsAndStatics.THEME_SYSTEM;
} else {
- defaultTheme = ConstantsAndStatics.THEME_TIME;
+ defaultTheme = ConstantsAndStatics.THEME_AUTO_TIME;
}
applyTheme();
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/AlarmBroadcastReceiver.java b/app/src/main/java/in/basulabs/shakealarmclock/AlarmBroadcastReceiver.java
index e45a730..aae8a62 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/AlarmBroadcastReceiver.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/AlarmBroadcastReceiver.java
@@ -3,7 +3,6 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.os.PowerManager;
import androidx.core.content.ContextCompat;
@@ -26,32 +25,10 @@ public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, Service_RingAlarm.class);
intent1.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS,
- Objects.requireNonNull(intent.getExtras())
- .getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS));
+ Objects.requireNonNull(intent.getExtras()).getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS));
ContextCompat.startForegroundService(context, intent1);
- /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.startForegroundService(intent1);
- } else {
- context.startService(intent1);
- }*/
-
- } else if (Objects.equals(intent.getAction(), ConstantsAndStatics.ACTION_CREATE_BACKGROUND_SERVICE)) {
-
- SharedPreferences sharedPreferences =
- context.getSharedPreferences(ConstantsAndStatics.SHARED_PREF_FILE_NAME, Context.MODE_PRIVATE);
-
- if (sharedPreferences.getBoolean(ConstantsAndStatics.SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE, true)) {
- Intent intent1 = new Intent(context, Service_AlarmActivater.class);
- context.startService(intent1);
-
- SharedPreferences.Editor editor = sharedPreferences.edit()
- .remove(ConstantsAndStatics.SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE)
- .putBoolean(ConstantsAndStatics.SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE, false);
- editor.commit();
- }
-
- } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)
+ } else if (Objects.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)
|| intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)
|| intent.getAction().equals(Intent.ACTION_TIME_CHANGED)) {
@@ -62,11 +39,6 @@ public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, Service_UpdateAlarm.class);
ContextCompat.startForegroundService(context, intent1);
- /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.startForegroundService(intent1);
- } else {
- context.startService(intent1);
- }*/
}
}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/ConstantsAndStatics.java b/app/src/main/java/in/basulabs/shakealarmclock/ConstantsAndStatics.java
index 5025e65..4ee7326 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/ConstantsAndStatics.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/ConstantsAndStatics.java
@@ -2,10 +2,16 @@
import android.content.Context;
import android.content.Intent;
+import android.util.Log;
import androidx.appcompat.app.AppCompatDelegate;
+import androidx.work.Configuration;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkManager;
import java.time.LocalTime;
+import java.util.concurrent.TimeUnit;
/**
* A class containing all the constants required by this app.
@@ -65,8 +71,7 @@ final class ConstantsAndStatics {
static final String BUNDLE_KEY_IS_ALARM_ON = "in.basulabs.shakealarmclock.IsAlarmOn";
/**
- * Bundle key for the alarm repeat days. The value is an ArrayList of Integer type. Monday is 1 and Sunday
- * is 7.
+ * Bundle key for the alarm repeat days. The value is an ArrayList of Integer type. Monday is 1 and Sunday is 7.
*/
static final String BUNDLE_KEY_REPEAT_DAYS = "in.basulabs.shakealarmclock.ArrayListOfRepeatDays";
@@ -110,17 +115,20 @@ final class ConstantsAndStatics {
*/
static final String BUNDLE_KEY_ALARM_TONE_URI = "in.basulabs.shakealarmclock.ALARM_TONE_URI";
+ /**
+ * Bundle key: Indicates whether the user has explicitly chosen a date for that alarm.
+ */
static final String BUNDLE_KEY_HAS_USER_CHOSEN_DATE = "in.basulabs.shakealarmclock.HAS_USER_CHOSEN_DATE";
/**
- * Intent action delivered to {@link android.content.BroadcastReceiver} in {@link Service_RingAlarm}
- * instructing it to snooze the alarm.
+ * Intent action delivered to {@link android.content.BroadcastReceiver} in {@link Service_RingAlarm} instructing it
+ * to snooze the alarm.
*/
static final String ACTION_SNOOZE_ALARM = "in.basulabs.shakealarmclock.Service_RingAlarm -- SNOOZE_ALARM";
/**
- * Intent action delivered to {@link android.content.BroadcastReceiver} in {@link Service_RingAlarm}
- * instructing it to cancel the alarm.
+ * Intent action delivered to {@link android.content.BroadcastReceiver} in {@link Service_RingAlarm} instructing it
+ * to cancel the alarm.
*/
static final String ACTION_CANCEL_ALARM = "in.basulabs.shakealarmclock.Service_RingAlarm -- CANCEL_ALARM";
@@ -139,14 +147,18 @@ final class ConstantsAndStatics {
*/
static final String ACTION_EXISTING_ALARM = "in.basulabs.shakealarmclock.ACTION_EXISTING_ALARM";
+ /**
+ * Indicates whether {@link Activity_RingtonePicker} should play the ringtone when the user clicks on a
+ * {@link android.widget.RadioButton}. Default: {@code true}.
+ */
static final String EXTRA_PLAY_RINGTONE = "in.basulabs.shakealarmclock.EXTRA_PLAY_RINGTONE";
/**
* Bundle key for the old alarm hour.
* This is passed from {@link Activity_AlarmDetails} to
- * {@link Activity_AlarmsList} if the user saves the edits made to an existing alarm. Using this and
- * {@link #BUNDLE_KEY_OLD_ALARM_MINUTE}, {@link Activity_AlarmsList} deletes the old alarm and
- * adds/activates the new alarm.
+ * {@link Activity_AlarmsList} if the user saves the edits made to an existing alarm. Using this and {@link
+ * #BUNDLE_KEY_OLD_ALARM_MINUTE}, {@link Activity_AlarmsList} deletes the old alarm and adds/activates the new
+ * alarm.
*
*
* @see #BUNDLE_KEY_OLD_ALARM_MINUTE
@@ -156,9 +168,8 @@ final class ConstantsAndStatics {
/**
* Bundle key for the old alarm minute.
* This is passed from {@link Activity_AlarmDetails} to
- * {@link Activity_AlarmsList} if the user saves the edits made to an existing alarm. Using this and
- * {@link #BUNDLE_KEY_OLD_ALARM_HOUR}, {@link Activity_AlarmsList} deletes the old alarm and
- * adds/activates the new alarm.
+ * {@link Activity_AlarmsList} if the user saves the edits made to an existing alarm. Using this and {@link
+ * #BUNDLE_KEY_OLD_ALARM_HOUR}, {@link Activity_AlarmsList} deletes the old alarm and adds/activates the new alarm.
*
*
* @see #BUNDLE_KEY_OLD_ALARM_HOUR
@@ -170,105 +181,154 @@ final class ConstantsAndStatics {
*/
static final String BUNDLE_KEY_ALARM_ID = "in.basulabs.shakealarmclock.OLD_ALARM_ID";
- /**
- * Intent action passed as broadcast to {@link AlarmBroadcastReceiver} from {@link Service_AlarmActivater}
- * so that the former can recreate the latter when the latter is killed.
- */
- static final String ACTION_CREATE_BACKGROUND_SERVICE = "in.basulabs.shakealarmclock" +
- ".CreateBackgroundService";
-
/**
* Broadcast action: {@link Activity_RingAlarm} should now be destroyed.
*/
- static final String ACTION_DESTROY_RING_ALARM_ACTIVITY = "in.basulabs.shakealarmclock" +
- ".DESTROY_RING_ALARM_ACTIVITY";
+ static final String ACTION_DESTROY_RING_ALARM_ACTIVITY = "in.basulabs.shakealarmclock.DESTROY_RING_ALARM_ACTIVITY";
/**
- * {@link android.content.SharedPreferences} Key indicating whether the app was recently active. The value
- * is {@code boolean}.
+ * {@link android.content.SharedPreferences} Key indicating whether the app was recently active. The value is {@code
+ * boolean}.
*/
- static final String SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE = "in.basulabs.shakealarmclock" +
- ".SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE";
+ static final String SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE =
+ "in.basulabs.shakealarmclock.SHARED_PREF_KEY_WAS_APP_RECENTLY_ACTIVE";
/**
- * {@link android.content.SharedPreferences} key indicating whether the read storage permission was asked
- * before. This is used to determine if the user had chosen "Don't ask again" before denying the
- * permission. The value is {@code boolean}.
+ * {@link android.content.SharedPreferences} key indicating whether the read storage permission was asked before.
+ * This is used to determine if the user had chosen "Don't ask again" before denying the permission. The value is
+ * {@code boolean}.
*/
static final String SHARED_PREF_KEY_PERMISSION_WAS_ASKED_BEFORE = "in.basulabs.shakealarmclock.PERMISSION_WAS_ASKED_BEFORE";
/**
- * {@link android.content.SharedPreferences} key to store the default shake operation. Can be either
- * {@link #DISMISS} or {@link #SNOOZE}.
+ * {@link android.content.SharedPreferences} key to store the default shake operation. Can be either {@link
+ * #DISMISS} or {@link #SNOOZE}.
*/
- static final String SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION = "in.basulabs.shakealarmclock" +
- ".DEFAULT_SHAKE_OPERATION";
+ static final String SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION = "in.basulabs.shakealarmclock.DEFAULT_SHAKE_OPERATION";
/**
- * {@link android.content.SharedPreferences} key to store the default power button operation. Can be
- * either {@link #DISMISS} or {@link #SNOOZE}.
+ * {@link android.content.SharedPreferences} key to store the default power button operation. Can be either {@link
+ * #DISMISS} or {@link #SNOOZE}.
*/
- static final String SHARED_PREF_KEY_DEFAULT_POWER_BTN_OPERATION = "in.basulabs.shakealarmclock" +
- ".DEFAULT_POWER_BTN_OPERATION";
+ static final String SHARED_PREF_KEY_DEFAULT_POWER_BTN_OPERATION =
+ "in.basulabs.shakealarmclock.DEFAULT_POWER_BTN_OPERATION";
+ /**
+ * Indicates that the ringing alarm should be snoozed.
+ */
static final int SNOOZE = 0;
+ /**
+ * Indicates that the ringing alarm should be dismissed completely.
+ */
static final int DISMISS = 1;
static final int DO_NOTHING = 2;
/**
- * {@link android.content.SharedPreferences} key to store the default snooze state. The value is {@code
- * boolean}.
+ * {@link android.content.SharedPreferences} key to store the default snooze state. The value is {@code boolean}.
*/
- static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_IS_ON = "in.basulabs.shakealarmclock" +
- ".DEFAULT_SNOOZE_STATE";
+ static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_IS_ON = "in.basulabs.shakealarmclock.DEFAULT_SNOOZE_STATE";
/**
* {@link android.content.SharedPreferences} key to store the default snooze interval in minutes.
*/
- static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_INTERVAL = "in.basulabs.shakealarmclock" +
- ".DEFAULT_SNOOZE_INTERVAL";
+ static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_INTERVAL = "in.basulabs.shakealarmclock.DEFAULT_SNOOZE_INTERVAL";
/**
- * {@link android.content.SharedPreferences} key to store the default snooze frequency, i.e. the number of
- * times the alarm will ring before being cancelled automatically.
+ * {@link android.content.SharedPreferences} key to store the default snooze frequency, i.e. the number of times the
+ * alarm will ring before being cancelled automatically.
*/
- static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_FREQ = "in.basulabs.shakealarmclock" +
- ".DEFAULT_SNOOZE_FREQUENCY";
+ static final String SHARED_PREF_KEY_DEFAULT_SNOOZE_FREQ = "in.basulabs.shakealarmclock.DEFAULT_SNOOZE_FREQUENCY";
/**
- * {@link android.content.SharedPreferences} key to store the default alarm tone Uri. If the file is
- * unavailable, it will be replaced by the default alarm tone during runtime. The value is {@code String};
- * should be converted to Uri using {@link android.net.Uri#parse(String)}.
+ * {@link android.content.SharedPreferences} key to store the default alarm tone Uri. If the file is unavailable, it
+ * will be replaced by the default alarm tone during runtime. The value is {@code String}; should be converted to
+ * Uri using {@link android.net.Uri#parse(String)}.
*/
- static final String SHARED_PREF_KEY_DEFAULT_ALARM_TONE_URI = "in.basulabs.shakealarmclock" +
- ".DEFAULT_ALARM_TONE_URI";
+ static final String SHARED_PREF_KEY_DEFAULT_ALARM_TONE_URI = "in.basulabs.shakealarmclock.DEFAULT_ALARM_TONE_URI";
/**
* {@link android.content.SharedPreferences} key to store the default alarm volume.
*/
- static final String SHARED_PREF_KEY_DEFAULT_ALARM_VOLUME = "in.basulabs.shakealarmclock" +
- ".DEFAULT_ALARM_VOLUME";
+ static final String SHARED_PREF_KEY_DEFAULT_ALARM_VOLUME = "in.basulabs.shakealarmclock.DEFAULT_ALARM_VOLUME";
+
+ /**
+ * The app will set its theme according to time. From 10:00 PM to 6:00 AM, the theme will be dark, and light
+ * otherwise.
+ */
+ static final int THEME_AUTO_TIME = 0;
+
+ /**
+ * Indicates that the theme of the app should be light. Corresponds to {@link androidx.appcompat.app.AppCompatDelegate#MODE_NIGHT_NO}.
+ */
+ static final int THEME_LIGHT = 1;
+
+ /**
+ * Indicates that the theme of the app should be light. Corresponds to {@link androidx.appcompat.app.AppCompatDelegate#MODE_NIGHT_YES}.
+ */
+ static final int THEME_DARK = 2;
- static final int THEME_TIME = 0, THEME_LIGHT = 1, THEME_DARK = 2, THEME_SYSTEM = 3;
+ /**
+ * Indicates that the theme of the app should be light. Corresponds to {@link androidx.appcompat.app.AppCompatDelegate#MODE_NIGHT_FOLLOW_SYSTEM}.
+ * Available only on Android Q+.
+ */
+ static final int THEME_SYSTEM = 3;
/**
- * {@link android.content.SharedPreferences} key to store the current theme. Can only have the values
- * {@link #THEME_TIME}, {@link #THEME_LIGHT}, {@link #THEME_DARK} or {@link #THEME_SYSTEM}.
+ * {@link android.content.SharedPreferences} key to store the current theme. Can only have the values {@link
+ * #THEME_AUTO_TIME}, {@link #THEME_LIGHT}, {@link #THEME_DARK} or {@link #THEME_SYSTEM}.
*/
static final String SHARED_PREF_KEY_THEME = "in.basulabs.shakealarmclock.THEME";
static final String SHARED_PREF_KEY_AUTO_SET_TONE = "in.basulabs.shakealarmclock.AUTO_SET_TONE";
+ /**
+ * Unique name for work.
+ */
+ static final String WORK_NAME_ACTIVATE_ALARMS = "in.basulabs.WORK_ACTIVATE_ALARMS";
+
+ /**
+ * Creates a {@link PeriodicWorkRequest} and enqueues a unique work using {@link
+ * WorkManager#enqueueUniquePeriodicWork(String, ExistingPeriodicWorkPolicy, PeriodicWorkRequest)}.
+ *
+ * @param context The {@link Context} that is scheduling the work.
+ */
+ static void schedulePeriodicWork(Context context) {
+
+ try {
+ WorkManager.initialize(context, new Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).build());
+ } catch (Exception ignored) {}
+
+ PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(Worker_ActivateAlarms.class,
+ 15, TimeUnit.MINUTES).build();
+
+ WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORK_NAME_ACTIVATE_ALARMS,
+ ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);
+ }
+
+ /**
+ * Cancels a scheduled work using {@link WorkManager#cancelUniqueWork(String)}.
+ *
+ * @param context The {@link Context} that is requesting the work to be cancelled.
+ */
+ static void cancelScheduledPeriodicWork(Context context) {
+
+ try {
+ WorkManager.initialize(context, new Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).build());
+ } catch (Exception ignored) {}
+
+ WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME_ACTIVATE_ALARMS);
+ }
+
/**
* Get the theme that can be applied using {@link AppCompatDelegate#setDefaultNightMode(int)}.
*
- * @param theme The theme value as stored in {@link android.content.SharedPreferences}. Can only have
- * the values {@link #THEME_TIME}, {@link #THEME_LIGHT}, {@link #THEME_DARK} or {@link #THEME_SYSTEM}.
+ * @param theme The theme value as stored in {@link android.content.SharedPreferences}. Can only have the values
+ * {@link #THEME_AUTO_TIME}, {@link #THEME_LIGHT}, {@link #THEME_DARK} or {@link #THEME_SYSTEM}.
*
- * @return Can have the values {@link AppCompatDelegate#MODE_NIGHT_YES}, {@link
- * AppCompatDelegate#MODE_NIGHT_NO} or {@link AppCompatDelegate#MODE_NIGHT_FOLLOW_SYSTEM}.
+ * @return Can have the values {@link AppCompatDelegate#MODE_NIGHT_YES}, {@link AppCompatDelegate#MODE_NIGHT_NO} or
+ * {@link AppCompatDelegate#MODE_NIGHT_FOLLOW_SYSTEM}.
*/
static int getTheme(int theme) {
switch (theme) {
@@ -288,12 +348,12 @@ static int getTheme(int theme) {
}
}
- static void killServices(Context context, int alarmID){
- if (Service_RingAlarm.isThisServiceRunning && Service_RingAlarm.alarmID == alarmID){
+ static void killServices(Context context, int alarmID) {
+ if (Service_RingAlarm.isThisServiceRunning && Service_RingAlarm.alarmID == alarmID) {
Intent intent = new Intent(context, Service_RingAlarm.class);
context.stopService(intent);
}
- if (Service_SnoozeAlarm.isThisServiceRunning && Service_SnoozeAlarm.alarmID == alarmID){
+ if (Service_SnoozeAlarm.isThisServiceRunning && Service_SnoozeAlarm.alarmID == alarmID) {
Intent intent = new Intent(context, Service_SnoozeAlarm.class);
context.stopService(intent);
}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Fragment_AlarmDetails_Main.java b/app/src/main/java/in/basulabs/shakealarmclock/Fragment_AlarmDetails_Main.java
index 4082b0f..b276389 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/Fragment_AlarmDetails_Main.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Fragment_AlarmDetails_Main.java
@@ -83,15 +83,7 @@ public void onAttach(@NonNull Context context) {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //Log.e(this.getClass().getSimpleName(), "INSIDE ONCREATE()");
savedInstanceStateIsNull = savedInstanceState == null;
- /*if (savedInstanceState == null) {
- //Log.e(this.getClass().getSimpleName(), "Saved instance is null.");
- savedInstanceStateIsNull = true;
- } else {
- //Log.e(this.getClass().getSimpleName(), "Saved instance NOT null.");
- savedInstanceStateIsNull = false;
- }*/
}
//--------------------------------------------------------------------------------------------------
@@ -101,8 +93,6 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
- //Log.e(this.getClass().getSimpleName(), "Inside onCreateView; setView = " + savedInstanceStateIsNull);
-
View view = inflater.inflate(R.layout.frag_alarm_details_main, container, false);
viewModel = new ViewModelProvider(requireActivity()).get(ViewModel_AlarmDetails.class);
@@ -305,8 +295,7 @@ private void displaySnoozeOptions() {
* Updates {@link #currentRepeatOptionsTV}.
*/
private void displayRepeatOptions() {
- /*Log.e(this.getClass().getSimpleName(),
- "contents = " + Arrays.toString(viewModel.getRepeatDays().toArray()));*/
+
if (viewModel.getIsRepeatOn()) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < viewModel.getRepeatDays().size(); i++) {
@@ -359,7 +348,6 @@ private void setDate() {
public void onClick(View view) {
switch (view.getId()) {
case R.id.saveButton:
- //Log.e(this.getClass().toString(), "save button clicked.");
saveButtonClicked();
break;
case R.id.cancelButton:
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/MyApplication.java b/app/src/main/java/in/basulabs/shakealarmclock/MyApplication.java
index 4e70d12..2cd9138 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/MyApplication.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/MyApplication.java
@@ -19,7 +19,6 @@ public class MyApplication extends Application {
@Override
public void onReceive(Context context, Intent intent) {
if (Objects.equals(intent.getAction(), Intent.ACTION_DATE_CHANGED)) {
- //Log.e(this.getClass().getSimpleName(), "Received broadcast.");
Activity_AlarmsList.onDateChanged();
}
}
@@ -31,8 +30,6 @@ public void onReceive(Context context, Intent intent) {
public void onCreate() {
super.onCreate();
- //Log.e(this.getClass().getSimpleName(), "Inside onCreate()........");
-
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_DATE_CHANGED);
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/MyContentProvider.java b/app/src/main/java/in/basulabs/shakealarmclock/MyContentProvider.java
new file mode 100644
index 0000000..3f05ff1
--- /dev/null
+++ b/app/src/main/java/in/basulabs/shakealarmclock/MyContentProvider.java
@@ -0,0 +1,47 @@
+package in.basulabs.shakealarmclock;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+public abstract class MyContentProvider extends ContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
+ @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
+ @Nullable String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
+ return 0;
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ return null;
+ }
+}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/MyWorkManagerInitializer.java b/app/src/main/java/in/basulabs/shakealarmclock/MyWorkManagerInitializer.java
new file mode 100644
index 0000000..5266dff
--- /dev/null
+++ b/app/src/main/java/in/basulabs/shakealarmclock/MyWorkManagerInitializer.java
@@ -0,0 +1,20 @@
+package in.basulabs.shakealarmclock;
+
+import android.util.Log;
+
+import androidx.work.Configuration;
+import androidx.work.WorkManager;
+
+import java.util.Objects;
+
+public class MyWorkManagerInitializer extends MyContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ WorkManager.initialize(Objects.requireNonNull(getContext()),
+ new Configuration.Builder()
+ .setMinimumLoggingLevel(Log.DEBUG)
+ .build());
+ return true;
+ }
+}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Service_AlarmActivater.java b/app/src/main/java/in/basulabs/shakealarmclock/Service_AlarmActivater.java
deleted file mode 100644
index ff77f32..0000000
--- a/app/src/main/java/in/basulabs/shakealarmclock/Service_AlarmActivater.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package in.basulabs.shakealarmclock;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-
-import androidx.annotation.NonNull;
-
-import java.time.DayOfWeek;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.temporal.TemporalAdjusters;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static android.os.SystemClock.elapsedRealtime;
-
-public class Service_AlarmActivater extends Service {
-
- private AlarmDatabase alarmDatabase;
-
- public static boolean isThisServiceRunning;
- public static int pid = - 1;
-
- //-----------------------------------------------------------------------------------------------------
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- //Log.e(this.getClass().getSimpleName(), "service started.");
- isThisServiceRunning = true;
-
- Service_AlarmActivater obj = this;
- pid = android.os.Process.myPid();
-
- alarmDatabase = AlarmDatabase.getInstance(obj);
-
- AtomicReference> alarmEntityList = new AtomicReference<>();
-
- Thread thread = new Thread(
- () -> alarmEntityList.set(alarmDatabase.alarmDAO().getActiveAlarms()));
-
- if (! Service_RingAlarm.isThisServiceRunning && ! Service_SnoozeAlarm.isThisServiceRunning
- && ! Service_UpdateAlarm.isThisServiceRunning) {
- thread.start();
- try {
- thread.join();
-
- if (alarmEntityList.get().size() > 0) {
- activateAlarmsIfInactive(alarmEntityList.get());
- }
- } catch (InterruptedException ignored) {
- }
- }
-
- return START_STICKY;
- }
-
- //------------------------------------------------------------------------------------------------------
-
- @Override
- public void onTaskRemoved(Intent rootIntent) {
- super.onTaskRemoved(rootIntent);
-
- //Log.e(this.getClass().getSimpleName(), "onTaskRemoved() called.");
-
- Intent restartServiceIntent = new Intent(this, AlarmBroadcastReceiver.class);
- restartServiceIntent.setAction(ConstantsAndStatics.ACTION_CREATE_BACKGROUND_SERVICE);
- restartServiceIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-
- PendingIntent restartServicePendingIntent = PendingIntent.getBroadcast(
- getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
-
- AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
- alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsedRealtime() + 3000,
- restartServicePendingIntent);
- }
-
- //------------------------------------------------------------------------------------------------------
-
- private void activateAlarmsIfInactive(@NonNull List list) {
-
- final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
- final Service_AlarmActivater obj = this;
-
- for (AlarmEntity alarmEntity : list) {
-
- Thread thread = new Thread(() -> {
-
- ArrayList repeatDays = new ArrayList<>(
- alarmDatabase.alarmDAO().getAlarmRepeatDays(alarmEntity.alarmID));
-
- Intent intent = new Intent(obj, AlarmBroadcastReceiver.class);
- intent.setAction(ConstantsAndStatics.ACTION_DELIVER_ALARM);
- intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-
- Bundle data = alarmEntity.getAlarmDetailsInABundle();
- data.putIntegerArrayList(ConstantsAndStatics.BUNDLE_KEY_REPEAT_DAYS, repeatDays);
- intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, data);
-
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(obj, alarmEntity.alarmID, intent,
- PendingIntent.FLAG_NO_CREATE);
-
- if (pendingIntent == null) {
- //Log.e(this.getClass().getSimpleName(), "pending intent not found.");
-
- LocalDateTime alarmDateTime;
- LocalDate alarmDate = LocalDate
- .of(alarmEntity.alarmYear, alarmEntity.alarmMonth,
- alarmEntity.alarmDay);
- LocalTime alarmTime = LocalTime
- .of(alarmEntity.alarmHour, alarmEntity.alarmMinutes);
-
- if (alarmEntity.isRepeatOn && repeatDays.size() > 0) {
-
- Collections.sort(repeatDays);
-
- alarmDateTime = LocalDateTime.of(LocalDate.now(), alarmTime);
- int dayOfWeek = alarmDateTime.getDayOfWeek().getValue();
-
- for (int i = 0; i < repeatDays.size(); i++) {
- if (repeatDays.get(i) == dayOfWeek) {
- if (alarmTime.isAfter(LocalTime.now())) {
- // Alarm possible today, nothing more to do, break out of loop.
- break;
- }
- } else if (repeatDays.get(i) > dayOfWeek) {
- // There is a day available in the same week for the alarm to ring; select that day and
- // break from loop.
- alarmDateTime =
- alarmDateTime.with(TemporalAdjusters
- .next(DayOfWeek.of(repeatDays.get(i))));
- break;
- }
- if (i == repeatDays.size() - 1) {
- // No day possible in this week. Select the first available date from next week.
- alarmDateTime = alarmDateTime
- .with(TemporalAdjusters
- .next(DayOfWeek.of(repeatDays.get(0))));
- }
- }
-
- } else {
- alarmDateTime = LocalDateTime.of(alarmDate, alarmTime);
- if (! alarmDateTime.isAfter(LocalDateTime.now())) {
- alarmDateTime.plusDays(1);
- }
- }
-
- ZonedDateTime zonedDateTime = ZonedDateTime
- .of(alarmDateTime, ZoneId.systemDefault());
-
- /*Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, alarmDateTime.getYear());
- calendar.set(Calendar.MONTH, alarmDateTime.getMonthValue() - 1);
- calendar.set(Calendar.DAY_OF_MONTH, alarmDateTime.getDayOfMonth());
- calendar.set(Calendar.HOUR_OF_DAY, alarmDateTime.getHour());
- calendar.set(Calendar.MINUTE, alarmDateTime.getMinute());
- calendar.set(Calendar.SECOND, 0);*/
-
- PendingIntent pendingIntent1 = PendingIntent
- .getBroadcast(obj, alarmEntity.alarmID, intent, 0);
-
- alarmManager.setAlarmClock(
- new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
- pendingIntent1), pendingIntent1);
-
- /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
- calendar.getTimeInMillis(),
- pendingIntent1);
- } else {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
- pendingIntent1);
- }*/
-
- } /*else {
- //Log.e(this.getClass().getSimpleName(), "pending intent found.");
- }*/
-
- });
- thread.start();
- try {
- thread.join();
- } catch (InterruptedException ignored) {
- }
- }
-
-
- }
-
- //---------------------------------------------------------------------------------------------------
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- isThisServiceRunning = false;
- pid = - 1;
- }
-
- //----------------------------------------------------------------------------------------------------
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Service_RingAlarm.java b/app/src/main/java/in/basulabs/shakealarmclock/Service_RingAlarm.java
index f307856..dd0d307 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/Service_RingAlarm.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Service_RingAlarm.java
@@ -25,7 +25,6 @@
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Process;
import android.os.VibrationEffect;
import android.os.Vibrator;
@@ -78,8 +77,7 @@ public class Service_RingAlarm extends Service implements SensorEventListener {
private boolean isShakeActive;
- public static final String BUNDLE_KEY_NO_OF_TIMES_SNOOZED = "in.basulabs.shakealarmclock" +
- ".NO_OF_TIMES_SNOOZED";
+ public static final String BUNDLE_KEY_NO_OF_TIMES_SNOOZED = "in.basulabs.shakealarmclock.NO_OF_TIMES_SNOOZED";
//--------------------------------------------------------------------------------------------------
@@ -87,11 +85,8 @@ public class Service_RingAlarm extends Service implements SensorEventListener {
@Override
public void onReceive(Context context, Intent intent) {
if (Objects.equals(intent.getAction(), ConstantsAndStatics.ACTION_SNOOZE_ALARM)) {
- //Log.e(this.getClass().toString(), "Received broadcast to snooze alarm.");
snoozeAlarm();
- } else if (Objects
- .equals(intent.getAction(), ConstantsAndStatics.ACTION_CANCEL_ALARM)) {
- //Log.e(this.getClass().toString(), "Received broadcast to cancel alarm.");
+ } else if (Objects.equals(intent.getAction(), ConstantsAndStatics.ACTION_CANCEL_ALARM)) {
dismissAlarm();
}
}
@@ -101,46 +96,32 @@ public void onReceive(Context context, Intent intent) {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- //Log.e(this.getClass().toString(), "Inside onStartCommand");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- startForeground(NOTIFICATION_ID, buildRingNotification(),
- ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE);
+ startForeground(NOTIFICATION_ID, buildRingNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE);
} else {
startForeground(NOTIFICATION_ID, buildRingNotification());
}
isThisServiceRunning = true;
- if (Service_AlarmActivater.isThisServiceRunning) {
- Intent intent1 = new Intent(this, Service_AlarmActivater.class);
- stopService(intent1);
- }
- if (Service_AlarmActivater.pid != - 1) {
- Process.killProcess(Service_AlarmActivater.pid);
- }
+ ConstantsAndStatics.cancelScheduledPeriodicWork(this);
- alarmDetails = Objects.requireNonNull(intent.getExtras())
- .getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS);
+ alarmDetails = Objects.requireNonNull(intent.getExtras()).getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS);
- numberOfTimesTheAlarmHasBeenSnoozed = intent.getExtras()
- .getInt(BUNDLE_KEY_NO_OF_TIMES_SNOOZED, 0);
+ numberOfTimesTheAlarmHasBeenSnoozed = intent.getExtras().getInt(BUNDLE_KEY_NO_OF_TIMES_SNOOZED, 0);
assert alarmDetails != null;
- sharedPreferences = getSharedPreferences(ConstantsAndStatics.SHARED_PREF_FILE_NAME,
- MODE_PRIVATE);
+ sharedPreferences = getSharedPreferences(ConstantsAndStatics.SHARED_PREF_FILE_NAME, MODE_PRIVATE);
- isShakeActive = sharedPreferences
- .getInt(ConstantsAndStatics.SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION,
- ConstantsAndStatics.SNOOZE) != ConstantsAndStatics.DO_NOTHING;
+ isShakeActive = sharedPreferences.getInt(ConstantsAndStatics.SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION,
+ ConstantsAndStatics.SNOOZE) != ConstantsAndStatics.DO_NOTHING;
assert alarmDetails != null;
alarmToneUri = alarmDetails.getParcelable(ConstantsAndStatics.BUNDLE_KEY_ALARM_TONE_URI);
- //Log.e(this.getClass().toString(), "Received Uri: " + alarmToneUri.toString());
alarmID = alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID);
- //Log.e(this.getClass().getSimpleName(), "alarmID = " + alarmID);
ringTimer = new CountDownTimer(60000, 1000) {
@@ -183,7 +164,6 @@ public void onFinish() {
@Override
public void onDestroy() {
super.onDestroy();
- //Log.e(this.getClass().getSimpleName(), "onDestroy() called.");
isThisServiceRunning = false;
try {
ringTimer.cancel();
@@ -209,8 +189,7 @@ public void onDestroy() {
private void initialiseShakeSensor() {
if (isShakeActive) {
Sensor accelerometer = snsMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- snsMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI,
- new Handler());
+ snsMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI, new Handler());
lastShakeTime = System.currentTimeMillis();
}
}
@@ -225,8 +204,7 @@ private void createNotificationChannel() {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(Integer.toString(NOTIFICATION_ID),
"in.basulabs.shakealarmclock Notifications", importance);
- NotificationManager notificationManager = (NotificationManager) getSystemService(
- NOTIFICATION_SERVICE);
+ NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
channel.setSound(null, null);
assert notificationManager != null;
notificationManager.createNotificationChannel(channel);
@@ -236,11 +214,11 @@ private void createNotificationChannel() {
//--------------------------------------------------------------------------------------------------
/**
- * Creates a notification that can be shown when the alarm is ringing. Has a full screen intent
- * to {@link Activity_RingAlarm}. The content intent points to {@link Activity_AlarmsList}.
+ * Creates a notification that can be shown when the alarm is ringing. Has a full screen intent to {@link
+ * Activity_RingAlarm}. The content intent points to {@link Activity_AlarmsList}.
*
- * @return A {@link Notification} that can be used with {@link #startForeground(int,
- * Notification)} or displayed with {@link NotificationManager#notify(int, Notification)}.
+ * @return A {@link Notification} that can be used with {@link #startForeground(int, Notification)} or displayed
+ * with {@link NotificationManager#notify(int, Notification)}.
*/
private Notification buildRingNotification() {
createNotificationChannel();
@@ -272,13 +250,12 @@ private Notification buildRingNotification() {
*/
private void ringAlarm() {
- //Log.e(this.getClass().getSimpleName(), "Ring Alarm called.");
notificationManager.notify(NOTIFICATION_ID, buildRingNotification());
initialiseShakeSensor();
- if (! (alarmDetails
- .getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE) == ConstantsAndStatics.ALARM_TYPE_VIBRATE_ONLY)) {
+ if (! (alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE)
+ == ConstantsAndStatics.ALARM_TYPE_VIBRATE_ONLY)) {
mediaPlayer = new MediaPlayer();
AudioAttributes attributes = new AudioAttributes.Builder()
@@ -297,8 +274,8 @@ private void ringAlarm() {
} catch (IOException ignored) {
}
- if (alarmDetails
- .getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE) == ConstantsAndStatics.ALARM_TYPE_SOUND_AND_VIBRATE) {
+ if (alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE)
+ == ConstantsAndStatics.ALARM_TYPE_SOUND_AND_VIBRATE) {
alarmVibration();
}
mediaPlayer.start();
@@ -323,9 +300,7 @@ private void alarmVibration() {
if (vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (vibrator.hasAmplitudeControl()) {
- vibrator.vibrate(
- VibrationEffect
- .createWaveform(vibrationPattern, vibrationAmplitudes, 0));
+ vibrator.vibrate(VibrationEffect.createWaveform(vibrationPattern, vibrationAmplitudes, 0));
}
} else {
vibrator.vibrate(vibrationPattern, 0);
@@ -336,8 +311,8 @@ private void alarmVibration() {
//--------------------------------------------------------------------------------------------------
/**
- * Snoozes the alarm. If snooze is off, or the snoze frequency has been reached, the alarm will
- * be cancelled by calling {@link #dismissAlarm()}.
+ * Snoozes the alarm. If snooze is off, or the snoze frequency has been reached, the alarm will be cancelled by
+ * calling {@link #dismissAlarm()}.
*/
private void snoozeAlarm() {
@@ -352,8 +327,7 @@ private void snoozeAlarm() {
Intent intent = new Intent(this, Service_SnoozeAlarm.class);
intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, alarmDetails);
- intent.putExtra(BUNDLE_KEY_NO_OF_TIMES_SNOOZED,
- numberOfTimesTheAlarmHasBeenSnoozed);
+ intent.putExtra(BUNDLE_KEY_NO_OF_TIMES_SNOOZED, numberOfTimesTheAlarmHasBeenSnoozed);
ContextCompat.startForegroundService(this, intent);
stopSelf();
@@ -377,8 +351,7 @@ private void dismissAlarm() {
Thread thread_toggleAlarm = new Thread(
() -> alarmDatabase.alarmDAO()
- .toggleAlarm(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID),
- 0));
+ .toggleAlarm(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID), 0));
//////////////////////////////////////////////////////
// If repeat is on, set another alarm. Otherwise
@@ -391,9 +364,8 @@ private void dismissAlarm() {
} catch (InterruptedException ignored) {
}
} else {
- LocalTime alarmTime = LocalTime
- .of(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_HOUR),
- alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_MINUTE));
+ LocalTime alarmTime = LocalTime.of(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_HOUR),
+ alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_MINUTE));
ArrayList repeatDays = alarmDetails
.getIntegerArrayList(ConstantsAndStatics.BUNDLE_KEY_REPEAT_DAYS);
@@ -413,18 +385,18 @@ private void dismissAlarm() {
} else if (repeatDays.get(i) > dayOfWeek) {
// There is a day available in the same week for the alarm to ring; select that day and
// break from loop.
- alarmDateTime = alarmDateTime
- .with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(i))));
+ alarmDateTime = alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(i))));
break;
}
if (i == repeatDays.size() - 1) {
// No day possible in this week. Select the first available date from next week.
- alarmDateTime = alarmDateTime
- .with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(0))));
+ alarmDateTime = alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(0))));
}
}
setAlarm(alarmDateTime);
}
+
+ ConstantsAndStatics.schedulePeriodicWork(this);
stopSelf();
}
@@ -432,13 +404,12 @@ private void dismissAlarm() {
//--------------------------------------------------------------------------------------------------
/**
- * Stops the ringing alarm. Also sends a broadcast to {@link Activity_RingAlarm} to finish
- * itsef.
+ * Stops the ringing alarm. Also sends a broadcast to {@link Activity_RingAlarm} to finish itsef.
*/
private void stopRinging() {
try {
ringTimer.cancel();
- //snoozeTimer.cancel();
+
if ((alarmDetails
.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE) == ConstantsAndStatics.ALARM_TYPE_VIBRATE_ONLY) || (alarmDetails
.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_TYPE) == ConstantsAndStatics.ALARM_TYPE_SOUND_AND_VIBRATE)) {
@@ -469,12 +440,10 @@ private void setAlarm(LocalDateTime alarmDateTime) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, alarmID, intent, 0);
- ZonedDateTime zonedDateTime = ZonedDateTime
- .of(alarmDateTime.withSecond(0), ZoneId.systemDefault());
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime.withSecond(0), ZoneId.systemDefault());
alarmManager.setAlarmClock(
- new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
- pendingIntent), pendingIntent);
+ new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000, pendingIntent), pendingIntent);
}
//---------------------------------------------------------------------------------------------------
@@ -487,8 +456,7 @@ private void cancelPendingIntent() {
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, alarmDetails);
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(this, alarmID, intent, PendingIntent.FLAG_NO_CREATE);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, alarmID, intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
@@ -516,20 +484,16 @@ public void onSensorChanged(SensorEvent event) {
float gZ = z / SensorManager.GRAVITY_EARTH;
float gForce = (float) Math.sqrt(gX * gX + gY * gY + gZ * gZ);
- //Log.e(this.getClass().getSimpleName(), "gForce: " + gForce);
// gForce will be close to 1 when there is no movement.
if (gForce >= 3.8f) {
long currTime = System.currentTimeMillis();
if (Math.abs(currTime - lastShakeTime) > MINIMUM_MILLIS_BETWEEN_SHAKES) {
- //Log.e(this.getClass().getSimpleName(), "Event detected, ");
lastShakeTime = currTime;
shakeVibration();
- if (sharedPreferences
- .getInt(ConstantsAndStatics.SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION,
- ConstantsAndStatics.SNOOZE) == ConstantsAndStatics.SNOOZE
- && alarmDetails
- .getBoolean(ConstantsAndStatics.BUNDLE_KEY_IS_SNOOZE_ON)) {
+ if (sharedPreferences.getInt(ConstantsAndStatics.SHARED_PREF_KEY_DEFAULT_SHAKE_OPERATION,
+ ConstantsAndStatics.SNOOZE) == ConstantsAndStatics.SNOOZE
+ && alarmDetails.getBoolean(ConstantsAndStatics.BUNDLE_KEY_IS_SNOOZE_ON)) {
snoozeAlarm();
} else {
dismissAlarm();
@@ -543,14 +507,12 @@ public void onSensorChanged(SensorEvent event) {
//--------------------------------------------------------------------------------------------------
/**
- * Creates a vibration for a small period of time, indicating that the app has registered a
- * shake event.
+ * Creates a vibration for a small period of time, indicating that the app has registered a shake event.
*/
private void shakeVibration() {
if (vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- vibrator.vibrate(
- VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
+ vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(200);
}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Service_SnoozeAlarm.java b/app/src/main/java/in/basulabs/shakealarmclock/Service_SnoozeAlarm.java
index ef4a12b..4a53746 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/Service_SnoozeAlarm.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Service_SnoozeAlarm.java
@@ -15,7 +15,6 @@
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.IBinder;
-import android.os.Process;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
@@ -66,21 +65,13 @@ public int onStartCommand(Intent intent, int flags, int startId) {
}
isThisServiceRunning = true;
- if (Service_AlarmActivater.isThisServiceRunning) {
- Intent intent1 = new Intent(this, Service_AlarmActivater.class);
- stopService(intent1);
- }
- if (Service_AlarmActivater.pid != - 1) {
- Process.killProcess(Service_AlarmActivater.pid);
- }
+ ConstantsAndStatics.cancelScheduledPeriodicWork(this);
Bundle data = Objects.requireNonNull(intent.getExtras());
alarmDetails = data.getBundle(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS);
assert alarmDetails != null;
alarmID = alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID);
- //Log.e(this.getClass().getSimpleName(), "alarmID = " + alarmID);
-
numberOfTimesTheAlarmhasBeenSnoozed =
intent.getExtras().getInt(Service_RingAlarm.BUNDLE_KEY_NO_OF_TIMES_SNOOZED);
@@ -98,13 +89,12 @@ public int onStartCommand(Intent intent, int flags, int startId) {
alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_MINUTE), 0, 0),
ZoneId.systemDefault());
- ZonedDateTime newAlarmDateTime =
- alarmDateTime
- .plusMinutes(numberOfTimesTheAlarmhasBeenSnoozed * alarmDetails
+ ZonedDateTime newAlarmDateTime = alarmDateTime.plusMinutes(numberOfTimesTheAlarmhasBeenSnoozed * alarmDetails
.getInt(ConstantsAndStatics.BUNDLE_KEY_SNOOZE_TIME_IN_MINS));
- snoozeTimer = new CountDownTimer(
- Math.abs(Duration.between(ZonedDateTime.now(), newAlarmDateTime).toMillis()), 500) {
+ snoozeTimer = new CountDownTimer(Math.abs(Duration.between(ZonedDateTime.now(),
+ newAlarmDateTime).toMillis()), 500) {
+
@Override
public void onTick(long l) {
}
@@ -113,8 +103,7 @@ public void onTick(long l) {
public void onFinish() {
Intent intent1 = new Intent(myInstance, Service_RingAlarm.class);
intent1.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, alarmDetails);
- intent1.putExtra(Service_RingAlarm.BUNDLE_KEY_NO_OF_TIMES_SNOOZED,
- numberOfTimesTheAlarmhasBeenSnoozed);
+ intent1.putExtra(Service_RingAlarm.BUNDLE_KEY_NO_OF_TIMES_SNOOZED, numberOfTimesTheAlarmhasBeenSnoozed);
ContextCompat.startForegroundService(myInstance, intent1);
myInstance.stopSelf();
}
@@ -178,10 +167,8 @@ private void dismissAlarm() {
AlarmDatabase alarmDatabase = AlarmDatabase.getInstance(this);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
- Thread thread_toggleAlarm = new Thread(
- () -> alarmDatabase.alarmDAO()
- .toggleAlarm(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID),
- 0));
+ Thread thread_toggleAlarm = new Thread(() ->
+ alarmDatabase.alarmDAO().toggleAlarm(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID),0));
/////////////////////////////////////
// Dismiss the snoozed alarm
@@ -190,10 +177,8 @@ private void dismissAlarm() {
intent.setAction(ConstantsAndStatics.ACTION_DELIVER_ALARM);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(this, alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID),
- intent,
- PendingIntent.FLAG_NO_CREATE);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID),
+ intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
@@ -210,12 +195,10 @@ private void dismissAlarm() {
} catch (InterruptedException ignored) {
}
} else {
- LocalTime alarmTime = LocalTime
- .of(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_HOUR),
+ LocalTime alarmTime = LocalTime.of(alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_HOUR),
alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_MINUTE));
- ArrayList repeatDays = alarmDetails
- .getIntegerArrayList(ConstantsAndStatics.BUNDLE_KEY_REPEAT_DAYS);
+ ArrayList repeatDays = alarmDetails.getIntegerArrayList(ConstantsAndStatics.BUNDLE_KEY_REPEAT_DAYS);
assert repeatDays != null;
Collections.sort(repeatDays);
@@ -232,31 +215,26 @@ private void dismissAlarm() {
} else if (repeatDays.get(i) > dayOfWeek) {
// There is a day available in the same week for the alarm to ring; select that day and
// break from loop.
- alarmDateTime = alarmDateTime
- .with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(i))));
+ alarmDateTime = alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(i))));
break;
}
if (i == repeatDays.size() - 1) {
// No day possible in this week. Select the first available date from next week.
- alarmDateTime = alarmDateTime
- .with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(0))));
+ alarmDateTime = alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(0))));
}
}
intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, alarmDetails);
- PendingIntent pendingIntent2 = PendingIntent
- .getBroadcast(this,
- alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID), intent,
- 0);
+ PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this,
+ alarmDetails.getInt(ConstantsAndStatics.BUNDLE_KEY_ALARM_ID), intent, 0);
- ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime.withSecond(0),
- ZoneId.systemDefault());
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime.withSecond(0), ZoneId.systemDefault());
- alarmManager.setAlarmClock(
- new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
+ alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
pendingIntent2), pendingIntent2);
}
+ ConstantsAndStatics.schedulePeriodicWork(this);
stopSelf();
}
@@ -271,8 +249,7 @@ private void cancelPendingIntent() {
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, alarmDetails);
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(this, alarmID, intent, PendingIntent.FLAG_NO_CREATE);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, alarmID, intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Service_UpdateAlarm.java b/app/src/main/java/in/basulabs/shakealarmclock/Service_UpdateAlarm.java
index 8932b61..8bc3ea2 100644
--- a/app/src/main/java/in/basulabs/shakealarmclock/Service_UpdateAlarm.java
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Service_UpdateAlarm.java
@@ -42,33 +42,16 @@ public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(NOTIFICATION_ID, buildNotification());
isThisServiceRunning = true;
+ ConstantsAndStatics.cancelScheduledPeriodicWork(this);
+
alarmDatabase = AlarmDatabase.getInstance(this);
ArrayList alarmEntityArrayList = getActiveAlarms();
- //Log.e(this.getClass().toString(), "Started.");
-
if (alarmEntityArrayList != null && alarmEntityArrayList.size() > 0) {
- //Log.e(this.getClass().toString(), "We have active alarms.");
-
- try {
- if (Service_AlarmActivater.isThisServiceRunning) {
- Intent intent1 = new Intent(this, Service_AlarmActivater.class);
- stopService(intent1);
- }
- if (Service_AlarmActivater.pid != - 1) {
- android.os.Process.killProcess(Service_AlarmActivater.pid);
- }
-
- } catch (Exception ignored) {
- }
-
cancelActiveAlarms(alarmEntityArrayList);
activateAlarms(alarmEntityArrayList);
-
- Intent intent1 = new Intent(this, Service_AlarmActivater.class);
- startService(intent1);
}
stopSelf();
@@ -82,6 +65,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
public void onDestroy() {
super.onDestroy();
isThisServiceRunning = false;
+ ConstantsAndStatics.schedulePeriodicWork(this);
}
@@ -95,8 +79,7 @@ private void createNotificationChannel() {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(Integer.toString(NOTIFICATION_ID),
"in.basulabs.shakealarmclock Notification", importance);
- NotificationManager notificationManager = (NotificationManager) getSystemService(
- NOTIFICATION_SERVICE);
+ NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
channel.setSound(null, null);
assert notificationManager != null;
notificationManager.createNotificationChannel(channel);
@@ -118,8 +101,8 @@ private Notification buildNotification() {
Intent contentIntent = new Intent(this, Activity_AlarmsList.class);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
contentIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- PendingIntent contentPendingIntent = PendingIntent
- .getActivity(this, 5701, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent contentPendingIntent = PendingIntent.getActivity(this, 5701,
+ contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
Integer.toString(NOTIFICATION_ID))
@@ -143,8 +126,7 @@ private Notification buildNotification() {
@Nullable
private ArrayList getActiveAlarms() {
- AtomicReference> alarmEntityArrayList = new AtomicReference<>(
- new ArrayList<>());
+ AtomicReference> alarmEntityArrayList = new AtomicReference<>(new ArrayList<>());
Thread thread = new Thread(
() -> alarmEntityArrayList.set(new ArrayList<>(alarmDatabase.alarmDAO().getActiveAlarms())));
@@ -172,38 +154,18 @@ private void cancelActiveAlarms(@NonNull ArrayList alarmEntityArray
for (AlarmEntity alarmEntity : alarmEntityArrayList) {
- /*if (Service_RingAlarm.isThisServiceRunning) {
- if (Service_RingAlarm.alarmHour == alarmEntity.alarmHour && Service_RingAlarm.alarmMinute == alarmEntity.alarmMinutes) {
- Intent intent1 = new Intent(this, Service_RingAlarm.class);
- stopService(intent1);
- }
- }*/
-
ConstantsAndStatics.killServices(this, alarmEntity.alarmID);
- /*LocalDateTime localDateTime = LocalDateTime.of(alarmEntity.alarmYear, alarmEntity.alarmMonth,
- alarmEntity.alarmDay, alarmEntity.alarmHour, alarmEntity.alarmMinutes);
-
- ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,
- ZoneId.of(sharedPreferences.getString(ConstantsAndStatics.SHARED_PREF_KEY_ZONE_ID,
- ZoneId.systemDefault().getId())));
-
- zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault());*/
-
Intent intent = new Intent(Service_UpdateAlarm.this, AlarmBroadcastReceiver.class);
intent.setAction(ConstantsAndStatics.ACTION_DELIVER_ALARM);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- PendingIntent pendingIntent = PendingIntent
- .getBroadcast(Service_UpdateAlarm.this, alarmEntity.alarmID, intent,
- PendingIntent.FLAG_NO_CREATE);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(Service_UpdateAlarm.this,
+ alarmEntity.alarmID, intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
- //Log.e(this.getClass().toString(), "Alarm cancelled.");
- } /*else {
- //Log.e(this.getClass().toString(), "Alarm not found.");
- }*/
+ }
}
}
@@ -214,9 +176,8 @@ private ArrayList getRepeatDays(int alarmID) {
AtomicReference> repeatDays = new AtomicReference<>();
- Thread thread =
- new Thread(() -> repeatDays
- .set(new ArrayList<>(alarmDatabase.alarmDAO().getAlarmRepeatDays(alarmID))));
+ Thread thread = new Thread(
+ () -> repeatDays.set(new ArrayList<>(alarmDatabase.alarmDAO().getAlarmRepeatDays(alarmID))));
thread.start();
try {
thread.join();
@@ -238,8 +199,7 @@ private void activateAlarms(@NonNull ArrayList alarmEntityArrayList
ArrayList repeatDays = getRepeatDays(alarmEntity.alarmID);
LocalDateTime alarmDateTime;
- LocalDate alarmDate = LocalDate.of(alarmEntity.alarmYear, alarmEntity.alarmMonth,
- alarmEntity.alarmDay);
+ LocalDate alarmDate = LocalDate.of(alarmEntity.alarmYear, alarmEntity.alarmMonth, alarmEntity.alarmDay);
LocalTime alarmTime = LocalTime.of(alarmEntity.alarmHour, alarmEntity.alarmMinutes);
if (alarmEntity.isRepeatOn && repeatDays != null && repeatDays.size() > 0) {
@@ -294,24 +254,8 @@ private void activateAlarms(@NonNull ArrayList alarmEntityArrayList
ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime, ZoneId.systemDefault());
- /*Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, alarmDateTime.getYear());
- calendar.set(Calendar.MONTH, alarmDateTime.getMonthValue() - 1);
- calendar.set(Calendar.DAY_OF_MONTH, alarmDateTime.getDayOfMonth());
- calendar.set(Calendar.HOUR_OF_DAY, alarmDateTime.getHour());
- calendar.set(Calendar.MINUTE, alarmDateTime.getMinute());
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);*/
-
alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
pendingIntent), pendingIntent);
- /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
- pendingIntent);
- } else {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
- }*/
-
}
diff --git a/app/src/main/java/in/basulabs/shakealarmclock/Worker_ActivateAlarms.java b/app/src/main/java/in/basulabs/shakealarmclock/Worker_ActivateAlarms.java
new file mode 100644
index 0000000..c38472a
--- /dev/null
+++ b/app/src/main/java/in/basulabs/shakealarmclock/Worker_ActivateAlarms.java
@@ -0,0 +1,145 @@
+package in.basulabs.shakealarmclock;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Worker_ActivateAlarms extends Worker {
+
+ Context context;
+
+ private boolean stopExecuting;
+
+ //----------------------------------------------------------------------------------------------------------
+
+ public Worker_ActivateAlarms(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
+ this.context = context;
+ }
+
+ //----------------------------------------------------------------------------------------------------------
+
+ @NonNull
+ @Override
+ public Result doWork() {
+
+ stopExecuting = false;
+ activateAlarmsIfInactive();
+
+ return Result.success();
+ }
+
+ //----------------------------------------------------------------------------------------------------------
+
+ /**
+ * Activates the alarms that are ON, but inactive because {@link AlarmManager} has cancelled them for no reason.
+ */
+ private void activateAlarmsIfInactive() {
+
+ final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ final AlarmDatabase alarmDatabase = AlarmDatabase.getInstance(context);
+
+ List list = alarmDatabase.alarmDAO().getActiveAlarms();
+
+ if (list != null && list.size() > 0) {
+
+ for (AlarmEntity alarmEntity : list) {
+
+ AtomicReference> repeatDaysAtomic = new AtomicReference<>();
+
+ alarmDatabase.alarmDAO().getAlarmRepeatDays(alarmEntity.alarmID);
+
+ ArrayList repeatDays = repeatDaysAtomic.get();
+
+ Intent intent = new Intent(context, AlarmBroadcastReceiver.class);
+ intent.setAction(ConstantsAndStatics.ACTION_DELIVER_ALARM);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+ Bundle data = alarmEntity.getAlarmDetailsInABundle();
+ data.putIntegerArrayList(ConstantsAndStatics.BUNDLE_KEY_REPEAT_DAYS, repeatDays);
+ intent.putExtra(ConstantsAndStatics.BUNDLE_KEY_ALARM_DETAILS, data);
+
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(context, alarmEntity.alarmID, intent,
+ PendingIntent.FLAG_NO_CREATE);
+
+ if (pendingIntent == null) {
+
+ LocalDateTime alarmDateTime;
+ LocalDate alarmDate = LocalDate.of(alarmEntity.alarmYear, alarmEntity.alarmMonth, alarmEntity.alarmDay);
+ LocalTime alarmTime = LocalTime.of(alarmEntity.alarmHour, alarmEntity.alarmMinutes);
+
+ if (alarmEntity.isRepeatOn && repeatDays.size() > 0) {
+
+ Collections.sort(repeatDays);
+
+ alarmDateTime = LocalDateTime.of(LocalDate.now(), alarmTime);
+ int dayOfWeek = alarmDateTime.getDayOfWeek().getValue();
+
+ for (int i = 0; i < repeatDays.size(); i++) {
+ if (repeatDays.get(i) == dayOfWeek) {
+ if (alarmTime.isAfter(LocalTime.now())) {
+ // Alarm possible today, nothing more to do, break out of loop.
+ break;
+ }
+ } else if (repeatDays.get(i) > dayOfWeek) {
+ // There is a day available in the same week for the alarm to ring; select that day and
+ // break from loop.
+ alarmDateTime =
+ alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(i))));
+ break;
+ }
+ if (i == repeatDays.size() - 1) {
+ // No day possible in this week. Select the first available date from next week.
+ alarmDateTime = alarmDateTime.with(TemporalAdjusters.next(DayOfWeek.of(repeatDays.get(0))));
+ }
+ }
+
+ } else {
+ alarmDateTime = LocalDateTime.of(alarmDate, alarmTime);
+ if (! alarmDateTime.isAfter(LocalDateTime.now())) {
+ alarmDateTime.plusDays(1);
+ }
+ }
+
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(alarmDateTime, ZoneId.systemDefault());
+
+ PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, alarmEntity.alarmID, intent, 0);
+
+ alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(zonedDateTime.toEpochSecond() * 1000,
+ pendingIntent1), pendingIntent1);
+
+ }
+
+ if (stopExecuting && ! isStopped()) {
+ break;
+ }
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------------------------------------
+
+ @Override
+ public void onStopped() {
+ super.onStopped();
+ stopExecuting = true;
+ }
+}
diff --git a/build.gradle b/build.gradle
index c64a238..b974aec 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,3 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
@@ -6,9 +5,6 @@ buildscript {
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
}
}
@@ -17,11 +13,6 @@ allprojects {
google()
jcenter()
}
- /*gradle.projectsEvaluated {
- tasks.withType(JavaCompile) {
- options.compilerArgs << "-Xlint:deprecation"
- }
- }*/
}
task clean(type: Delete) {