From 97cc92696ca2ba58061e77f67057b787cc6f1576 Mon Sep 17 00:00:00 2001 From: Cristi Libotean Date: Sun, 4 Mar 2018 11:08:00 +0200 Subject: [PATCH 1/5] Fixed problem with duplicated accounts getting created. When initially importing contacts you could end up with duplicated accounts if you had more than one google account you were importing from. --- .../main/java/com/djonique/birdays/backup/RecoverHelper.java | 1 + .../main/java/com/djonique/birdays/utils/ContactsHelper.java | 1 + gradle.properties | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/djonique/birdays/backup/RecoverHelper.java b/app/src/main/java/com/djonique/birdays/backup/RecoverHelper.java index cd9310c..48353c9 100644 --- a/app/src/main/java/com/djonique/birdays/backup/RecoverHelper.java +++ b/app/src/main/java/com/djonique/birdays/backup/RecoverHelper.java @@ -133,6 +133,7 @@ private void parseXml(XmlPullParser parser) { if (name.equals(PERSON) && person != null) { if (!Utils.isPersonAlreadyInDb(person, dbPersons)) { dbHelper.addRecord(person); + dbPersons.add(person); alarmHelper.setAlarms(person); } } diff --git a/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java b/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java index aa86cf9..a083bd0 100644 --- a/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java +++ b/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java @@ -200,6 +200,7 @@ protected Void doInBackground(Void... params) { for (Person person : contacts) { if (!Utils.isPersonAlreadyInDb(person, dbPersons)) { dbHelper.addRecord(person); + dbPersons.add(person); alarmHelper.setAlarms(person); } } diff --git a/gradle.properties b/gradle.properties index 1d3591c..16b3163 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,6 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true + +android.injected.build.model.only.versioned=3 From b90a9b5dee4403855ed5f20e12ff48e8d487f778 Mon Sep 17 00:00:00 2001 From: Cristi Libotean Date: Sun, 4 Mar 2018 11:12:23 +0200 Subject: [PATCH 2/5] Reworked the way separators are handled. Added ability to show the age the person is turning to (or has turned to) this year. --- .../birdays/activities/DetailActivity.java | 6 +- .../birdays/adapters/AllFragmentAdapter.java | 89 +++---------------- .../djonique/birdays/adapters/ItemType.java | 7 ++ .../birdays/fragments/AllFragment.java | 77 +--------------- .../djonique/birdays/models/DisplayedAge.java | 7 ++ .../com/djonique/birdays/models/Person.java | 3 +- .../djonique/birdays/models/Separator.java | 14 --- .../com/djonique/birdays/utils/Utils.java | 44 +++++++++ app/src/main/res/values-en/strings.xml | 1 + app/src/main/res/values/strings.xml | 6 +- app/src/main/res/xml/preferences.xml | 2 +- 11 files changed, 88 insertions(+), 168 deletions(-) create mode 100644 app/src/main/java/com/djonique/birdays/adapters/ItemType.java create mode 100644 app/src/main/java/com/djonique/birdays/models/DisplayedAge.java diff --git a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java index 023cc08..45964cb 100644 --- a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java +++ b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java @@ -46,6 +46,7 @@ import com.djonique.birdays.adapters.FamousFragmentAdapter; import com.djonique.birdays.alarm.AlarmHelper; import com.djonique.birdays.database.DbHelper; +import com.djonique.birdays.models.DisplayedAge; import com.djonique.birdays.models.Person; import com.djonique.birdays.utils.Constants; import com.djonique.birdays.utils.Utils; @@ -103,7 +104,8 @@ public class DetailActivity extends AppCompatActivity { private DbHelper dbHelper; private Person person; private long timeStamp, date; - private String phoneNumber, email, displayedAge; + private String phoneNumber, email; + private DisplayedAge displayedAge; private boolean yearUnknown; @Override @@ -114,7 +116,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); boolean adEnabled = preferences.getBoolean(getString(R.string.ad_interstitial_key), true); - displayedAge = preferences.getString(Constants.DISPLAYED_AGE_KEY, "0"); + displayedAge = Utils.getDisplayedAge(preferences.getString(Constants.DISPLAYED_AGE_KEY, DisplayedAge.CURRENT.name())); /* * Interstitial doesn't work on Android API 26+ diff --git a/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java b/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java index cc294ed..5a1ab82 100644 --- a/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java +++ b/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java @@ -31,6 +31,7 @@ import com.djonique.birdays.activities.DetailActivity; import com.djonique.birdays.activities.MainActivity; import com.djonique.birdays.fragments.AllFragment; +import com.djonique.birdays.models.DisplayedAge; import com.djonique.birdays.models.Item; import com.djonique.birdays.models.Person; import com.djonique.birdays.models.Separator; @@ -41,27 +42,12 @@ import java.util.List; public class AllFragmentAdapter extends RecyclerView.Adapter { - - private static final int TYPE_PERSON = 0; - private static final int TYPE_SEPARATOR = 1; - - public boolean containsSeparatorJanuary; - public boolean containsSeparatorFebruary; - public boolean containsSeparatorMarch; - public boolean containsSeparatorApril; - public boolean containsSeparatorMay; - public boolean containsSeparatorJune; - public boolean containsSeparatorJuly; - public boolean containsSeparatorAugust; - public boolean containsSeparatorSeptember; - public boolean containsSeparatorOctober; - public boolean containsSeparatorNovember; - public boolean containsSeparatorDecember; + public boolean[] containedSeparators = new boolean[12]; //all months private List items; private AllFragment allFragment; private Context context; - private String displayedAge; + private DisplayedAge displayedAge; public AllFragmentAdapter(AllFragment allFragment) { this.allFragment = allFragment; @@ -117,57 +103,20 @@ public void removePerson(int location) { } private void checkSeparator(int type) { - switch (type) { - case Separator.TYPE_JANUARY: - containsSeparatorJanuary = false; - break; - case Separator.TYPE_FEBRUARY: - containsSeparatorFebruary = false; - break; - case Separator.TYPE_MARCH: - containsSeparatorMarch = false; - break; - case Separator.TYPE_APRIL: - containsSeparatorApril = false; - break; - case Separator.TYPE_MAY: - containsSeparatorMay = false; - break; - case Separator.TYPE_JUNE: - containsSeparatorJune = false; - break; - case Separator.TYPE_JULY: - containsSeparatorJuly = false; - break; - case Separator.TYPE_AUGUST: - containsSeparatorAugust = false; - break; - case Separator.TYPE_SEPTEMBER: - containsSeparatorSeptember = false; - break; - case Separator.TYPE_OCTOBER: - containsSeparatorOctober = false; - break; - case Separator.TYPE_NOVEMBER: - containsSeparatorNovember = false; - break; - case Separator.TYPE_DECEMBER: - containsSeparatorDecember = false; - break; - } + containedSeparators[type] = false; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { context = parent.getContext(); - displayedAge = PreferenceManager.getDefaultSharedPreferences(context) - .getString(Constants.DISPLAYED_AGE_KEY, "0"); - switch (viewType) { - case TYPE_PERSON: + displayedAge = Utils.getDisplayedAge(PreferenceManager.getDefaultSharedPreferences(context) + .getString(Constants.DISPLAYED_AGE_KEY, DisplayedAge.CURRENT.name())); + switch (ItemType.values()[viewType]) { + case PERSON: View view = LayoutInflater.from(context).inflate(R.layout.description_list_view, parent, false); return new ListViewHolder(view); - case TYPE_SEPARATOR: + case SEPARATOR: View separator = LayoutInflater.from(context).inflate(R.layout.model_separator, parent, false); return new SeparatorViewHolder(separator); @@ -198,7 +147,7 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { listViewHolder.tvDate.setText(Utils.getDateWithoutYear(date)); } else { listViewHolder.tvAge.setVisibility(View.VISIBLE); - final int age = (displayedAge.equals("0") ? Utils.getCurrentAge(date) : Utils.getFutureAge(date)); + final int age = Utils.getAge(date, displayedAge); listViewHolder.tvDate.setText(Utils.getDate(date)); GradientDrawable ageCircle = (GradientDrawable) listViewHolder.tvAge.getBackground(); ageCircle.setColor(ContextCompat.getColor(context, getAgeCircleColor(age))); @@ -239,19 +188,9 @@ public void removeAllPersons() { if (getItemCount() != 0) { items = new ArrayList<>(); notifyDataSetChanged(); - - containsSeparatorJanuary = false; - containsSeparatorFebruary = false; - containsSeparatorMarch = false; - containsSeparatorApril = false; - containsSeparatorMay = false; - containsSeparatorJune = false; - containsSeparatorJuly = false; - containsSeparatorAugust = false; - containsSeparatorSeptember = false; - containsSeparatorOctober = false; - containsSeparatorNovember = false; - containsSeparatorDecember = false; + for (int i = 0; i < containedSeparators.length; i++) { + containedSeparators[i] = false; + } } } @@ -273,7 +212,7 @@ private int getAgeCircleColor(int age) { @Override public int getItemViewType(int position) { - return getItem(position).isPerson() ? TYPE_PERSON : TYPE_SEPARATOR; + return getItem(position).isPerson() ? ItemType.PERSON.ordinal() : ItemType.SEPARATOR.ordinal(); } private static class ListViewHolder extends RecyclerView.ViewHolder { diff --git a/app/src/main/java/com/djonique/birdays/adapters/ItemType.java b/app/src/main/java/com/djonique/birdays/adapters/ItemType.java new file mode 100644 index 0000000..10ad239 --- /dev/null +++ b/app/src/main/java/com/djonique/birdays/adapters/ItemType.java @@ -0,0 +1,7 @@ +package com.djonique.birdays.adapters; + +public enum ItemType { + PERSON, + SEPARATOR, + ANNIVERSARY, +} diff --git a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java index 07537a3..744855a 100644 --- a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java +++ b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java @@ -152,80 +152,11 @@ public void addAllPersonsFromDb() { } private Separator getSeparator(Person person) { + int month = person.getMonth(); Separator separator = null; - switch (person.getMonth()) { - case Calendar.JANUARY: - if (!adapter.containsSeparatorJanuary) { - adapter.containsSeparatorJanuary = true; - separator = new Separator(Separator.TYPE_JANUARY); - } - break; - case Calendar.FEBRUARY: - if (!adapter.containsSeparatorFebruary) { - adapter.containsSeparatorFebruary = true; - separator = new Separator(Separator.TYPE_FEBRUARY); - } - break; - case Calendar.MARCH: - if (!adapter.containsSeparatorMarch) { - adapter.containsSeparatorMarch = true; - separator = new Separator(Separator.TYPE_MARCH); - } - break; - case Calendar.APRIL: - if (!adapter.containsSeparatorApril) { - adapter.containsSeparatorApril = true; - separator = new Separator(Separator.TYPE_APRIL); - } - break; - case Calendar.MAY: - if (!adapter.containsSeparatorMay) { - adapter.containsSeparatorMay = true; - separator = new Separator(Separator.TYPE_MAY); - } - break; - case Calendar.JUNE: - if (!adapter.containsSeparatorJune) { - adapter.containsSeparatorJune = true; - separator = new Separator(Separator.TYPE_JUNE); - } - break; - case Calendar.JULY: - if (!adapter.containsSeparatorJuly) { - adapter.containsSeparatorJuly = true; - separator = new Separator(Separator.TYPE_JULY); - } - break; - case Calendar.AUGUST: - if (!adapter.containsSeparatorAugust) { - adapter.containsSeparatorAugust = true; - separator = new Separator(Separator.TYPE_AUGUST); - } - break; - case Calendar.SEPTEMBER: - if (!adapter.containsSeparatorSeptember) { - adapter.containsSeparatorSeptember = true; - separator = new Separator(Separator.TYPE_SEPTEMBER); - } - break; - case Calendar.OCTOBER: - if (!adapter.containsSeparatorOctober) { - adapter.containsSeparatorOctober = true; - separator = new Separator(Separator.TYPE_OCTOBER); - } - break; - case Calendar.NOVEMBER: - if (!adapter.containsSeparatorNovember) { - adapter.containsSeparatorNovember = true; - separator = new Separator(Separator.TYPE_NOVEMBER); - } - break; - case Calendar.DECEMBER: - if (!adapter.containsSeparatorDecember) { - adapter.containsSeparatorDecember = true; - separator = new Separator(Separator.TYPE_DECEMBER); - } - break; + if (!adapter.containedSeparators[month]) { + adapter.containedSeparators[month] = true; + separator = new Separator(month); } return separator; } diff --git a/app/src/main/java/com/djonique/birdays/models/DisplayedAge.java b/app/src/main/java/com/djonique/birdays/models/DisplayedAge.java new file mode 100644 index 0000000..b4f0237 --- /dev/null +++ b/app/src/main/java/com/djonique/birdays/models/DisplayedAge.java @@ -0,0 +1,7 @@ +package com.djonique.birdays.models; + +public enum DisplayedAge { + CURRENT, + FUTURE, + TURNING, +} diff --git a/app/src/main/java/com/djonique/birdays/models/Person.java b/app/src/main/java/com/djonique/birdays/models/Person.java index 2d2907a..01d37f8 100644 --- a/app/src/main/java/com/djonique/birdays/models/Person.java +++ b/app/src/main/java/com/djonique/birdays/models/Person.java @@ -137,7 +137,8 @@ public boolean equals(Object obj) { return false; } Person person = (Person) obj; - return name.equalsIgnoreCase(person.getName()); + return this.name.equalsIgnoreCase(person.name) && + this.date == person.date; } @Override diff --git a/app/src/main/java/com/djonique/birdays/models/Separator.java b/app/src/main/java/com/djonique/birdays/models/Separator.java index 5eb24f1..f87bbe9 100644 --- a/app/src/main/java/com/djonique/birdays/models/Separator.java +++ b/app/src/main/java/com/djonique/birdays/models/Separator.java @@ -17,20 +17,6 @@ package com.djonique.birdays.models; public class Separator implements Item { - - public static final int TYPE_JANUARY = 0; - public static final int TYPE_FEBRUARY = 1; - public static final int TYPE_MARCH = 2; - public static final int TYPE_APRIL = 3; - public static final int TYPE_MAY = 4; - public static final int TYPE_JUNE = 5; - public static final int TYPE_JULY = 6; - public static final int TYPE_AUGUST = 7; - public static final int TYPE_SEPTEMBER = 8; - public static final int TYPE_OCTOBER = 9; - public static final int TYPE_NOVEMBER = 10; - public static final int TYPE_DECEMBER = 11; - private int type; public Separator(int type) { diff --git a/app/src/main/java/com/djonique/birdays/utils/Utils.java b/app/src/main/java/com/djonique/birdays/utils/Utils.java index db31ffe..3b3eafb 100644 --- a/app/src/main/java/com/djonique/birdays/utils/Utils.java +++ b/app/src/main/java/com/djonique/birdays/utils/Utils.java @@ -29,6 +29,7 @@ import android.widget.Toast; import com.djonique.birdays.R; +import com.djonique.birdays.models.DisplayedAge; import com.djonique.birdays.models.Person; import com.djonique.birdays.widget.WidgetProvider; @@ -89,6 +90,44 @@ public static long getTimeOffset() { return TimeZone.getDefault().getOffset(today.getTimeInMillis()); } + /** + * Determines the way the age should be displayed. + * @param candidate + * @return + */ + public static DisplayedAge getDisplayedAge(String candidate) { + //need to support both indexes and strings + DisplayedAge[] values = DisplayedAge.values(); + for (DisplayedAge value : values) { + if (candidate.equals(value.name())) { + return value; + } + } + try { + //0 current, 1 future + Integer index = Integer.parseInt(candidate); + return values[index]; + } + catch (NumberFormatException nfex) + { + //pass + } + + return DisplayedAge.CURRENT; + } + + public static int getAge(long date, DisplayedAge displayedAge) { + switch (displayedAge) { + default: + case CURRENT: + return getCurrentAge(date); + case TURNING: + return getTurningAge(date); + case FUTURE: + return getFutureAge(date); + } + } + /** * Returns current age */ @@ -104,6 +143,11 @@ public static int getCurrentAge(long date) { return age; } + public static int getTurningAge(long date) { + dayOfBirthday.setTimeInMillis(date); + return getYear(today) - getYear(dayOfBirthday); + } + /** * Returns future age */ diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 1290070..a955b50 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -163,6 +163,7 @@ Current + Turning/Turned Future diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0bf2fb4..86c0310 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -203,12 +203,14 @@ Current + Turning/Turned Future - 0 - 1 + CURRENT + TURNING + FUTURE You must restart an app for these changes to take effect diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 44d8098..afe6429 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -81,7 +81,7 @@ android:summary="%s" android:title="@string/start_page" /> Date: Sun, 4 Mar 2018 14:03:26 +0200 Subject: [PATCH 3/5] Updated romanian translation. --- app/src/main/res/values-ro/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 78be459..3ef0123 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -163,6 +163,7 @@ Actuală + Împlinită anul acesta Viitor From d5e904134f18a1ad05c4791566257f4412209785 Mon Sep 17 00:00:00 2001 From: Cristi Libotean Date: Fri, 9 Mar 2018 15:54:37 +0200 Subject: [PATCH 4/5] Added ability to add multiple notifications beforehand for the same person. Instead of being able to only add a single extra notification (either 1 day, 2 days, 3 days, 1 week or 2 weeks beforehand) you can add any/all of these. --- .../birdays/activities/DetailActivity.java | 2 +- .../birdays/activities/EditActivity.java | 2 +- .../birdays/activities/SettingsActivity.java | 57 +++++--- .../djonique/birdays/alarm/AlarmHelper.java | 132 +++++++++--------- .../djonique/birdays/alarm/AlarmReceiver.java | 17 ++- .../birdays/database/DbQueryManager.java | 1 + .../birdays/fragments/AllFragment.java | 4 +- .../com/djonique/birdays/utils/Constants.java | 2 +- app/src/main/res/values-be/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-en/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fil/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-hu/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-kab/strings.xml | 2 +- app/src/main/res/values-kk/strings.xml | 2 +- app/src/main/res/values-nb/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-tr/strings.xml | 2 +- app/src/main/res/values-uk/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values-zh/strings.xml | 2 +- app/src/main/res/values/strings.xml | 17 ++- app/src/main/res/xml/preferences.xml | 6 +- 32 files changed, 156 insertions(+), 130 deletions(-) diff --git a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java index 45964cb..4c0f6e8 100644 --- a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java +++ b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java @@ -286,7 +286,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(); diff --git a/app/src/main/java/com/djonique/birdays/activities/EditActivity.java b/app/src/main/java/com/djonique/birdays/activities/EditActivity.java index 27f5ec6..20c0da5 100644 --- a/app/src/main/java/com/djonique/birdays/activities/EditActivity.java +++ b/app/src/main/java/com/djonique/birdays/activities/EditActivity.java @@ -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); } diff --git a/app/src/main/java/com/djonique/birdays/activities/SettingsActivity.java b/app/src/main/java/com/djonique/birdays/activities/SettingsActivity.java index 86035a9..7d45761 100644 --- a/app/src/main/java/com/djonique/birdays/activities/SettingsActivity.java +++ b/app/src/main/java/com/djonique/birdays/activities/SettingsActivity.java @@ -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; @@ -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 { @@ -182,6 +186,28 @@ public static class BirdaysPreferenceFragment extends PreferenceFragment private SharedPreferences preferences; + private String getAdditionalNotificationsSelectedValues(MultiSelectListPreference preference) { + final Map 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); @@ -189,14 +215,18 @@ public void onCreate(Bundle savedInstanceState) { 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) newValue); + preference.setSummary(getAdditionalNotificationsSelectedValues(preference)); return true; } }); @@ -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); } } } @@ -452,15 +480,13 @@ 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 persons) { @@ -468,7 +494,7 @@ private void restartAlarms(final AlarmHelper alarmHelper, final List per @Override public void run() { for (Person person : persons) { - alarmHelper.removeAlarms(person.getTimeStamp()); + alarmHelper.removeAlarms(person); alarmHelper.setAlarms(person); } } @@ -476,8 +502,7 @@ public void run() { } 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); diff --git a/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java b/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java index 8287293..c879eae 100644 --- a/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java +++ b/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java @@ -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> pendingIntents = new HashMap<>(); + final private Context context; + final private AlarmManager alarmManager; + final private SharedPreferences preferences; public AlarmHelper(Context context) { this.context = context; @@ -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 additionalNotificationOffsets = getAdditionalNotificationOffsets(); + if ((additionalNotificationOffsets != null) && (!additionalNotificationOffsets.isEmpty())) { + setAdditionalAlarms(person); } } catch (SecurityException e) { if (context instanceof Activity) { @@ -71,6 +75,14 @@ public void run() { } } + private void addPendingIntent(Person person, PendingIntent pendingIntent) { + if (!pendingIntents.containsKey(person)) { + pendingIntents.put(person, new HashSet()); + } + + pendingIntents.get(person).add(pendingIntent); + } + /** * Set up main alarm */ @@ -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 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); + } } /** @@ -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 getAdditionalNotificationOffsets() { + final Set strs = preferences.getStringSet(Constants.ADDITIONAL_NOTIFICATION_KEY, Collections.emptySet()); + final Set 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); diff --git a/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java b/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java index 660553c..a594943 100644 --- a/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java +++ b/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java @@ -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); } /** diff --git a/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java b/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java index 2a8966b..2e8507b 100644 --- a/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java +++ b/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java @@ -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, diff --git a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java index 744855a..0dccd68 100644 --- a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java +++ b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java @@ -164,7 +164,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() + "?"); @@ -197,7 +197,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); } diff --git a/app/src/main/java/com/djonique/birdays/utils/Constants.java b/app/src/main/java/com/djonique/birdays/utils/Constants.java index 39c08d4..98c9f44 100644 --- a/app/src/main/java/com/djonique/birdays/utils/Constants.java +++ b/app/src/main/java/com/djonique/birdays/utils/Constants.java @@ -35,7 +35,7 @@ public interface Constants { // Settings keys String NOTIFICATIONS_KEY = "notifications_key"; String NOTIFICATION_TIME_KEY = "notification_time_key"; - String ADDITIONAL_NOTIFICATION_KEY = "additional_notification_key"; + String ADDITIONAL_NOTIFICATION_KEY = "additional_notification_key_multi"; String RINGTONE_KEY = "ringtone_key"; String NIGHT_MODE_KEY = "night_mode_key"; String START_PAGE = "start_page_key"; diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index b81ca15..e30b886 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -111,9 +111,9 @@ Разрешить приложению присылать уведомления о предстоящих днях рождения Время уведомления Дополнительное уведомление + Никогда - Никогда За 1 день За 2 дня За 3 дня diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c2e4216..bad539c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -111,9 +111,9 @@ Der App erlauben, Benachrichtigungen von anstehenden Geburtstagen zu senden Zeitpunkt der Benachrichtigung Weitere Benachrichtigung + Nie - Nie 1 Tag vorher 2 Tage vorher 3 Tage vorher diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 1d46df4..a8c4dd4 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -111,9 +111,9 @@ Αφήστε την εφαρμογή να στείλει ειδοποιήσεις για τα επερχόμενα γενέθλια Χρόνος ειδοποίησης Πρόσθετη ειδοποίηση + Ποτέ - Ποτέ Mία ηέρα πριν Δύο μέρες πριν Τρεις ημέρες πριν diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index a955b50..e1a0865 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -110,10 +110,10 @@ Notifications Allow the app to send notifications of upcoming birthdays Notification time - Additional notification + Additional notifications + Never - Never 1 day before 2 days before 3 days before diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d78dae9..272c432 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -111,9 +111,9 @@ Permitir que la app te envíe notificaciones de próximos cumpleaños Tiempo de la notificación Notificaciones adicionales + Nunca - Nunca 1 día antes 2 días antes 3 días antes diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 616b985..88252b4 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -111,9 +111,9 @@ Hayaan ang app na mag padala ng notipikasyon ng nalalapit na kaarawan Oras ng notipikasyon Karagdagang notipikasyon + Hindi kailanman - Hindi kailanman Bago ang 1 araw Bago ang 2 na araw Bago ang 3 na araw diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 48bf8ef..ecd9948 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -111,9 +111,9 @@ Permettre l’application envoyer des notifications d’anniversaires à venir Heure de notification Notification supplémentaire + Jamais - Jamais 1 jour avant 2 jours avant 3 jours avant diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 28d38da..0afdc5d 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -111,9 +111,9 @@ Engedélyezze, hogy az alkalmazás küldjön értesítéseket a következő születésnapokról Értesítés idő Kiegészítő értesítés + Soha - Soha 1 nappal előtte 2 nappal előtte 3 nappal előtte diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 4c74cd0..6c9573a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -111,9 +111,9 @@ Izinkan aplikasi mengirim notifikasi ulang tahun yang akan datang Waktu notifikasi Notifikasi tambahan + Tidak pernah - Tidak pernah Sehari sebelumnya 2 hari sebelumnya 3 hari sebelumnya diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 9a84e0f..e264a13 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -111,9 +111,9 @@ Consentire all\'app di inviare notifiche dei compleanni imminenti Ora di notifica Ulteriori notifiche + Mai - Mai 1 giorno prima 2 giorni prima 3 giorni prima diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 822eaf8..2c15b7f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -111,9 +111,9 @@ アプリが誕生日の通知を送信することを許可します 通知時間 追加通知 + 決して - 決して 1日前 2日前 3日前 diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index af7532f..22ecd57 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -111,9 +111,9 @@ Sireg asnas akken ad yazen ilɣa n imulliyen i d-iteddun Akud n wulɣu Ilɣa nniḍen + Wurǧin - Wurǧin Send 1 n wass Send 2 n wussan Send 3 n wussan diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index b81ca15..e30b886 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -111,9 +111,9 @@ Разрешить приложению присылать уведомления о предстоящих днях рождения Время уведомления Дополнительное уведомление + Никогда - Никогда За 1 день За 2 дня За 3 дня diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 1b4a0fa..4ce3382 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -111,9 +111,9 @@ Tillat appen å sende varslinger om kommende bursdager Varslingsklokkeslett Ytterlig varsling + Aldri - Aldri 1 dag før 2 dager før 3 dager før diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4d120fa..3604eab 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -111,9 +111,9 @@ Sta de toepassing toe om toekomstige verjaardagsmeldingen te verzenden Meldingstijd Aanvullende notificatie + Nooit - Nooit 1dag ervoor 2 dagen ervoor 3 dagen ervoor diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 34c549e..553e86d 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -111,9 +111,9 @@ Permitir que o aplicativo envie notificações de aniversários futuros Hora de notificação Notificação adicional + Nunca - Nunca 1 dia antes 2 dias antes 3 dias antes diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 3ef0123..865b453 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -111,9 +111,9 @@ Permite aplicației să trimită notificări pentru viitoarele aniversări Timp notificare Notificări suplimentare + Niciodată - Niciodată Cu o zi înainte Cu 2 zile înainte Cu 3 zile înainte diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b81ca15..e30b886 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -111,9 +111,9 @@ Разрешить приложению присылать уведомления о предстоящих днях рождения Время уведомления Дополнительное уведомление + Никогда - Никогда За 1 день За 2 дня За 3 дня diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d771a92..0d049e0 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -111,9 +111,9 @@ Uygulamaya yaklaşan doğum günleri bildirimlerini göndermeye izin ver Bildirim zamanı Ek bildirim + Hiçbir zaman - Hiçbir zaman 1 gün önce 2 gün önce 3 gün önce diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 99d135d..933b76d 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -111,9 +111,9 @@ Дозволити застосунку присилати сповіщення про майбутні дні народження Час сповіщення Додаткове сповіщення + Ніколи - Ніколи За 1 день За 2 дні За 3 дні diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 0fbd465..6ff823c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -111,9 +111,9 @@ 允許應用程式發送即將到來的生日通知 通知時間 附加通知 + 從來沒有 - 從來沒有 1天前 2天前 3天前 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index aa7cbc8..e0b156f 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -111,9 +111,9 @@ 允许应用程序发送即将到来的生日通知 通知时间 附加通知 + 从不 - 从不 1天前 2天前 3天前 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86c0310..cc4d721 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,7 +108,7 @@ notifications_key notification_time_key - additional_notification_key + additional_notification_key_multi ringtone_key help_key import_contacts_key @@ -135,10 +135,10 @@ Allow the app to send notifications of upcoming birthdays Notification time 645703200000 - Additional notification + Additional notifications + Never - Never 1 day before 2 days before 3 days before @@ -147,12 +147,11 @@ - 0 - 86400000 - 172800000 - 259200000 - 604800000 - 1209600000 + 1 + 2 + 3 + 7 + 14 diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index afe6429..83d2003 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -30,13 +30,13 @@ android:dependency="@string/notifications_key" android:key="@string/notification_time_key" android:title="@string/notifications_time" /> - Date: Wed, 14 Mar 2018 11:10:12 +0200 Subject: [PATCH 5/5] Added ability to notify about anniversaries, custom anniversaries as well as birthdays. --- .../birdays/activities/DetailActivity.java | 19 ++- .../birdays/adapters/AllFragmentAdapter.java | 85 ++++------ .../birdays/adapters/PagerAdapter.java | 2 +- .../djonique/birdays/alarm/AlarmHelper.java | 2 + .../djonique/birdays/alarm/AlarmReceiver.java | 13 +- .../djonique/birdays/database/DbHelper.java | 27 ++- .../birdays/database/DbQueryManager.java | 156 ++++++------------ .../birdays/fragments/AllFragment.java | 118 ++++--------- .../birdays/fragments/MonthFragment.java | 3 +- .../birdays/models/AnniversaryType.java | 6 + .../com/djonique/birdays/models/Item.java | 5 +- .../{adapters => models}/ItemType.java | 2 +- .../com/djonique/birdays/models/Person.java | 116 ++++++++----- .../djonique/birdays/models/Separator.java | 26 ++- .../com/djonique/birdays/utils/Constants.java | 1 + .../birdays/utils/ContactsHelper.java | 47 ++++-- app/src/main/res/layout/activity_detail.xml | 3 +- .../main/res/layout/description_list_view.xml | 19 ++- app/src/main/res/values-en/strings.xml | 4 +- app/src/main/res/values-ro/strings.xml | 6 +- app/src/main/res/values/strings.xml | 6 +- 21 files changed, 347 insertions(+), 319 deletions(-) create mode 100644 app/src/main/java/com/djonique/birdays/models/AnniversaryType.java rename app/src/main/java/com/djonique/birdays/{adapters => models}/ItemType.java (64%) diff --git a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java index 4c0f6e8..cad4baf 100644 --- a/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java +++ b/app/src/main/java/com/djonique/birdays/activities/DetailActivity.java @@ -46,6 +46,7 @@ import com.djonique.birdays.adapters.FamousFragmentAdapter; import com.djonique.birdays.alarm.AlarmHelper; import com.djonique.birdays.database.DbHelper; +import com.djonique.birdays.models.AnniversaryType; import com.djonique.birdays.models.DisplayedAge; import com.djonique.birdays.models.Person; import com.djonique.birdays.utils.Constants; @@ -83,10 +84,14 @@ public class DetailActivity extends AppCompatActivity { RelativeLayout rlDaysSinceBirthday; @BindView(R.id.textview_detail_since) TextView tvDaysSinceBirthday; + @BindView(R.id.textview_detail_label) + TextView tvAnniversaryLabel; @BindView(R.id.imageview_detail_zodiac) ImageView ivZodiacSign; @BindView(R.id.textview_detail_zodiac) TextView tvZodiacSign; + @BindView(R.id.textview_detail_zodiac_label) + TextView tvZodiacSignLabel; @BindView(R.id.cardview_detail_info) CardView cardViewInfo; @BindView(R.id.relativelayout_detail_phone) @@ -204,6 +209,7 @@ private void setupUI() { setSeasonImage(); tvDaysLeft.setText(Utils.daysLeft(this, date)); + tvAnniversaryLabel.setText(person.getAnniversaryLabel()); if (yearUnknown) { tvDate.setText(Utils.getDateWithoutYear(date)); @@ -215,9 +221,16 @@ private void setupUI() { tvDaysSinceBirthday.setText(Utils.daysSinceBirthday(date)); } - int zodiacId = Utils.getZodiacId(date); - tvZodiacSign.setText(getString(zodiacId)); - ivZodiacSign.setImageResource(Utils.getZodiacImage(zodiacId)); + if (person.getAnniversaryType() == AnniversaryType.BIRTHDAY) { + int zodiacId = Utils.getZodiacId(date); + tvZodiacSign.setText(getString(zodiacId)); + ivZodiacSign.setImageResource(Utils.getZodiacImage(zodiacId)); + } + else { + tvZodiacSign.setVisibility(View.GONE); + tvZodiacSignLabel.setVisibility(View.GONE); + ivZodiacSign.setVisibility(View.GONE); + } if (isEmpty(phoneNumber) && isEmpty(email)) cardViewInfo.setVisibility(View.GONE); diff --git a/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java b/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java index 5a1ab82..029c94a 100644 --- a/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java +++ b/app/src/main/java/com/djonique/birdays/adapters/AllFragmentAdapter.java @@ -33,6 +33,7 @@ import com.djonique.birdays.fragments.AllFragment; import com.djonique.birdays.models.DisplayedAge; import com.djonique.birdays.models.Item; +import com.djonique.birdays.models.ItemType; import com.djonique.birdays.models.Person; import com.djonique.birdays.models.Separator; import com.djonique.birdays.utils.Constants; @@ -42,8 +43,6 @@ import java.util.List; public class AllFragmentAdapter extends RecyclerView.Adapter { - public boolean[] containedSeparators = new boolean[12]; //all months - private List items; private AllFragment allFragment; private Context context; @@ -63,49 +62,36 @@ public Item getItem(int position) { } public void addItem(Item item) { - items.add(item); - notifyItemInserted(getItemCount() - 1); - } + final Item prev = items.size() > 0 ? getItem(items.size() - 1) : null; + //first item or the item before this one isn't within the same month + if ((prev == null) || (prev.getMonth() != item.getMonth())) { + items.add(new Separator(item.getMonth())); + notifyItemInserted(items.size() - 1); + } - public void addItem(int location, Item item) { - items.add(location, item); - notifyItemInserted(location); + items.add(item); + notifyItemInserted(items.size() - 1); } public void removePerson(int location) { - if (location >= 0 && location < getItemCount()) { + if ((location >= 0) && (location < items.size())) { + final Item item = getItem(location); + final Item prev = location > 0 ? getItem(location - 1) : null; + final Item next = location < items.size() - 1 ? getItem(location + 1) : null; items.remove(location); notifyItemRemoved(location); - - if (location - 1 >= 0 && !getItem(location - 1).isPerson()) { - - if (location != getItemCount() && !getItem(location).isPerson() && !getItem(location - 1).isPerson()) { - Separator separator = (Separator) getItem(location - 1); - checkSeparator(separator.getType()); - items.remove(location - 1); - notifyItemRemoved(location - 1); - - } else if (location == getItemCount() && !getItem(location - 1).isPerson()) { - Separator separator = (Separator) getItem(location - 1); - checkSeparator(separator.getType()); + //if the previous item is a separator + if ((prev != null) && (prev.isSeparator())) { + //check the next item, if it doesn't exist then we need to remove the separator as well + //if it exists but it's in a different month we need to remove the separator as well + if ((next == null) || (next.getMonth() != item.getMonth())) { items.remove(location - 1); notifyItemRemoved(location - 1); } - - } else if (getItemCount() - 1 >= 0 && !getItem(getItemCount() - 1).isPerson()) { - Separator separator = (Separator) getItem(getItemCount() - 1); - checkSeparator(separator.getType()); - int locationTemp = getItemCount() - 1; - items.remove(locationTemp); - notifyItemRemoved(locationTemp); } } } - private void checkSeparator(int type) { - containedSeparators[type] = false; - } - @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { context = parent.getContext(); @@ -113,12 +99,10 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType .getString(Constants.DISPLAYED_AGE_KEY, DisplayedAge.CURRENT.name())); switch (ItemType.values()[viewType]) { case PERSON: - View view = LayoutInflater.from(context).inflate(R.layout.description_list_view, - parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.description_list_view, parent, false); return new ListViewHolder(view); case SEPARATOR: - View separator = LayoutInflater.from(context).inflate(R.layout.model_separator, - parent, false); + View separator = LayoutInflater.from(context).inflate(R.layout.model_separator, parent, false); return new SeparatorViewHolder(separator); default: return null; @@ -127,21 +111,22 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - - Item item = getItem(position); + Item item = items.get(position); String[] months = holder.itemView.getResources().getStringArray(R.array.months); - if (item.isPerson()) { + if (!item.isSeparator()) { holder.itemView.setEnabled(true); - View itemView = holder.itemView; + final View itemView = holder.itemView; final Person person = ((Person) item); final ListViewHolder listViewHolder = ((ListViewHolder) holder); listViewHolder.tvName.setText(person.getName()); - long date = person.getDate(); + final long date = person.getDate(); + listViewHolder.tvLabel.setVisibility(View.VISIBLE); + listViewHolder.tvLabel.setText(person.getAnniversaryLabel()); if (person.isYearUnknown()) { listViewHolder.tvAge.setVisibility(View.GONE); listViewHolder.tvDate.setText(Utils.getDateWithoutYear(date)); @@ -165,17 +150,15 @@ public boolean onLongClick(View v) { itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - allFragment.startActivity(new Intent(context, DetailActivity.class). - putExtra(Constants.TIME_STAMP, person.getTimeStamp())); + allFragment.startActivity(new Intent(context, DetailActivity.class). putExtra(Constants.TIME_STAMP, person.getTimeStamp())); if (context instanceof MainActivity) { - ((MainActivity) context).overridePendingTransition(R.anim.activity_secondary_in, - R.anim.activity_primary_out); + ((MainActivity) context).overridePendingTransition(R.anim.activity_secondary_in, R.anim.activity_primary_out); } } }); } else { Separator separator = ((Separator) item); - ((SeparatorViewHolder) holder).separatorView.setText(months[separator.getType()]); + ((SeparatorViewHolder) holder).separatorView.setText(months[separator.getMonth()]); } } @@ -188,9 +171,6 @@ public void removeAllPersons() { if (getItemCount() != 0) { items = new ArrayList<>(); notifyDataSetChanged(); - for (int i = 0; i < containedSeparators.length; i++) { - containedSeparators[i] = false; - } } } @@ -212,22 +192,23 @@ private int getAgeCircleColor(int age) { @Override public int getItemViewType(int position) { - return getItem(position).isPerson() ? ItemType.PERSON.ordinal() : ItemType.SEPARATOR.ordinal(); + return getItem(position).getItemType().ordinal(); } private static class ListViewHolder extends RecyclerView.ViewHolder { - TextView tvName, tvDate, tvAge; + private final TextView tvName, tvDate, tvLabel, tvAge; ListViewHolder(View itemView) { super(itemView); tvName = itemView.findViewById(R.id.textview_all_name); tvDate = itemView.findViewById(R.id.textview_all_date); + tvLabel = itemView.findViewById(R.id.textview_all_label); tvAge = itemView.findViewById(R.id.textview_all_age); } } private class SeparatorViewHolder extends RecyclerView.ViewHolder { - TextView separatorView; + final TextView separatorView; SeparatorViewHolder(View itemView) { super(itemView); diff --git a/app/src/main/java/com/djonique/birdays/adapters/PagerAdapter.java b/app/src/main/java/com/djonique/birdays/adapters/PagerAdapter.java index 6e476f8..e1cf7e4 100644 --- a/app/src/main/java/com/djonique/birdays/adapters/PagerAdapter.java +++ b/app/src/main/java/com/djonique/birdays/adapters/PagerAdapter.java @@ -115,7 +115,7 @@ public void addPersonsFromDb() { monthFragment.addMonthPersonsFromDb(); } if (allFragment != null) { - allFragment.addAllPersonsFromDb(); + allFragment.refreshAllPersonsFromDb(); } } diff --git a/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java b/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java index c879eae..9fc6b63 100644 --- a/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java +++ b/app/src/main/java/com/djonique/birdays/alarm/AlarmHelper.java @@ -89,6 +89,7 @@ private void addPendingIntent(Person person, PendingIntent pendingIntent) { private void setAlarm(Person person) { Intent intent = new Intent(context, AlarmReceiver.class); intent.putExtra(Constants.NAME, person.getName()); + intent.putExtra(Constants.ANNIVERSARY_LABEL, person.getAnniversaryLabel()); intent.putExtra(Constants.WHEN, context.getString(R.string.today)); intent.putExtra(Constants.TIME_STAMP, person.getTimeStamp()); @@ -111,6 +112,7 @@ private void setAdditionalAlarms(Person person) { Intent intent = new Intent(context, AlarmReceiver.class); intent.putExtra(Constants.NAME, person.getName()); intent.putExtra(Constants.WHEN, setWhen(additionalNotificationOffset)); + intent.putExtra(Constants.ANNIVERSARY_LABEL, person.getAnniversaryLabel()); intent.putExtra(Constants.TIME_STAMP, person.getTimeStamp()); long triggerAtMillis = setupCalendarYear(person, additionalNotificationOffset); diff --git a/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java b/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java index a594943..5eaafbd 100644 --- a/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java +++ b/app/src/main/java/com/djonique/birdays/alarm/AlarmReceiver.java @@ -51,9 +51,10 @@ public void onReceive(Context context, Intent intent) { preferences = PreferenceManager.getDefaultSharedPreferences(context); // Extras from intent - String name = intent.getStringExtra(Constants.NAME); - String when = intent.getStringExtra(Constants.WHEN); - long timeStamp = intent.getLongExtra(Constants.TIME_STAMP, 0); + final String name = intent.getStringExtra(Constants.NAME); + final String when = intent.getStringExtra(Constants.WHEN); + final String label = intent.getStringExtra(Constants.ANNIVERSARY_LABEL); + final long timeStamp = intent.getLongExtra(Constants.TIME_STAMP, 0); PendingIntent pendingIntent = TaskStackBuilder.create(context) .addNextIntentWithParentStack(getResultIntent(context, timeStamp, intent)) @@ -61,7 +62,7 @@ public void onReceive(Context context, Intent intent) { createNotificationChannel(context); - NotificationCompat.Builder builder = buildNotification(context, name, when); + NotificationCompat.Builder builder = buildNotification(context, name, label, when); setDefaultsAndRingtone(builder); @@ -107,9 +108,11 @@ private void createNotificationChannel(Context context) { /** * Builds default notification */ - private NotificationCompat.Builder buildNotification(Context context, String title, String text) { + private NotificationCompat.Builder buildNotification(Context context, String title, String label, String text) { return new NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle(title) + .setContentInfo(label) + .setSubText(label) .setContentText(text) .setSmallIcon(R.drawable.ic_notification) .setColor(context.getResources().getColor(R.color.accent_green_200)) diff --git a/app/src/main/java/com/djonique/birdays/database/DbHelper.java b/app/src/main/java/com/djonique/birdays/database/DbHelper.java index 6417b4d..2febbcf 100644 --- a/app/src/main/java/com/djonique/birdays/database/DbHelper.java +++ b/app/src/main/java/com/djonique/birdays/database/DbHelper.java @@ -22,6 +22,8 @@ import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; +import com.djonique.birdays.R; +import com.djonique.birdays.models.AnniversaryType; import com.djonique.birdays.models.Person; import com.djonique.birdays.utils.Utils; @@ -35,18 +37,22 @@ public class DbHelper extends SQLiteOpenHelper { static final String COLUMN_DATE = "date"; static final String COLUMN_IS_YEAR_KNOWN = "is_year_known"; static final String COLUMN_PHONE_NUMBER = "phone"; + static final String COLUMN_ANNIVERSARY_TYPE = "type"; + static final String COLUMN_ANNIVERSARY_LABEL = "label"; static final String COLUMN_EMAIL = "email"; static final String COLUMN_TIME_STAMP = "time_stamp"; static final String SELECTION_TIME_STAMP = COLUMN_TIME_STAMP + " = ?"; private static final String DB_NAME = "my_db"; - private static final int DATABASE_VERSION = 1; + private static final int DATABASE_VERSION = 3; private static final String DB_PERSONS_CREATE = "CREATE TABLE " + DB_PERSONS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " TEXT, " + COLUMN_DATE + " INTEGER, " + COLUMN_IS_YEAR_KNOWN + " INTEGER, " + COLUMN_PHONE_NUMBER + " TEXT, " + + COLUMN_ANNIVERSARY_TYPE + " TEXT, " + + COLUMN_ANNIVERSARY_LABEL + " TEXT, " + COLUMN_EMAIL + " TEXT, " + COLUMN_TIME_STAMP + " INTEGER" + ");"; @@ -85,6 +91,17 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.endTransaction(); } } + if (newVersion == DATABASE_VERSION) { + db.beginTransaction(); + try { + db.execSQL("ALTER TABLE " + DB_PERSONS + " ADD COLUMN " + COLUMN_ANNIVERSARY_TYPE + " TEXT DEFAULT '" + AnniversaryType.BIRTHDAY.name() + "'"); + db.execSQL("ALTER TABLE " + DB_PERSONS + " ADD COLUMN " + COLUMN_ANNIVERSARY_LABEL + " TEXT DEFAULT '" + context.getResources().getString(R.string.birthday) + "'"); + db.setTransactionSuccessful(); + } + finally { + db.endTransaction(); + } + } } public DbQueryManager query() { @@ -92,22 +109,26 @@ public DbQueryManager query() { } public void addRecord(Person person) { - ContentValues cv = new ContentValues(); + final ContentValues cv = new ContentValues(); cv.put(COLUMN_NAME, person.getName()); cv.put(COLUMN_DATE, person.getDate()); cv.put(COLUMN_IS_YEAR_KNOWN, Utils.boolToInt(person.isYearUnknown())); cv.put(COLUMN_PHONE_NUMBER, person.getPhoneNumber()); + cv.put(COLUMN_ANNIVERSARY_TYPE, person.getAnniversaryType().toString()); + cv.put(COLUMN_ANNIVERSARY_LABEL, person.getAnniversaryLabel()); cv.put(COLUMN_EMAIL, person.getEmail()); cv.put(COLUMN_TIME_STAMP, person.getTimeStamp()); getWritableDatabase().insert(DB_PERSONS, null, cv); } public void updateRecord(Person person) { - ContentValues cv = new ContentValues(); + final ContentValues cv = new ContentValues(); cv.put(COLUMN_NAME, person.getName()); cv.put(COLUMN_DATE, person.getDate()); cv.put(COLUMN_IS_YEAR_KNOWN, Utils.boolToInt(person.isYearUnknown())); cv.put(COLUMN_PHONE_NUMBER, person.getPhoneNumber()); + cv.put(COLUMN_ANNIVERSARY_TYPE, person.getAnniversaryType().toString()); + cv.put(COLUMN_ANNIVERSARY_LABEL, person.getAnniversaryLabel()); cv.put(COLUMN_EMAIL, person.getEmail()); getWritableDatabase().update(DB_PERSONS, cv, SELECTION_TIME_STAMP, new String[]{String.valueOf(person.getTimeStamp())}); diff --git a/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java b/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java index 2e8507b..b3baf38 100644 --- a/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java +++ b/app/src/main/java/com/djonique/birdays/database/DbQueryManager.java @@ -19,6 +19,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import com.djonique.birdays.models.AnniversaryType; import com.djonique.birdays.models.Person; import com.djonique.birdays.utils.Utils; @@ -28,101 +29,42 @@ public class DbQueryManager { private SQLiteDatabase database; - private Person person; - private List persons; DbQueryManager(SQLiteDatabase database) { 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, - new String[]{Long.toString(timeStamp)}, null, null, null); + final List candidates = getPersons(DbHelper.DB_PERSONS, null, DbHelper.SELECTION_TIME_STAMP, new String[]{Long.toString(timeStamp)}, null, null, null, null); - if (cursor.moveToFirst()) { - String name = getName(cursor); - long date = getDate(cursor); - boolean isYearKnown = getYearUnknown(cursor); - String phoneNumber = getPhoneNumber(cursor); - String email = getEmail(cursor); - - person = new Person(name, date, isYearKnown, phoneNumber, email, timeStamp); + if (candidates.size() > 0) { + return candidates.get(0); } - cursor.close(); - return person; + return null; } public List getPersons() { - persons = new ArrayList<>(); - - Cursor cursor = database.query(DbHelper.DB_PERSONS, null, null, null, null, - null, null); - - if (cursor.moveToFirst()) { - do { - String name = getName(cursor); - long date = getDate(cursor); - boolean isYearKnown = getYearUnknown(cursor); - String phoneNumber = getPhoneNumber(cursor); - String email = getEmail(cursor); - long timeStamp = getTimeStamp(cursor); - - person = new Person(name, date, isYearKnown, phoneNumber, email, timeStamp); - persons.add(person); - - } while (cursor.moveToNext()); - } - cursor.close(); - - return persons; + return getPersons(DbHelper.DB_PERSONS, null, null, null, null, null, null, null); } - public List getSearchPerson(String selection, String[] selectionArgs, String orderBy) { - persons = new ArrayList<>(); - - Cursor cursor = database.query(DbHelper.DB_PERSONS, null, selection, selectionArgs, null, - null, orderBy); - - if (cursor.moveToFirst()) { - do { - String name = getName(cursor); - long date = getDate(cursor); - boolean isYearKnown = getYearUnknown(cursor); - String phoneNumber = getPhoneNumber(cursor); - String email = getEmail(cursor); - long timeStamp = getTimeStamp(cursor); - - person = new Person(name, date, isYearKnown, phoneNumber, email, timeStamp); - persons.add(person); - - } while (cursor.moveToNext()); - } - cursor.close(); - - return persons; + public interface Matches { + public boolean match(Person person); } - public List getThisMonthPersons() { - persons = new ArrayList<>(); + private List getPersons(final String db, final String[] columns, final String selection, final String[] selectionArgs, final String groupBy, final String having, final String orderBy, final Matches matcher) { + final List persons = new ArrayList<>(); - Cursor cursor = database.query(DbHelper.DB_PERSONS, null, null, null, null, null, null); + final Cursor cursor = database.query(db, columns, selection, selectionArgs, groupBy, having, orderBy); if (cursor.moveToFirst()) { do { - String name = getName(cursor); - long date = getDate(cursor); - boolean isYearKnown = getYearUnknown(cursor); - String phoneNumber = getPhoneNumber(cursor); - String email = getEmail(cursor); - long timeStamp = getTimeStamp(cursor); - - if (Utils.isCurrentMonth(date)) { - person = new Person(name, date, isYearKnown, phoneNumber, email, timeStamp); - persons.add(person); + final Person person = getPerson(cursor); + if ((matcher == null) || (matcher.match(person))) { + persons.add(getPerson(cursor)); } + } while (cursor.moveToNext()); } cursor.close(); @@ -130,46 +72,48 @@ public List getThisMonthPersons() { return persons; } - public List getSearchMonthPerson(String selection, String[] selectionArgs, - String orderBy) { - persons = new ArrayList<>(); + private Person getPerson(final Cursor cursor) { + final String name = getName(cursor); + final long date = getDate(cursor); + final boolean isYearKnown = getYearUnknown(cursor); + final String phoneNumber = getPhoneNumber(cursor); + final AnniversaryType anniversaryType = getAnniversaryType(cursor); + final String label = getAnniversaryLabel(cursor); + final String email = getEmail(cursor); + final long timeStamp = getTimeStamp(cursor); + + return new Person(name, date, isYearKnown, phoneNumber, email, label, anniversaryType, timeStamp); + } - Cursor cursor = database.query(DbHelper.DB_PERSONS, null, selection, selectionArgs, null, - null, orderBy); + public List getSearchPerson(String selection, String[] selectionArgs, String orderBy) { + return getPersons(DbHelper.DB_PERSONS, null, selection, selectionArgs, null, null, orderBy, null); + } - if (cursor.moveToFirst()) { - do { - String name = getName(cursor); - long date = getDate(cursor); - boolean isYearKnown = getYearUnknown(cursor); - String phoneNumber = getPhoneNumber(cursor); - String email = getEmail(cursor); - long timeStamp = getTimeStamp(cursor); - - if (Utils.isCurrentMonth(date)) { - person = new Person(name, date, isYearKnown, phoneNumber, email, timeStamp); - persons.add(person); - } - } while (cursor.moveToNext()); - } - cursor.close(); + public List getThisMonthPersons() { + return getSearchMonthPersons(null, null, null); + } - return persons; + public List getSearchMonthPersons(String selection, String[] selectionArgs, String orderBy) { + return getPersons(DbHelper.DB_PERSONS, null, selection, selectionArgs, null, null, orderBy, new Matches() { + @Override + public boolean match(Person person) { + return Utils.isCurrentMonth(person.getDate()); + } + }); } public List getFamousBornThisDay(long dayOfBirthday) { - persons = new ArrayList<>(); + final List persons = new ArrayList<>(); - Cursor cursor = database.query(DbHelper.DB_FAMOUS, null, null, null, null, null, null); + final Cursor cursor = database.query(DbHelper.DB_FAMOUS, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { - String name = getName(cursor); - long date = getDate(cursor); + final String name = getName(cursor); + final long date = getDate(cursor); - if (Utils.getMonth(date) == Utils.getMonth(dayOfBirthday) && - Utils.getDay(date) == Utils.getDay(dayOfBirthday)) { - person = new Person(name, date); + if (Utils.getMonth(date) == Utils.getMonth(dayOfBirthday) && Utils.getDay(date) == Utils.getDay(dayOfBirthday)) { + final Person person = new Person(name, date); persons.add(person); } } while (cursor.moveToNext()); @@ -195,6 +139,14 @@ private String getPhoneNumber(Cursor cursor) { return cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_PHONE_NUMBER)); } + private String getAnniversaryLabel(Cursor cursor) { + return cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_ANNIVERSARY_LABEL)); + } + + private AnniversaryType getAnniversaryType(Cursor cursor) { + return AnniversaryType.valueOf(cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_ANNIVERSARY_TYPE))); + } + private String getEmail(Cursor cursor) { return cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_EMAIL)); } diff --git a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java index 0dccd68..1a2882f 100644 --- a/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java +++ b/app/src/main/java/com/djonique/birdays/fragments/AllFragment.java @@ -35,10 +35,10 @@ import com.djonique.birdays.adapters.AllFragmentAdapter; import com.djonique.birdays.alarm.AlarmHelper; import com.djonique.birdays.database.DbHelper; +import com.djonique.birdays.models.Item; import com.djonique.birdays.models.Person; -import com.djonique.birdays.models.Separator; -import java.util.Calendar; +import java.util.Collections; import java.util.List; public class AllFragment extends Fragment { @@ -63,7 +63,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { if (getActivity() != null) { activity = (MainActivity) getActivity(); - addAllPersonsFromDb(); + refreshAllPersonsFromDb(); alarmHelper = new AlarmHelper(activity); } } @@ -71,94 +71,50 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_recycler_view, container, false); - RecyclerView recyclerView = view.findViewById(R.id.recyclerView); + final View view = inflater.inflate(R.layout.fragment_recycler_view, container, false); + final RecyclerView recyclerView = view.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); adapter = new AllFragmentAdapter(this); recyclerView.setAdapter(adapter); return view; } - public void addPerson(Person newPerson, boolean saveToDb) { - int position = -1; - Separator separator = null; - - long newPersonDate = newPerson.getDate(); - int newPersonMonth = newPerson.getMonth(); - int newPersonDay = newPerson.getDay(); - - for (int i = 0; i < adapter.getItemCount(); i++) { - if (adapter.getItem(i).isPerson()) { - Person person = ((Person) adapter.getItem(i)); - int month = person.getMonth(); - int day = person.getDay(); - - if (newPersonMonth < month) { - position = i; - break; - } else if (newPersonMonth == month) { - if (newPersonDay <= day) { - // If date before - position = i; - break; - } else { // If date after - if (adapter.getItemCount() > (i + 1) && adapter.getItem(i + 1).isPerson()) { // If after person, not adapter - Person nextPerson = ((Person) adapter.getItem(i + 1)); - if (newPersonDay <= nextPerson.getDay()) { - // If date before, else if date after - continue - position = i + 1; - break; - } - } else { // If after adapter, not person - position = i + 1; - break; - } - } - } - } - } - - if (newPersonDate != 0) { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(newPersonDate); - - separator = getSeparator(newPerson); - } - - if (position != -1) { - if (separator != null) { - adapter.addItem(position - 1, separator); - } - adapter.addItem(position, newPerson); - } else { - if (separator != null) { - adapter.addItem(separator); - } - adapter.addItem(newPerson); - } - + public void addPerson(Person person, boolean saveToDb) { if (saveToDb) { - activity.dbHelper.addRecord(newPerson); + activity.dbHelper.addRecord(person); + refreshAllPersonsFromDb(); } } - public void addAllPersonsFromDb() { - adapter.removeAllPersons(); - List persons = activity.dbHelper.query().getPersons(); - - for (Person person : persons) { - addPerson(person, false); +// public List addSeparatorsToPersons(List persons) { +// List fullList = new ArrayList<>(); +// Person last = null; +// //need the persons to be sorted by month +// Collections.sort(persons); +// for (Person person : persons) { +// //we just switched months +// if ((last == null) || (person.getMonth() > last.getMonth())) { +// fullList.add(new Separator(person.getMonth())); +// } +// fullList.add(person); +// last = person; +// } +// +// return fullList; +// } + + public void showPersons(List persons) { + //final List fullList = addSeparatorsToPersons(persons); + Collections.sort(persons); + for (Item item : persons) { + adapter.addItem(item); } } - private Separator getSeparator(Person person) { - int month = person.getMonth(); - Separator separator = null; - if (!adapter.containedSeparators[month]) { - adapter.containedSeparators[month] = true; - separator = new Separator(month); - } - return separator; + public void refreshAllPersonsFromDb() { + adapter.removeAllPersons(); + final List persons = activity.dbHelper.query().getPersons(); + showPersons(persons); } public void removePersonDialog(final int location) { @@ -183,7 +139,7 @@ public void onClick(DialogInterface dialog, int which) { snackbar.setAction(getString(R.string.undo), new View.OnClickListener() { @Override public void onClick(View v) { - addPerson(activity.dbHelper.query().getPerson(timeStamp), false); + refreshAllPersonsFromDb(); isRemoved[0] = false; } }); @@ -221,9 +177,7 @@ public void findPerson(String name) { List persons = activity.dbHelper.query().getSearchPerson(DbHelper.SELECTION_LIKE_NAME, new String[]{"%" + name + "%"}, DbHelper.COLUMN_NAME); - for (int i = 0; i < persons.size(); i++) { - addPerson(persons.get(i), false); - } + showPersons(persons); } public interface DeletingPersonListener { diff --git a/app/src/main/java/com/djonique/birdays/fragments/MonthFragment.java b/app/src/main/java/com/djonique/birdays/fragments/MonthFragment.java index 396d015..7a4871c 100644 --- a/app/src/main/java/com/djonique/birdays/fragments/MonthFragment.java +++ b/app/src/main/java/com/djonique/birdays/fragments/MonthFragment.java @@ -103,8 +103,7 @@ public void deleteRecord(long timeStamp) { public void findPerson(String name) { adapter.removeAllPersons(); List persons = new ArrayList<>(); - persons.addAll(activity.dbHelper.query().getSearchMonthPerson(DbHelper.SELECTION_LIKE_NAME, - new String[]{"%" + name + "%"}, DbHelper.COLUMN_NAME)); + persons.addAll(activity.dbHelper.query().getSearchMonthPersons(DbHelper.SELECTION_LIKE_NAME, new String[]{"%" + name + "%"}, DbHelper.COLUMN_NAME)); for (int i = 0; i < persons.size(); i++) { addPerson(persons.get(i)); diff --git a/app/src/main/java/com/djonique/birdays/models/AnniversaryType.java b/app/src/main/java/com/djonique/birdays/models/AnniversaryType.java new file mode 100644 index 0000000..7c066b7 --- /dev/null +++ b/app/src/main/java/com/djonique/birdays/models/AnniversaryType.java @@ -0,0 +1,6 @@ +package com.djonique.birdays.models; + +public enum AnniversaryType { + BIRTHDAY, + ANNIVERSARY, +} diff --git a/app/src/main/java/com/djonique/birdays/models/Item.java b/app/src/main/java/com/djonique/birdays/models/Item.java index a1d6717..d357adf 100644 --- a/app/src/main/java/com/djonique/birdays/models/Item.java +++ b/app/src/main/java/com/djonique/birdays/models/Item.java @@ -17,5 +17,8 @@ package com.djonique.birdays.models; public interface Item { - boolean isPerson(); + ItemType getItemType(); + boolean isSeparator(); + int getMonth(); + AnniversaryType getAnniversaryType(); } \ No newline at end of file diff --git a/app/src/main/java/com/djonique/birdays/adapters/ItemType.java b/app/src/main/java/com/djonique/birdays/models/ItemType.java similarity index 64% rename from app/src/main/java/com/djonique/birdays/adapters/ItemType.java rename to app/src/main/java/com/djonique/birdays/models/ItemType.java index 10ad239..d33367a 100644 --- a/app/src/main/java/com/djonique/birdays/adapters/ItemType.java +++ b/app/src/main/java/com/djonique/birdays/models/ItemType.java @@ -1,4 +1,4 @@ -package com.djonique.birdays.adapters; +package com.djonique.birdays.models; public enum ItemType { PERSON, diff --git a/app/src/main/java/com/djonique/birdays/models/Person.java b/app/src/main/java/com/djonique/birdays/models/Person.java index 01d37f8..b89241b 100644 --- a/app/src/main/java/com/djonique/birdays/models/Person.java +++ b/app/src/main/java/com/djonique/birdays/models/Person.java @@ -22,16 +22,17 @@ import java.util.Date; public class Person implements Item, Comparable { - - private String name, phoneNumber, email; - private long date, timeStamp; + private long date; + private long timeStamp; + private String name; private boolean yearUnknown; + private String anniversaryLabel; + private AnniversaryType anniversaryType; + private String phoneNumber; + private String email; - /** - * Default constructor - */ public Person() { - this.timeStamp = new Date().getTime(); + super(); } /** @@ -45,26 +46,21 @@ public Person(String name, long date) { /** * Constructor for importing from Contacts */ - public Person(String name, long date, boolean yearUnknown, String phoneNumber, String email) { - this.name = name; - this.date = date; - this.yearUnknown = yearUnknown; - this.phoneNumber = phoneNumber; - this.email = email; - this.timeStamp = new Date().getTime(); + public Person(String name, long date, boolean yearUnknown, String phoneNumber, String email, String anniversaryLabel, AnniversaryType anniversaryType) { + this(name, date, yearUnknown, phoneNumber, email, anniversaryLabel, anniversaryType, new Date().getTime()); } /** * Constructor for DbQueryManager */ - public Person(String name, long date, boolean yearUnknown, String phoneNumber, String email, - long timeStamp) { - this.name = name; - this.date = date; + public Person(String name, long date, boolean yearUnknown, String phoneNumber, String email, String anniversaryLabel, AnniversaryType anniversaryType, long timeStamp) { + this(name, date); this.yearUnknown = yearUnknown; this.phoneNumber = phoneNumber; this.email = email; - this.timeStamp = timeStamp; + this.anniversaryLabel = anniversaryLabel; + this.anniversaryType = anniversaryType; + this.setTimeStamp(timeStamp); } public String getName() { @@ -83,6 +79,14 @@ public void setDate(long date) { this.date = date; } + public long getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + public boolean isYearUnknown() { return yearUnknown; } @@ -91,6 +95,27 @@ public void setYearUnknown(boolean yearUnknown) { this.yearUnknown = yearUnknown; } + @Override + public int getMonth() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(this.date); + return calendar.get(Calendar.MONTH); + } + + public int getDay() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(this.date); + return calendar.get(Calendar.DAY_OF_MONTH); + } + + public String getAnniversaryLabel() { + return anniversaryLabel; + } + + public void setAnniversaryLabel(String anniversaryLabel) { + this.anniversaryLabel = anniversaryLabel; + } + public String getPhoneNumber() { return phoneNumber; } @@ -107,25 +132,31 @@ public void setEmail(String email) { this.email = email; } - public long getTimeStamp() { - return timeStamp; + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + ", anniversaryLabel='" + anniversaryLabel + '\'' + + '}'; } @Override - public boolean isPerson() { - return true; + public ItemType getItemType() { + return ItemType.PERSON; } - public int getMonth() { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(this.date); - return calendar.get(Calendar.MONTH); + @Override + public AnniversaryType getAnniversaryType() { + return anniversaryType; } - public int getDay() { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(this.date); - return calendar.get(Calendar.DAY_OF_MONTH); + public void setAnniversaryType(AnniversaryType anniversaryType) { + this.anniversaryType = anniversaryType; + } + + @Override + public boolean isSeparator() { + return false; } @Override @@ -136,19 +167,26 @@ public boolean equals(Object obj) { if (!Person.class.isAssignableFrom(obj.getClass())) { return false; } - Person person = (Person) obj; - return this.name.equalsIgnoreCase(person.name) && - this.date == person.date; + Person that = (Person) obj; + return this.getName().equalsIgnoreCase(that.getName()) && + this.getAnniversaryLabel().equalsIgnoreCase(that.getAnniversaryLabel()) && + this.getDate() == that.getDate(); } @Override public int compareTo(@NonNull Person person) { - if (this.getMonth() < person.getMonth()) { - return -1; - } else if (this.getMonth() == person.getMonth()) { - return this.getDay() - person.getDay(); + final Integer m1 = this.getMonth(); + final Integer m2 = person.getMonth(); + final Integer d1 = this.getDay(); + final Integer d2 = person.getDay(); + if (m1 != m2) { + return m1.compareTo(m2); } else { - return 1; + if (d1 != d2) { + return d1.compareTo(d2); + } + + return this.getName().compareTo(person.getName()); } } } \ No newline at end of file diff --git a/app/src/main/java/com/djonique/birdays/models/Separator.java b/app/src/main/java/com/djonique/birdays/models/Separator.java index f87bbe9..64e4f87 100644 --- a/app/src/main/java/com/djonique/birdays/models/Separator.java +++ b/app/src/main/java/com/djonique/birdays/models/Separator.java @@ -17,17 +17,29 @@ package com.djonique.birdays.models; public class Separator implements Item { - private int type; + private int month; - public Separator(int type) { - this.type = type; + public Separator(int month) { + this.month = month; } - public boolean isPerson() { - return false; + @Override + public int getMonth() { + return month; } - public int getType() { - return type; + @Override + public ItemType getItemType() { + return ItemType.SEPARATOR; + } + + @Override + public AnniversaryType getAnniversaryType() { + return null; + } + + @Override + public boolean isSeparator() { + return true; } } \ No newline at end of file diff --git a/app/src/main/java/com/djonique/birdays/utils/Constants.java b/app/src/main/java/com/djonique/birdays/utils/Constants.java index 98c9f44..a77cc06 100644 --- a/app/src/main/java/com/djonique/birdays/utils/Constants.java +++ b/app/src/main/java/com/djonique/birdays/utils/Constants.java @@ -30,6 +30,7 @@ public interface Constants { // Alarm String NAME = "NAME"; String WHEN = "WHEN"; + String ANNIVERSARY_LABEL = "ANNIVERSARY_LABEL"; String TIME_STAMP = "TIME_STAMP"; // Settings keys diff --git a/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java b/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java index a083bd0..654be62 100644 --- a/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java +++ b/app/src/main/java/com/djonique/birdays/utils/ContactsHelper.java @@ -19,15 +19,18 @@ import android.app.Activity; import android.content.ContentResolver; import android.content.SharedPreferences; +import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.provider.ContactsContract; +import android.text.TextUtils; import android.widget.Toast; import com.djonique.birdays.R; import com.djonique.birdays.alarm.AlarmHelper; import com.djonique.birdays.database.DbHelper; +import com.djonique.birdays.models.AnniversaryType; import com.djonique.birdays.models.Person; import java.util.ArrayList; @@ -103,6 +106,26 @@ public String getContactEmail(ContentResolver contentResolver, String id) { return email; } + private String getTypeLabel(Resources res, int type, String label) { + if (type == ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM && !TextUtils.isEmpty(label)) { + return label; + } else { + final int labelRes = ContactsContract.CommonDataKinds.Event.getTypeResource(type); + return res.getText(labelRes).toString(); + } + } + + private AnniversaryType getAnniversaryType(int type) { + switch (type) { + case ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY: + return AnniversaryType.BIRTHDAY; + + case ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY: + default: + return AnniversaryType.ANNIVERSARY; + } + } + /** * Returns all contacts with Birthdays */ @@ -113,10 +136,14 @@ private List getAllContactsWithBirthdays(ContentResolver contentResolver Cursor cursor = getContactsCursor(contentResolver); while (cursor.moveToNext()) { - String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Event.CONTACT_ID)); - String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); - String dateString = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE)); - long date; + final String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Event.CONTACT_ID)); + final String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); + final String dateString = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE)); + final int type = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.TYPE)); + final String label = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Event.LABEL)); + final String anniversary = getTypeLabel(activity.getResources(), type, label); + + final long date; try { date = Utils.formatDateToLong(dateString); } catch (Exception e) { @@ -128,7 +155,7 @@ private List getAllContactsWithBirthdays(ContentResolver contentResolver String phoneNumber = getContactPhoneNumber(contentResolver, id); String email = getContactEmail(contentResolver, id); - Person person = new Person(name, date, yearUnknown, phoneNumber, email); + Person person = new Person(name, date, yearUnknown, phoneNumber, email, anniversary, getAnniversaryType(type)); contacts.add(person); } cursor.close(); @@ -143,16 +170,16 @@ private Cursor getContactsCursor(ContentResolver contentResolver) { /* String[] projection = new String[]{ ContactsContract.Contacts.DISPLAY_NAME, - ContactsContract.CommonDataKinds.Event.CONTACT_ID, + / ContactsContract.CommonDataKinds.Event.CONTACT_ID, ContactsContract.CommonDataKinds.Event.START_DATE, };*/ String where = ContactsContract.Data.MIMETYPE - + "= ? AND " - + ContactsContract.CommonDataKinds.Event.TYPE - + "=" - + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY; + + "= ?"; +// + ContactsContract.CommonDataKinds.Event.TYPE +// + "=" +// + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY; String[] selectionArgs = new String[]{ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE}; return contentResolver.query(uri, null, where, selectionArgs, null); } diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index 40ab9e8..aaf0fb4 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -94,7 +94,7 @@ + android:id="@+id/textview_detail_label" /> @@ -153,6 +153,7 @@ diff --git a/app/src/main/res/layout/description_list_view.xml b/app/src/main/res/layout/description_list_view.xml index 43b0d50..b010eb8 100644 --- a/app/src/main/res/layout/description_list_view.xml +++ b/app/src/main/res/layout/description_list_view.xml @@ -17,6 +17,7 @@ --> @@ -32,16 +33,30 @@ android:shadowDx="1" android:shadowDy="1" android:shadowRadius="1" + android:text="Age" android:textColor="@android:color/white" android:textSize="@dimen/age_circle_text_size" /> + android:maxLines="2" + android:text="Full name here" /> + android:layout_below="@+id/textview_all_label" + android:text="Date here" /> + + + \ No newline at end of file diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index e1a0865..e4b8d8f 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -69,9 +69,9 @@ Birthday - Days until next birthday + Days until next anniversary Today - Days since birth + Days since anniversary started Zodiac sign Season picture Calendar diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 865b453..1a589d0 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -22,7 +22,7 @@ Se încarcă contactele… Contacte încărcate - Nu se pot importa contanctele, formatul de date este nonstandard + Nu se pot importa contactele, formatul de date este nonstandard Este necesară permisiunea pentru importarea contactelor Permite Toate @@ -71,7 +71,7 @@ Ziua de naștere Numărul de zile până la următoarea aniversare Astăzi - Numărul de zile de la naștere + Numărul de zile de la prima aniversare Semn zodical Poză pentru sezon Calendar @@ -103,7 +103,7 @@ Optimizare activată! - \nÎncepând de la versiunea 6.0, Android introduce opțiunea de economisirea a batriei, care gestionează aplicațiile prin amânarea procesorului de fundal. \n\nPentru a face aplicații care dezactivează optimizarea pentu Birdays. + \nÎncepând de la versiunea 6.0, Android introduce opțiunea de economisirea a bateriei, care gestionează aplicațiile prin amânarea procesorului de fundal. \n\nPentru a face aplicații care dezactivează optimizarea pentu Birdays. Nu mai afișa Dezactivează diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cc4d721..e1bda41 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -73,9 +73,9 @@ Birthday - Days until next birthday + Days until next occurrence Today - Days since birth + Days since anniversary started Zodiac sign Season picture Calendar @@ -224,7 +224,7 @@ Why do I see ads? The revenue from advertising goes to the development of the project and to translation into other languages. You can remove ads for free Interstitial ad - This type of ad is limited to 1 show per day. Not so often, isn\'t it? + This month of ad is limited to 1 show per day. Not so often, isn\'t it? Banner About app