Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ private void deletePersonDialog(final Person person) {
@Override
public void onClick(DialogInterface dialog, int which) {

new AlarmHelper(getApplicationContext()).removeAlarms(timeStamp);
new AlarmHelper(getApplicationContext()).removeAlarms(person);
dbHelper.removeRecord(timeStamp);
Utils.notifyWidget(getApplicationContext());
dialog.dismiss();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private String updateText(EditText editText) {

private void setAlarms(Person person) {
AlarmHelper alarmHelper = new AlarmHelper(this);
alarmHelper.removeAlarms(person.getTimeStamp());
alarmHelper.removeAlarms(person);
alarmHelper.setAlarms(person);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.ListPreference;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
Expand All @@ -53,7 +54,10 @@
import com.djonique.birdays.utils.PermissionManager;
import com.djonique.birdays.utils.Utils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SettingsActivity extends AppCompatActivity implements ContactsHelper.LoadingContactsListener {

Expand Down Expand Up @@ -182,21 +186,47 @@ public static class BirdaysPreferenceFragment extends PreferenceFragment

private SharedPreferences preferences;

private String getAdditionalNotificationsSelectedValues(MultiSelectListPreference preference) {
final Map<CharSequence, CharSequence> names = new LinkedHashMap<>();

for (int i = 0; i < preference.getEntryValues().length; i++) {
names.put(preference.getEntryValues()[i], preference.getEntries()[i]);
}
StringBuilder sb = new StringBuilder();
for (CharSequence candidate : names.keySet()) {
if (preference.getValues().contains(candidate)) {
sb.append(names.get(candidate)).append(", ");
}
}
if (sb.length() > 2) {
sb.setLength(sb.length() - 2); //remove last ', '
}
else {
sb.append(getActivity().getApplicationContext().getText(R.string.never));
}

return sb.toString();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);

preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

MultiSelectListPreference multi = (MultiSelectListPreference) findPreference(Constants.ADDITIONAL_NOTIFICATION_KEY);
multi.setSummary(getAdditionalNotificationsSelectedValues(multi));

/*
* Set summary for additional notification
*/
findPreference(Constants.ADDITIONAL_NOTIFICATION_KEY).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
((ListPreference) preference).setValue(newValue.toString());
preference.setSummary(((ListPreference) preference).getEntry());
public boolean onPreferenceChange(Preference uncastPreference, Object newValue) {
final MultiSelectListPreference preference = (MultiSelectListPreference) uncastPreference;
preference.setValues((Set<String>) newValue);
preference.setSummary(getAdditionalNotificationsSelectedValues(preference));
return true;
}
});
Expand Down Expand Up @@ -424,13 +454,11 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
new Thread(new Runnable() {
@Override
public void run() {
if (isChecked) {
for (Person person : persons) {
for (Person person : persons) {
if (isChecked) {
alarmHelper.setAlarms(person);
}
} else {
for (Person person : persons) {
alarmHelper.removeAlarms(person.getTimeStamp());
} else {
alarmHelper.removeAlarms(person);
}
}
}
Expand All @@ -452,32 +480,29 @@ public void run() {
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

private void restartAlarms(final AlarmHelper alarmHelper, final List<Person> persons) {
new Thread(new Runnable() {
@Override
public void run() {
for (Person person : persons) {
alarmHelper.removeAlarms(person.getTimeStamp());
alarmHelper.removeAlarms(person);
alarmHelper.setAlarms(person);
}
}
}).start();
}

private void restartApp() {
Intent intent = getActivity().getPackageManager()
.getLaunchIntentForPackage(getActivity().getPackageName());
Intent intent = getActivity().getPackageManager().getLaunchIntentForPackage(getActivity().getPackageName());
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Expand Down
132 changes: 67 additions & 65 deletions app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,19 @@
import com.djonique.birdays.utils.Utils;

import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class AlarmHelper {
import static android.text.format.DateUtils.DAY_IN_MILLIS;

private static final int REQUEST_CODE_OFFSET = 99;
private long defaultNotificationTime = 645703200000L - Utils.getTimeOffset();
private long additionalNotificationOffset;
private Context context;
private AlarmManager alarmManager;
private SharedPreferences preferences;
public class AlarmHelper {
final private long defaultNotificationTime = 645703200000L - Utils.getTimeOffset();
final private HashMap<Person, Set<PendingIntent>> pendingIntents = new HashMap<>();
final private Context context;
final private AlarmManager alarmManager;
final private SharedPreferences preferences;

public AlarmHelper(Context context) {
this.context = context;
Expand All @@ -55,9 +59,9 @@ public AlarmHelper(Context context) {
public void setAlarms(Person person) {
try {
setAlarm(person);
additionalNotificationOffset = Long.parseLong(preferences.getString(Constants.ADDITIONAL_NOTIFICATION_KEY, "0"));
if (additionalNotificationOffset != 0) {
setAdditionalAlarm(person);
Set<Long> additionalNotificationOffsets = getAdditionalNotificationOffsets();
if ((additionalNotificationOffsets != null) && (!additionalNotificationOffsets.isEmpty())) {
setAdditionalAlarms(person);
}
} catch (SecurityException e) {
if (context instanceof Activity) {
Expand All @@ -71,6 +75,14 @@ public void run() {
}
}

private void addPendingIntent(Person person, PendingIntent pendingIntent) {
if (!pendingIntents.containsKey(person)) {
pendingIntents.put(person, new HashSet<PendingIntent>());
}

pendingIntents.get(person).add(pendingIntent);
}

/**
* Set up main alarm
*/
Expand All @@ -85,28 +97,33 @@ private void setAlarm(Person person) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
(int) person.getTimeStamp(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

addPendingIntent(person, pendingIntent); //main alarm

setAlarmDependingOnApi(alarmManager, triggerAtMillis, pendingIntent);
}

/**
* Set up additional alarm
* Set up additional alarms
*/
private void setAdditionalAlarm(Person person) {
additionalNotificationOffset = Long.parseLong(preferences.getString(Constants.ADDITIONAL_NOTIFICATION_KEY, "0"));
private void setAdditionalAlarms(Person person) {
Set<Long> additionalNotificationOffsets = getAdditionalNotificationOffsets();
for (Long additionalNotificationOffset : additionalNotificationOffsets) {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(Constants.NAME, person.getName());
intent.putExtra(Constants.WHEN, setWhen(additionalNotificationOffset));
intent.putExtra(Constants.TIME_STAMP, person.getTimeStamp());

Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(Constants.NAME, person.getName());
intent.putExtra(Constants.WHEN, setWhen(additionalNotificationOffset));
intent.putExtra(Constants.TIME_STAMP, person.getTimeStamp());
long triggerAtMillis = setupCalendarYear(person, additionalNotificationOffset);

long triggerAtMillis = setupCalendarYear(person, additionalNotificationOffset);
int requestCode = (int) (person.getTimeStamp() + additionalNotificationOffset);

int requestCode = (int) person.getTimeStamp() + REQUEST_CODE_OFFSET;
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
(int) requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
addPendingIntent(person, pendingIntent);

setAlarmDependingOnApi(alarmManager, triggerAtMillis, pendingIntent);
setAlarmDependingOnApi(alarmManager, triggerAtMillis, pendingIntent);
}
}

/**
Expand All @@ -128,70 +145,55 @@ private void setAlarmDependingOnApi(AlarmManager alarmManager,
* Configures text for additional notification
*/
private String setWhen(long offset) {
String[] dates = context.getResources().getStringArray(R.array.additional_notification_delay);
String[] entryValues = context.getResources().getStringArray(R.array.additional_notification_entry_values);
String when = null;
for (int i = 1; i < entryValues.length; i++) {
if (offset == Long.parseLong(entryValues[i])) {
when = dates[i];
final String[] dates = context.getResources().getStringArray(R.array.additional_notification_delay);
final String[] entryValues = context.getResources().getStringArray(R.array.additional_notification_entry_values);
for (int i = 0; i < entryValues.length; i++) {
if (offset == (Long.parseLong(entryValues[i]) * DAY_IN_MILLIS)) {
return dates[i + 1];
}
}
return when;
return null;
}

/**
* Removes all alarms
*/
public void removeAlarms(long timeStamp) {
removeAlarm(timeStamp);
additionalNotificationOffset = Long.parseLong(preferences.getString(Constants.ADDITIONAL_NOTIFICATION_KEY, "0"));
if (additionalNotificationOffset != 0) {
removeAdditionalAlarm(timeStamp);
private Set<Long> getAdditionalNotificationOffsets() {
final Set<String> strs = preferences.getStringSet(Constants.ADDITIONAL_NOTIFICATION_KEY, Collections.<String>emptySet());
final Set<Long> results = new HashSet<>();
for (String str : strs) {
results.add(Long.parseLong(str) * DAY_IN_MILLIS);
}
}

/**
* Removes main alarm
*/
private void removeAlarm(long timeStamp) {
Intent intent = new Intent(context, AlarmReceiver.class);

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int) timeStamp, intent,
PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.cancel(pendingIntent);
return results;
}

/**
* Removes additional alarm
* Removes all alarms
*/
private void removeAdditionalAlarm(long timeStamp) {
Intent intent = new Intent(context, AlarmReceiver.class);

int requestCode = (int) timeStamp + REQUEST_CODE_OFFSET;

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
public void removeAlarms(Person person) {
if (pendingIntents.containsKey(person)) {
for (PendingIntent pendingIntent : pendingIntents.get(person)) {
alarmManager.cancel(pendingIntent);
}

alarmManager.cancel(pendingIntent);
pendingIntents.remove(person);
}
}

/**
* Set up time for triggering alarm
*/
private long setupCalendarYear(Person person, long offset) {
long now = Calendar.getInstance().getTimeInMillis();
long notificationTime = preferences.getLong(Constants.NOTIFICATION_TIME_KEY, defaultNotificationTime);
Calendar notificationTimeCalendar = Calendar.getInstance();
final long now = Calendar.getInstance().getTimeInMillis();
final long notificationTime = preferences.getLong(Constants.NOTIFICATION_TIME_KEY, defaultNotificationTime);
final Calendar notificationTimeCalendar = Calendar.getInstance();
notificationTimeCalendar.setTimeInMillis(notificationTime);

int hour = notificationTimeCalendar.get(Calendar.HOUR_OF_DAY);
int minutes = notificationTimeCalendar.get(Calendar.MINUTE);
final int hour = notificationTimeCalendar.get(Calendar.HOUR_OF_DAY);
final int minutes = notificationTimeCalendar.get(Calendar.MINUTE);

long date = person.getDate() - offset;
int year = Calendar.getInstance().get(Calendar.YEAR);
final long date = person.getDate() - offset;
final int year = Calendar.getInstance().get(Calendar.YEAR);

Calendar calendar = Calendar.getInstance();
final Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(date);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.HOUR_OF_DAY, hour);
Expand Down
17 changes: 8 additions & 9 deletions app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,14 @@ private void createNotificationChannel(Context context) {
* Builds default notification
*/
private NotificationCompat.Builder buildNotification(Context context, String title, String text) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setSmallIcon(R.drawable.ic_notification);
builder.setColor(context.getResources().getColor(R.color.accent_green_200));
builder.setCategory(NotificationCompat.CATEGORY_EVENT);
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
return builder;
return new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.ic_notification)
.setColor(context.getResources().getColor(R.color.accent_green_200))
.setCategory(NotificationCompat.CATEGORY_EVENT)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class DbQueryManager {
this.database = database;
}

//FIXME: make this work with IDs instead of timestamps
public Person getPerson(long timeStamp) {

Cursor cursor = database.query(DbHelper.DB_PERSONS, null, DbHelper.SELECTION_TIME_STAMP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private Separator getSeparator(Person person) {
public void removePersonDialog(final int location) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);

Person person = (Person) adapter.getItem(location);
final Person person = (Person) adapter.getItem(location);
final long timeStamp = person.getTimeStamp();

builder.setMessage(getString(R.string.delete_record_text) + person.getName() + "?");
Expand Down Expand Up @@ -266,7 +266,7 @@ public void onViewAttachedToWindow(View v) {
@Override
public void onViewDetachedFromWindow(View v) {
if (isRemoved[0]) {
alarmHelper.removeAlarms(timeStamp);
alarmHelper.removeAlarms(person);
activity.dbHelper.removeRecord(timeStamp);
deletingPersonListener.onPersonDeleted(timeStamp);
}
Expand Down
Loading