From 846ff8f56594d822389fef8a23cca3e1f5660d62 Mon Sep 17 00:00:00 2001 From: Forrest Guice Date: Wed, 21 Sep 2022 21:25:34 -0700 Subject: [PATCH] updateIllumination Fixes app crash (NPE) at higher latitudes when displaying moon illumination. #623 It shouldn't be assumed that all locations experience moonrise/moonset on a given day. The lunar noon (and lunar midnight) calendars are possibly null and must be checked first. If lunar noon doesn't occur, display illumination at solar noon instead. --- .../suntimeswidget/MoonPhaseView.java | 14 ++++++++--- .../calculator/SuntimesMoonData.java | 25 +++++++++++++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/forrestguice/suntimeswidget/MoonPhaseView.java b/app/src/main/java/com/forrestguice/suntimeswidget/MoonPhaseView.java index b06f7fd23..d3ad06873 100644 --- a/app/src/main/java/com/forrestguice/suntimeswidget/MoonPhaseView.java +++ b/app/src/main/java/com/forrestguice/suntimeswidget/MoonPhaseView.java @@ -40,6 +40,7 @@ import com.forrestguice.suntimeswidget.themes.SuntimesTheme; import java.text.NumberFormat; +import java.util.Calendar; @SuppressWarnings("Convert2Diamond") public class MoonPhaseView extends LinearLayout @@ -282,18 +283,23 @@ public void updateIllumination(Context context) illumNote = (context == null ? illum : context.getString(R.string.moon_illumination, illum)); } else { - boolean sharedNoon = (data.getLunarNoonToday().getTimeInMillis() == data.getLunarNoonTomorrow().getTimeInMillis()); + Calendar noonToday = data.getLunarNoonToday(); + long noonTodayMillis = ((noonToday != null) ? noonToday.getTimeInMillis() : 0); + Calendar noonTomorrow = data.getLunarNoonTomorrow(); + long noonTomorrowMillis = ((noonTomorrow != null) ? noonTomorrow.getTimeInMillis() : 0); + boolean sharedNoon = (noonTodayMillis == noonTomorrowMillis); + String illumTime; if (tomorrowMode) { illum = formatter.format(data.getMoonIlluminationTomorrow()); - illumTime = utils.calendarTimeShortDisplayString(context, data.getLunarNoonTomorrow()).toString(); + illumTime = utils.calendarTimeShortDisplayString(context, noonTomorrow).toString(); } else { illum = formatter.format(data.getMoonIlluminationToday()); illumTime = (sharedNoon) - ? utils.calendarDateTimeDisplayString(context, data.getLunarNoonToday()).toString() - : utils.calendarTimeShortDisplayString(context, data.getLunarNoonToday()).toString(); + ? utils.calendarDateTimeDisplayString(context, noonToday).toString() + : utils.calendarTimeShortDisplayString(context, noonToday).toString(); } illumNote = (context == null ? illum : context.getString(sharedNoon ? R.string.moon_illumination : R.string.moon_illumination_at, illum, illumTime)); } diff --git a/app/src/main/java/com/forrestguice/suntimeswidget/calculator/SuntimesMoonData.java b/app/src/main/java/com/forrestguice/suntimeswidget/calculator/SuntimesMoonData.java index cc9b9e233..46be61dfd 100644 --- a/app/src/main/java/com/forrestguice/suntimeswidget/calculator/SuntimesMoonData.java +++ b/app/src/main/java/com/forrestguice/suntimeswidget/calculator/SuntimesMoonData.java @@ -1,5 +1,5 @@ /** - Copyright (C) 2018-2019 Forrest Guice + Copyright (C) 2018-2022 Forrest Guice This file is part of SuntimesWidget. SuntimesWidget is free software: you can redistribute it and/or modify @@ -232,7 +232,7 @@ public void calculate() riseSet[2] = calculator.getMoonTimesForDate(otherCalendar); ArrayList midnights = findMidnight(); - if (midnights.size() >= 1) + if (midnights.size() > 0) { midnightToday = midnights.get(midnights.size() - 1); for (Calendar midnight : midnights) @@ -254,7 +254,7 @@ public void calculate() } ArrayList noons = findNoon(); - if (noons.size() >= 1) + if (noons.size() > 0) { noonToday = noons.get(noons.size() - 1); for (Calendar noon : noons) @@ -275,12 +275,12 @@ public void calculate() //Log.d("DEBUG", "using approximate lunar noon tomorrow"); } - double moonIllumination = ((noonToday != null) ? calculator.getMoonIlluminationForDate(noonToday) : 0); + double moonIllumination = getMoonIllumination(noonToday, todaysCalendar); if (moonIllumination >= 0) { this.moonIlluminationToday = moonIllumination; } - double moonIllumination1 = ((noonTomorrow != null) ? calculator.getMoonIlluminationForDate(noonTomorrow) : 0); + double moonIllumination1 = getMoonIllumination(noonTomorrow, otherCalendar); if (moonIllumination1 >= 0) { this.moonIlluminationTomorrow = moonIllumination1; } @@ -296,6 +296,21 @@ public void calculate() moonPhaseTomorrow = findPhaseOf(midnight1); } + private double getMoonIllumination(Calendar lunarNoon, Calendar today) + { + if (calculator != null) + { + if (lunarNoon != null) { + return calculator.getMoonIlluminationForDate(lunarNoon); + } + Calendar solarNoon = calculator.getSolarNoonCalendarForDate(today); + if (solarNoon != null) { + return calculator.getMoonIlluminationForDate(solarNoon); + } + } + return 0; + } + /** * Create a list of lunar noon times by examining the moonrise/moonset times from yesterday, today, and tomorrow. * @return an ArrayList of Calendar; contains up to 3 items (empty if not found).