Refactor prayer management in ExtrasActivity and enhance holiday handling in MainActivity

- Updated prayer strings in ExtrasActivity to use Unicode for special characters.
- Introduced multiple new prayers in ExtrasActivity and structured them using a PrayerItem class.
- Modified the prayer card creation to dynamically display titles and subtitles.
- Enhanced the prayer detail rendering to reflect the selected prayer.
- Added holiday tag functionality in MainActivity to display liturgical holidays.
- Implemented methods to identify known Catholic holidays and classify them by rank.
- Updated UI to show holiday tags based on the selected date.
- Addressed deprecation warnings in Gradle configuration.
This commit is contained in:
jahruz67
2026-05-21 22:55:40 -07:00
parent b4d312da41
commit 6a5e289f68
3 changed files with 609 additions and 34 deletions
@@ -24,17 +24,17 @@ public class ExtrasActivity extends Activity {
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
private static final String VENI_CREATOR_PRAYER =
"Ven, Espíritu Creador,\n"
"Ven, Esp\u00edritu Creador,\n"
+ "visita las almas de tus fieles\n"
+ "y llena de la gracia divina\n"
+ "los corazones que tú mismo creaste.\n\n"
+ " eres nuestro Consolador,\n"
+ "don del Dios altísimo,\n"
+ "los corazones que t\u00fa mismo creaste.\n\n"
+ "T\u00fa eres nuestro Consolador,\n"
+ "don del Dios alt\u00edsimo,\n"
+ "fuente viva, fuego, caridad\n"
+ "y espiritual unción.\n\n"
+ " derramas sobre nosotros\n"
+ "y espiritual unci\u00f3n.\n\n"
+ "T\u00fa derramas sobre nosotros\n"
+ "los siete dones;\n"
+ " eres el dedo de la diestra del Padre,\n"
+ "t\u00fa eres el dedo de la diestra del Padre,\n"
+ "promesa solemne del Padre,\n"
+ "que pones en nuestros labios la palabra.\n\n"
+ "Enciende tu luz en nuestras mentes,\n"
@@ -43,22 +43,93 @@ public class ExtrasActivity extends Activity {
+ "la debilidad de nuestro cuerpo.\n\n"
+ "Aleja de nosotros al enemigo,\n"
+ "danos pronto la paz;\n"
+ "siendo tú nuestro guía,\n"
+ "siendo t\u00fa nuestro gu\u00eda,\n"
+ "evitaremos todo mal.\n\n"
+ "Por ti conozcamos al Padre,\n"
+ "y también al Hijo;\n"
+ "y que en ti, Espíritu de ambos,\n"
+ "y tambi\u00e9n al Hijo;\n"
+ "y que en ti, Esp\u00edritu de ambos,\n"
+ "creamos en todo tiempo.\n\n"
+ "Gloria a Dios Padre,\n"
+ "y al Hijo que resucitó,\n"
+ "y al Espíritu Consolador,\n"
+ "y al Hijo que resucit\u00f3,\n"
+ "y al Esp\u00edritu Consolador,\n"
+ "por los siglos de los siglos.\n\n"
+ "Amén.";
+ "Am\u00e9n.";
private static final String ANGELUS_PRAYER =
"El \u00c1ngel del Se\u00f1or anunci\u00f3 a Mar\u00eda.\n"
+ "Y concibi\u00f3 por obra y gracia del Esp\u00edritu Santo.\n\n"
+ "Dios te salve, Mar\u00eda, llena eres de gracia,\n"
+ "el Se\u00f1or es contigo.\n"
+ "Bendita t\u00fa eres entre todas las mujeres,\n"
+ "y bendito es el fruto de tu vientre, Jes\u00fas.\n"
+ "Santa Mar\u00eda, Madre de Dios,\n"
+ "ruega por nosotros, pecadores,\n"
+ "ahora y en la hora de nuestra muerte.\n"
+ "Am\u00e9n.\n\n"
+ "He aqu\u00ed la esclava del Se\u00f1or.\n"
+ "H\u00e1gase en m\u00ed seg\u00fan tu palabra.\n\n"
+ "Dios te salve, Mar\u00eda...\n\n"
+ "Y el Verbo se hizo carne.\n"
+ "Y habit\u00f3 entre nosotros.\n\n"
+ "Dios te salve, Mar\u00eda...\n\n"
+ "Ruega por nosotros, Santa Madre de Dios.\n"
+ "Para que seamos dignos de alcanzar las promesas de Cristo.\n\n"
+ "Infunde, Se\u00f1or, tu gracia en nuestros corazones,\n"
+ "para que quienes hemos conocido por el anuncio del \u00c1ngel\n"
+ "la encarnaci\u00f3n de tu Hijo Jesucristo,\n"
+ "por su pasi\u00f3n y cruz seamos llevados\n"
+ "a la gloria de su resurrecci\u00f3n.\n"
+ "Por Jesucristo nuestro Se\u00f1or.\n\n"
+ "Am\u00e9n.";
private static final String SALVE_REGINA_PRAYER =
"Dios te salve, Reina y Madre de misericordia,\n"
+ "vida, dulzura y esperanza nuestra;\n"
+ "Dios te salve.\n\n"
+ "A ti llamamos los desterrados hijos de Eva;\n"
+ "a ti suspiramos, gimiendo y llorando\n"
+ "en este valle de l\u00e1grimas.\n\n"
+ "Ea, pues, Se\u00f1ora, abogada nuestra,\n"
+ "vuelve a nosotros esos tus ojos misericordiosos;\n"
+ "y despu\u00e9s de este destierro,\n"
+ "mu\u00e9stranos a Jes\u00fas,\n"
+ "fruto bendito de tu vientre.\n\n"
+ "\u00a1Oh clemente, oh piadosa,\n"
+ "oh dulce Virgen Mar\u00eda!\n\n"
+ "Ruega por nosotros, Santa Madre de Dios,\n"
+ "para que seamos dignos de alcanzar\n"
+ "las promesas de nuestro Se\u00f1or Jesucristo.\n\n"
+ "Am\u00e9n.";
private static final String MEMORARE_PRAYER =
"Acordaos, oh piados\u00edsima Virgen Mar\u00eda,\n"
+ "que jam\u00e1s se ha o\u00eddo decir\n"
+ "que ninguno de los que han acudido a vuestra protecci\u00f3n,\n"
+ "implorado vuestra asistencia\n"
+ "y reclamado vuestro socorro,\n"
+ "haya sido abandonado de vos.\n\n"
+ "Animado con esta confianza,\n"
+ "a vos tambi\u00e9n acudo,\n"
+ "oh Madre, Virgen de las v\u00edrgenes;\n"
+ "y aunque gimiendo bajo el peso de mis pecados,\n"
+ "me atrevo a comparecer ante vuestra presencia soberana.\n\n"
+ "No desech\u00e9is, oh Madre de Dios,\n"
+ "mis humildes s\u00faplicas;\n"
+ "antes bien, escuchadlas y acogedlas benignamente.\n\n"
+ "Am\u00e9n.";
private static final PrayerItem[] PRAYERS = {
new PrayerItem("Ven, Esp\u00edritu Creador", "Veni Creator Spiritus", VENI_CREATOR_PRAYER),
new PrayerItem("\u00c1ngelus", "Oraci\u00f3n de la Encarnaci\u00f3n", ANGELUS_PRAYER),
new PrayerItem("Salve Regina", "Dios te salve, Reina", SALVE_REGINA_PRAYER),
new PrayerItem("Acordaos", "Memorare", MEMORARE_PRAYER)
};
private ScrollView scrollView;
private LinearLayout listContainer;
private LinearLayout detailContainer;
private TextView titleText;
private PrayerItem selectedPrayer = PRAYERS[0];
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -110,13 +181,16 @@ public class ExtrasActivity extends Activity {
listContainer = new LinearLayout(this);
listContainer.setOrientation(LinearLayout.VERTICAL);
listContainer.addView(createPrayerCard());
for (PrayerItem prayer : PRAYERS) {
listContainer.addView(createPrayerCard(prayer));
}
content.addView(listContainer, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
));
detailContainer = createPrayerDetail();
detailContainer = new LinearLayout(this);
detailContainer.setOrientation(LinearLayout.VERTICAL);
detailContainer.setVisibility(View.GONE);
content.addView(detailContainer, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -179,13 +253,13 @@ public class ExtrasActivity extends Activity {
return topBar;
}
private View createPrayerCard() {
private View createPrayerCard(PrayerItem prayer) {
LinearLayout card = new LinearLayout(this);
card.setOrientation(LinearLayout.HORIZONTAL);
card.setGravity(Gravity.CENTER_VERTICAL);
card.setPadding(dp(18), dp(16), dp(16), dp(16));
card.setBackground(roundedRect(COLOR_CARD, dp(8), Color.rgb(229, 232, 230), dp(1)));
card.setOnClickListener(view -> showPrayerDetail());
card.setOnClickListener(view -> showPrayerDetail(prayer));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
card.setElevation(dp(1));
}
@@ -193,11 +267,11 @@ public class ExtrasActivity extends Activity {
LinearLayout copy = new LinearLayout(this);
copy.setOrientation(LinearLayout.VERTICAL);
TextView title = textView("Ven, Espíritu Creador", 20, COLOR_INK, Typeface.BOLD);
TextView title = textView(prayer.title, 20, COLOR_INK, Typeface.BOLD);
title.setIncludeFontPadding(false);
copy.addView(title);
TextView subtitle = textView("Veni Creator Spiritus", 14, COLOR_MUTED, Typeface.BOLD);
TextView subtitle = textView(prayer.subtitle, 14, COLOR_MUTED, Typeface.BOLD);
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
@@ -218,40 +292,45 @@ public class ExtrasActivity extends Activity {
ViewGroup.LayoutParams.WRAP_CONTENT
));
LinearLayout.LayoutParams cardParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
cardParams.setMargins(0, 0, 0, dp(12));
card.setLayoutParams(cardParams);
return card;
}
private LinearLayout createPrayerDetail() {
LinearLayout detail = new LinearLayout(this);
detail.setOrientation(LinearLayout.VERTICAL);
private void renderPrayerDetail() {
detailContainer.removeAllViews();
TextView subtitle = textView("Veni Creator Spiritus", 14, COLOR_WARM, Typeface.BOLD);
detail.addView(subtitle);
TextView subtitle = textView(selectedPrayer.subtitle, 14, COLOR_WARM, Typeface.BOLD);
detailContainer.addView(subtitle);
TextView prayer = textView(VENI_CREATOR_PRAYER, 21, COLOR_INK, Typeface.NORMAL);
TextView prayer = textView(selectedPrayer.body, 21, COLOR_INK, Typeface.NORMAL);
prayer.setLineSpacing(dp(5), 1.14f);
LinearLayout.LayoutParams prayerParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
prayerParams.setMargins(0, dp(16), 0, dp(18));
detail.addView(prayer, prayerParams);
detailContainer.addView(prayer, prayerParams);
TextView backToList = textView("Volver a extras", 15, COLOR_ACCENT, Typeface.BOLD);
backToList.setGravity(Gravity.CENTER);
backToList.setPadding(dp(14), 0, dp(14), 0);
backToList.setBackground(roundedRect(Color.WHITE, dp(8), Color.rgb(219, 226, 222), dp(1)));
backToList.setOnClickListener(view -> showPrayerList());
detail.addView(backToList, new LinearLayout.LayoutParams(
detailContainer.addView(backToList, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
dp(42)
));
return detail;
}
private void showPrayerDetail() {
titleText.setText("Ven, Espíritu Creador");
private void showPrayerDetail(PrayerItem prayer) {
selectedPrayer = prayer;
titleText.setText(prayer.title);
renderPrayerDetail();
listContainer.setVisibility(View.GONE);
detailContainer.setVisibility(View.VISIBLE);
scrollToTop();
@@ -293,4 +372,16 @@ public class ExtrasActivity extends Activity {
private int dp(int value) {
return Math.round(value * getResources().getDisplayMetrics().density);
}
private static class PrayerItem {
final String title;
final String subtitle;
final String body;
PrayerItem(String title, String subtitle, String body) {
this.title = title;
this.subtitle = subtitle;
this.body = body;
}
}
}
@@ -46,9 +46,17 @@ public class MainActivity extends Activity {
private static final int COLOR_MUTED = Color.rgb(91, 99, 98);
private static final int COLOR_ACCENT = Color.rgb(0, 107, 90);
private static final int COLOR_WARM = Color.rgb(217, 75, 61);
private static final int COLOR_HOLIDAY_BG = Color.rgb(255, 246, 229);
private static final int COLOR_HOLIDAY_BORDER = Color.rgb(229, 166, 72);
private static final int COLOR_HOLIDAY_TEXT = Color.rgb(143, 76, 22);
private static final int MIN_FONT_SP = 16;
private static final int MAX_FONT_SP = 30;
private static final int RANK_HOLY_DAY = 0;
private static final int RANK_MEMORIAL = 1;
private static final int RANK_FEAST = 2;
private static final int RANK_SOLEMNITY = 3;
private final Locale spanishLocale = new Locale("es", "ES");
private final List<TextView> resizableTextViews = new ArrayList<>();
@@ -59,6 +67,7 @@ public class MainActivity extends Activity {
private TextView dateChipPrimary;
private TextView dateChipSecondary;
private TextView liturgyText;
private LinearLayout holidayTagsRow;
private TextView statusText;
private TextView sourceText;
private LinearLayout statusBlock;
@@ -240,6 +249,17 @@ public class MainActivity extends Activity {
dateText = textView("", 16, COLOR_MUTED, Typeface.BOLD);
header.addView(dateText);
holidayTagsRow = new LinearLayout(this);
holidayTagsRow.setOrientation(LinearLayout.HORIZONTAL);
holidayTagsRow.setGravity(Gravity.CENTER_VERTICAL);
holidayTagsRow.setVisibility(View.GONE);
LinearLayout.LayoutParams tagsParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
tagsParams.setMargins(0, dp(8), 0, 0);
header.addView(holidayTagsRow, tagsParams);
liturgyText = textView("", 16, COLOR_INK, Typeface.NORMAL);
liturgyText.setLineSpacing(0, 1.12f);
LinearLayout.LayoutParams liturgyParams = new LinearLayout.LayoutParams(
@@ -463,17 +483,24 @@ public class MainActivity extends Activity {
if (dayNumber >= 1 && dayNumber <= daysInMonth) {
Calendar cellDate = startOfMonth(visibleMonthCalendar);
cellDate.set(Calendar.DAY_OF_MONTH, dayNumber);
LiturgicalDay holiday = knownCatholicHoliday(cellDate);
dayCell.setText(String.valueOf(dayNumber));
if (isSameDay(cellDate, selectedDateCalendar)) {
dayCell.setTextColor(Color.WHITE);
dayCell.setBackground(oval(COLOR_ACCENT));
dayCell.setBackground(oval(holiday == null ? COLOR_ACCENT : COLOR_WARM));
} else if (holiday != null) {
dayCell.setTextColor(COLOR_HOLIDAY_TEXT);
dayCell.setBackground(roundedRect(COLOR_HOLIDAY_BG, dp(8), COLOR_HOLIDAY_BORDER, dp(1)));
} else if (isSameDay(cellDate, today)) {
dayCell.setTextColor(COLOR_WARM);
dayCell.setBackground(roundedRect(Color.rgb(255, 239, 236), dp(8), Color.TRANSPARENT, 0));
} else {
dayCell.setBackground(roundedRect(Color.TRANSPARENT, dp(8), Color.TRANSPARENT, 0));
}
if (holiday != null) {
dayCell.setContentDescription(dayNumber + ", " + holiday.displayName(isEnglish));
}
Calendar dateForClick = (Calendar) cellDate.clone();
dayCell.setOnClickListener(view -> selectDate(dateForClick));
@@ -486,6 +513,426 @@ public class MainActivity extends Activity {
}
}
private void updateHolidayTags(LiturgicalDay holiday) {
if (holidayTagsRow == null) {
return;
}
holidayTagsRow.removeAllViews();
if (holiday == null) {
holidayTagsRow.setVisibility(View.GONE);
return;
}
holidayTagsRow.setVisibility(View.VISIBLE);
holidayTagsRow.addView(createHolidayTag(holiday.rankLabel(isEnglish)));
holidayTagsRow.addView(createHolidayTag(isEnglish ? "Catholic holiday" : "Fiesta cat\u00f3lica"));
}
private TextView createHolidayTag(String text) {
Locale locale = isEnglish ? Locale.US : spanishLocale;
TextView tag = textView(text.toUpperCase(locale), 11, COLOR_HOLIDAY_TEXT, Typeface.BOLD);
tag.setGravity(Gravity.CENTER);
tag.setIncludeFontPadding(false);
tag.setPadding(dp(10), dp(6), dp(10), dp(6));
tag.setBackground(roundedRect(COLOR_HOLIDAY_BG, dp(8), COLOR_HOLIDAY_BORDER, dp(1)));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
params.setMargins(0, 0, dp(6), 0);
tag.setLayoutParams(params);
return tag;
}
private LiturgicalDay holidayFromLiturgicalTitle(String title) {
if (title == null || title.trim().isEmpty()) {
return null;
}
String key = headingKey(title);
int rank = classifyLiturgicalTitle(key);
if (rank < 0) {
return null;
}
return new LiturgicalDay(title, title, rank);
}
private int classifyLiturgicalTitle(String key) {
if (key.contains("solemnity") || key.contains("solemnidad")) {
return RANK_SOLEMNITY;
}
if (key.contains("feast") || key.contains("fiesta")) {
return RANK_FEAST;
}
if (key.contains("memorial") || key.contains("memoria")) {
return RANK_MEMORIAL;
}
if (key.contains("ash wednesday")
|| key.contains("miercoles de ceniza")
|| key.contains("palm sunday")
|| key.contains("domingo de ramos")
|| key.contains("holy thursday")
|| key.contains("jueves santo")
|| key.contains("good friday")
|| key.contains("viernes santo")
|| key.contains("holy saturday")
|| key.contains("sabado santo")
|| key.contains("easter sunday")
|| key.contains("domingo de pascua")
|| key.contains("octave of easter")
|| key.contains("octava de pascua")
|| key.contains("pentecost")
|| key.contains("pentecostes")
|| key.contains("first sunday of advent")
|| key.contains("i domingo de adviento")) {
return RANK_HOLY_DAY;
}
return -1;
}
private LiturgicalDay knownCatholicHoliday(Calendar date) {
if (date == null) {
return null;
}
int year = date.get(Calendar.YEAR);
Calendar easter = easterSunday(year);
LiturgicalDay movable = holidayOnOffset(date, easter, -46,
"Ash Wednesday",
"Mi\u00e9rcoles de Ceniza",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, -7,
"Palm Sunday of the Passion of the Lord",
"Domingo de Ramos de la Pasi\u00f3n del Se\u00f1or",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, -3,
"Holy Thursday",
"Jueves Santo",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, -2,
"Good Friday",
"Viernes Santo",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, -1,
"Holy Saturday",
"S\u00e1bado Santo",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 0,
"Easter Sunday of the Resurrection of the Lord",
"Domingo de Pascua de la Resurrecci\u00f3n del Se\u00f1or",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 7,
"Second Sunday of Easter",
"II Domingo de Pascua",
RANK_HOLY_DAY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 39,
"Solemnity of the Ascension of the Lord",
"Solemnidad de la Ascensi\u00f3n del Se\u00f1or",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 49,
"Pentecost",
"Pentecost\u00e9s",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 50,
"Memorial of the Blessed Virgin Mary, Mother of the Church",
"Memoria de la Bienaventurada Virgen Mar\u00eda, Madre de la Iglesia",
RANK_MEMORIAL);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 56,
"Solemnity of the Most Holy Trinity",
"Solemnidad de la Sant\u00edsima Trinidad",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 60,
"Solemnity of the Most Holy Body and Blood of Christ",
"Solemnidad del Sant\u00edsimo Cuerpo y Sangre de Cristo",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
movable = holidayOnOffset(date, easter, 68,
"Solemnity of the Most Sacred Heart of Jesus",
"Solemnidad del Sagrado Coraz\u00f3n de Jes\u00fas",
RANK_SOLEMNITY);
if (movable != null) {
return movable;
}
Calendar advent = firstSundayOfAdvent(year);
if (isSameDay(date, shiftedDate(advent, -7))) {
return new LiturgicalDay(
"Solemnity of Our Lord Jesus Christ, King of the Universe",
"Solemnidad de Nuestro Se\u00f1or Jesucristo, Rey del Universo",
RANK_SOLEMNITY
);
}
if (isSameDay(date, advent)) {
return new LiturgicalDay(
"First Sunday of Advent",
"I Domingo de Adviento",
RANK_HOLY_DAY
);
}
Calendar baptism = sundayOnOrAfter(year, Calendar.JANUARY, 7);
if (isSameDay(date, baptism)) {
return new LiturgicalDay(
"Feast of the Baptism of the Lord",
"Fiesta del Bautismo del Se\u00f1or",
RANK_FEAST
);
}
Calendar holyFamily = holyFamilySunday(year);
if (isSameDay(date, holyFamily)) {
return new LiturgicalDay(
"Feast of the Holy Family",
"Fiesta de la Sagrada Familia",
RANK_FEAST
);
}
int month = date.get(Calendar.MONTH);
int day = date.get(Calendar.DAY_OF_MONTH);
if (month == Calendar.JANUARY && day == 1) {
return new LiturgicalDay(
"Solemnity of Mary, the Holy Mother of God",
"Solemnidad de Santa Mar\u00eda, Madre de Dios",
RANK_SOLEMNITY
);
}
if (month == Calendar.JANUARY && day == 6) {
return new LiturgicalDay(
"Solemnity of the Epiphany of the Lord",
"Solemnidad de la Epifan\u00eda del Se\u00f1or",
RANK_SOLEMNITY
);
}
if (month == Calendar.FEBRUARY && day == 2) {
return new LiturgicalDay(
"Feast of the Presentation of the Lord",
"Fiesta de la Presentaci\u00f3n del Se\u00f1or",
RANK_FEAST
);
}
if (month == Calendar.MARCH && day == 19) {
return new LiturgicalDay(
"Solemnity of Saint Joseph",
"Solemnidad de San Jos\u00e9",
RANK_SOLEMNITY
);
}
if (month == Calendar.MARCH && day == 25) {
return new LiturgicalDay(
"Solemnity of the Annunciation of the Lord",
"Solemnidad de la Anunciaci\u00f3n del Se\u00f1or",
RANK_SOLEMNITY
);
}
if (month == Calendar.MAY && day == 31) {
return new LiturgicalDay(
"Feast of the Visitation of the Blessed Virgin Mary",
"Fiesta de la Visitaci\u00f3n de la Bienaventurada Virgen Mar\u00eda",
RANK_FEAST
);
}
if (month == Calendar.JUNE && day == 24) {
return new LiturgicalDay(
"Solemnity of the Nativity of Saint John the Baptist",
"Solemnidad de la Natividad de San Juan Bautista",
RANK_SOLEMNITY
);
}
if (month == Calendar.JUNE && day == 29) {
return new LiturgicalDay(
"Solemnity of Saints Peter and Paul",
"Solemnidad de San Pedro y San Pablo",
RANK_SOLEMNITY
);
}
if (month == Calendar.AUGUST && day == 6) {
return new LiturgicalDay(
"Feast of the Transfiguration of the Lord",
"Fiesta de la Transfiguraci\u00f3n del Se\u00f1or",
RANK_FEAST
);
}
if (month == Calendar.AUGUST && day == 15) {
return new LiturgicalDay(
"Solemnity of the Assumption of the Blessed Virgin Mary",
"Solemnidad de la Asunci\u00f3n de la Bienaventurada Virgen Mar\u00eda",
RANK_SOLEMNITY
);
}
if (month == Calendar.SEPTEMBER && day == 14) {
return new LiturgicalDay(
"Feast of the Exaltation of the Holy Cross",
"Fiesta de la Exaltaci\u00f3n de la Santa Cruz",
RANK_FEAST
);
}
if (month == Calendar.NOVEMBER && day == 1) {
return new LiturgicalDay(
"Solemnity of All Saints",
"Solemnidad de Todos los Santos",
RANK_SOLEMNITY
);
}
if (month == Calendar.NOVEMBER && day == 2) {
return new LiturgicalDay(
"Commemoration of All the Faithful Departed",
"Conmemoraci\u00f3n de Todos los Fieles Difuntos",
RANK_HOLY_DAY
);
}
if (month == Calendar.NOVEMBER && day == 9) {
return new LiturgicalDay(
"Feast of the Dedication of the Lateran Basilica",
"Fiesta de la Dedicaci\u00f3n de la Bas\u00edlica de Letr\u00e1n",
RANK_FEAST
);
}
if (month == Calendar.DECEMBER && day == 8) {
return new LiturgicalDay(
"Solemnity of the Immaculate Conception",
"Solemnidad de la Inmaculada Concepci\u00f3n",
RANK_SOLEMNITY
);
}
if (month == Calendar.DECEMBER && day == 12) {
return new LiturgicalDay(
"Feast of Our Lady of Guadalupe",
"Fiesta de Nuestra Se\u00f1ora de Guadalupe",
RANK_FEAST
);
}
if (month == Calendar.DECEMBER && day == 25) {
return new LiturgicalDay(
"Solemnity of the Nativity of the Lord",
"Solemnidad de la Natividad del Se\u00f1or",
RANK_SOLEMNITY
);
}
return null;
}
private LiturgicalDay holidayOnOffset(
Calendar date,
Calendar baseDate,
int dayOffset,
String englishName,
String spanishName,
int rank
) {
if (isSameDay(date, shiftedDate(baseDate, dayOffset))) {
return new LiturgicalDay(englishName, spanishName, rank);
}
return null;
}
private Calendar calendarFromDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return startOfDay(calendar);
}
private Calendar shiftedDate(Calendar date, int dayOffset) {
Calendar shifted = startOfDay(date);
shifted.add(Calendar.DAY_OF_YEAR, dayOffset);
return shifted;
}
private Calendar easterSunday(int year) {
int a = year % 19;
int b = year / 100;
int c = year % 100;
int d = b / 4;
int e = b % 4;
int f = (b + 8) / 25;
int g = (b - f + 1) / 3;
int h = (19 * a + b - d - g + 15) % 30;
int i = c / 4;
int k = c % 4;
int l = (32 + 2 * e + 2 * i - h - k) % 7;
int m = (a + 11 * h + 22 * l) / 451;
int month = (h + l - 7 * m + 114) / 31;
int day = ((h + l - 7 * m + 114) % 31) + 1;
Calendar easter = Calendar.getInstance();
easter.clear();
easter.set(year, month - 1, day);
return startOfDay(easter);
}
private Calendar firstSundayOfAdvent(int year) {
return sundayOnOrAfter(year, Calendar.NOVEMBER, 27);
}
private Calendar sundayOnOrAfter(int year, int month, int day) {
Calendar date = Calendar.getInstance();
date.clear();
date.set(year, month, day);
date = startOfDay(date);
while (date.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
date.add(Calendar.DAY_OF_YEAR, 1);
}
return date;
}
private Calendar holyFamilySunday(int year) {
Calendar date = calendarDate(year, Calendar.DECEMBER, 26);
while (date.get(Calendar.DAY_OF_MONTH) <= 31) {
if (date.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
return date;
}
date.add(Calendar.DAY_OF_YEAR, 1);
}
return calendarDate(year, Calendar.DECEMBER, 30);
}
private Calendar calendarDate(int year, int month, int day) {
Calendar date = Calendar.getInstance();
date.clear();
date.set(year, month, day);
return startOfDay(date);
}
private View createStatusBlock() {
statusBlock = new LinearLayout(this);
statusBlock.setOrientation(LinearLayout.VERTICAL);
@@ -652,7 +1099,13 @@ public class MainActivity extends Activity {
sectionsLayout.removeAllViews();
statusBlock.setVisibility(View.VISIBLE);
dateText.setText(formatDisplayDate(date));
liturgyText.setText(isEnglish ? "Readings according to device date." : "Lecturas según la fecha del dispositivo.");
LiturgicalDay localHoliday = knownCatholicHoliday(calendarFromDate(date));
updateHolidayTags(localHoliday);
if (localHoliday == null) {
liturgyText.setText(isEnglish ? "Readings according to device date." : "Lecturas según la fecha del dispositivo.");
} else {
liturgyText.setText(localHoliday.displayName(isEnglish));
}
statusText.setText(isEnglish ? "Loading today's Word..." : "Cargando la Palabra de hoy...");
progressBar.setVisibility(View.VISIBLE);
retryButton.setVisibility(View.GONE);
@@ -674,6 +1127,8 @@ public class MainActivity extends Activity {
} else {
liturgyText.setText(reading.liturgicalTitle);
}
LiturgicalDay websiteHoliday = holidayFromLiturgicalTitle(reading.liturgicalTitle);
updateHolidayTags(websiteHoliday == null ? knownCatholicHoliday(selectedDateCalendar) : websiteHoliday);
if (isEnglish) {
addScriptureCard("Word of God", "Gospel of the Day", reading.gospel, true);
@@ -1215,6 +1670,35 @@ public class MainActivity extends Activity {
return Math.round(value * getResources().getDisplayMetrics().density);
}
private static class LiturgicalDay {
final String englishName;
final String spanishName;
final int rank;
LiturgicalDay(String englishName, String spanishName, int rank) {
this.englishName = englishName;
this.spanishName = spanishName;
this.rank = rank;
}
String displayName(boolean isEnglish) {
return isEnglish ? englishName : spanishName;
}
String rankLabel(boolean isEnglish) {
switch (rank) {
case RANK_SOLEMNITY:
return isEnglish ? "Solemnity" : "Solemnidad";
case RANK_FEAST:
return isEnglish ? "Feast" : "Fiesta";
case RANK_MEMORIAL:
return isEnglish ? "Memorial" : "Memoria";
default:
return isEnglish ? "Holy day" : "D\u00eda santo";
}
}
}
private static class DailyReading {
final String displayDate;
final String liturgicalTitle;