diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java index 7f3b0b99b5..fb322a8239 100644 --- a/app/src/main/java/info/nightscout/androidaps/Constants.java +++ b/app/src/main/java/info/nightscout/androidaps/Constants.java @@ -25,8 +25,6 @@ public class Constants { public static final int hoursToKeepInDatabase = 72; public static final int daysToKeepHistoryInDatabase = 30; - public static final long keepAliveMsecs = 5 * 60 * 1000L; - // SMS COMMUNICATOR public static final long remoteBolusMinDistance = 15 * 60 * 1000L; diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index ff33ec930f..8fa855cd7b 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -313,9 +313,7 @@ public class MainActivity extends NoSplashAppCompatActivity { return true; case R.id.nav_exit: log.debug("Exiting"); - MainApp.instance().stopKeepAliveService(); RxBus.INSTANCE.send(new EventAppExit()); - MainApp.closeDbHelper(); finish(); System.runFinalization(); System.exit(0); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 9933f75ac9..0506f461be 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -1,12 +1,14 @@ package info.nightscout.androidaps; import android.app.Application; -import android.content.BroadcastReceiver; import android.content.IntentFilter; import android.content.res.Resources; import android.os.SystemClock; +import androidx.annotation.ColorRes; import androidx.annotation.PluralsRes; +import androidx.annotation.StringRes; +import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.crashlytics.android.Crashlytics; @@ -99,7 +101,6 @@ import static info.nightscout.androidaps.plugins.constraints.versionChecker.Vers public class MainApp extends Application { private static Logger log = LoggerFactory.getLogger(L.CORE); - private static KeepAliveReceiver keepAliveReceiver; private static MainApp sInstance; public static Resources sResources; @@ -112,9 +113,7 @@ public class MainApp extends Application { private static ArrayList pluginsList = null; private static DataReceiver dataReceiver = new DataReceiver(); - private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver(); - private LocalBroadcastManager lbm; - BroadcastReceiver btReceiver; + private static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver(); TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver; public static boolean devBranch; @@ -168,7 +167,6 @@ public class MainApp extends Application { //trigger here to see the new version on app start after an update triggerCheckVersion(); - //setBTReceiver(); if (pluginsList == null) { pluginsList = new ArrayList<>(); @@ -240,10 +238,10 @@ public class MainApp extends Application { new Thread(() -> { SystemClock.sleep(5000); ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null); - startKeepAliveService(); }).start(); } + new Thread(() -> KeepAliveReceiver.setAlarm(this)).start(); doMigrations(); } @@ -273,7 +271,7 @@ public class MainApp extends Application { private void registerLocalBroadcastReceiver() { - lbm = LocalBroadcastManager.getInstance(this); + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT)); @@ -288,33 +286,21 @@ public class MainApp extends Application { lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL)); //register alarms - lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM)); - lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT)); - lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM)); - lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_URGENT_ALARM)); + lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM)); + lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT)); + lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM)); + lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM)); this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver(); this.timeDateOrTZChangeReceiver.registerBroadcasts(this); } - private void startKeepAliveService() { - if (keepAliveReceiver == null) { - keepAliveReceiver = new KeepAliveReceiver(); - keepAliveReceiver.setAlarm(this); - } - } - - public void stopKeepAliveService() { - if (keepAliveReceiver != null) - KeepAliveReceiver.cancelAlarm(this); - } - - public static String gs(int id) { + public static String gs(@StringRes int id) { return sResources.getString(id); } - public static String gs(int id, Object... args) { + public static String gs(@StringRes int id, Object... args) { return sResources.getString(id, args); } @@ -322,8 +308,8 @@ public class MainApp extends Application { return sResources.getQuantityString(id, quantity, args); } - public static int gc(int id) { - return sResources.getColor(id); + public static int gc(@ColorRes int id) { + return ContextCompat.getColor(instance(), id); } public static MainApp instance() { @@ -334,13 +320,6 @@ public class MainApp extends Application { return sDatabaseHelper; } - public static void closeDbHelper() { - if (sDatabaseHelper != null) { - sDatabaseHelper.close(); - sDatabaseHelper = null; - } - } - public static FirebaseAnalytics getFirebaseAnalytics() { return mFirebaseAnalytics; } @@ -443,20 +422,12 @@ public class MainApp extends Application { public void onTerminate() { if (L.isEnabled(L.CORE)) log.debug("onTerminate"); - super.onTerminate(); - if (sDatabaseHelper != null) { - sDatabaseHelper.close(); - sDatabaseHelper = null; - } - if (btReceiver != null) { - unregisterReceiver(btReceiver); - } - - if (timeDateOrTZChangeReceiver != null) { + if (timeDateOrTZChangeReceiver != null) unregisterReceiver(timeDateOrTZChangeReceiver); - } unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE); + KeepAliveReceiver.cancelAlarm(this); + super.onTerminate(); } public static int dpToPx(int dp) { diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 74f7ed234e..cd83c79f8e 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -194,15 +194,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return newVersion; } - /** - * Close the database connections and clear any cached DAOs. - */ - @Override - public void close() { - super.close(); - } - - public long size(String database) { return DatabaseUtils.queryNumEntries(getReadableDatabase(), database); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java index faabbd8192..3a776ab541 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java @@ -110,9 +110,7 @@ public class ImportExportPrefs { SP.putBoolean(R.string.key_setupwizard_processed, true); OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> { log.debug("Exiting"); - MainApp.instance().stopKeepAliveService(); RxBus.INSTANCE.send(new EventAppExit()); - MainApp.closeDbHelper(); if (context instanceof Activity) { ((Activity) context).finish(); } diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java deleted file mode 100644 index 652d2ef2c0..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java +++ /dev/null @@ -1,125 +0,0 @@ -package info.nightscout.androidaps.receivers; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.PowerManager; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.events.EventProfileNeedsUpdate; -import info.nightscout.androidaps.interfaces.APSInterface; -import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; -import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; -import info.nightscout.androidaps.queue.commands.Command; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.LocalAlertUtils; -import info.nightscout.androidaps.utils.T; - - -/** - * Created by mike on 07.07.2016. - */ -public class KeepAliveReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(L.CORE); - public static final long STATUS_UPDATE_FREQUENCY = T.mins(15).msecs(); - private static long lastReadStatus = 0; - private static long lastRun = 0; - private static long lastIobUpload = 0; - - public static void cancelAlarm(Context context) { - Intent intent = new Intent(context, KeepAliveReceiver.class); - PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0); - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - alarmManager.cancel(sender); - } - - @Override - public void onReceive(Context context, Intent rIntent) { - PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:KeepAliveReciever"); - wl.acquire(); - - LocalAlertUtils.shortenSnoozeInterval(); - LocalAlertUtils.checkStaleBGAlert(); - checkPump(); - checkAPS(); - - if (L.isEnabled(L.CORE)) - log.debug("KeepAlive received"); - wl.release(); - } - - private void checkAPS() { - APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS(); - boolean shouldUploadStatus = false; - if (usedAPS == null) shouldUploadStatus = true; - else if (DateUtil.isOlderThan(usedAPS.getLastAPSRun(), 5)) shouldUploadStatus = true; - - if (DateUtil.isOlderThan(lastIobUpload, 5) && shouldUploadStatus) { - lastIobUpload = DateUtil.now(); - NSUpload.uploadDeviceStatus(); - } - } - - private void checkPump() { - final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - final Profile profile = ProfileFunctions.getInstance().getProfile(); - if (pump != null && profile != null) { - long lastConnection = pump.lastDataTime(); - boolean isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); - boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep; - - if (L.isEnabled(L.CORE)) - log.debug("Last connection: " + DateUtil.dateAndTimeString(lastConnection)); - // sometimes keepalive broadcast stops - // as as workaround test if readStatus was requested before an alarm is generated - if (lastReadStatus != 0 && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) { - LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated); - } - - if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { - RxBus.INSTANCE.send(new EventProfileNeedsUpdate()); - } else if (isStatusOutdated && !pump.isBusy()) { - lastReadStatus = System.currentTimeMillis(); - ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Status outdated.", null); - } else if (isBasalOutdated && !pump.isBusy()) { - lastReadStatus = System.currentTimeMillis(); - ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Basal outdated.", null); - } - } - if (lastRun != 0 && System.currentTimeMillis() - lastRun > T.mins(10).msecs()) { - log.error("KeepAlive fail"); - FabricPrivacy.getInstance().logCustom("KeepAliveFail"); - } - lastRun = System.currentTimeMillis(); - } - - //called by MainApp at first app start - public void setAlarm(Context context) { - - LocalAlertUtils.shortenSnoozeInterval(); - LocalAlertUtils.presnoozeAlarms(); - - AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - Intent i = new Intent(context, KeepAliveReceiver.class); - PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0); - try { - pi.send(); - } catch (PendingIntent.CanceledException e) { - } - am.cancel(pi); - am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constants.keepAliveMsecs, pi); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt new file mode 100644 index 0000000000..7ca4f962ae --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt @@ -0,0 +1,121 @@ +package info.nightscout.androidaps.receivers + +import android.app.AlarmManager +import android.app.PendingIntent +import android.app.PendingIntent.CanceledException +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.PowerManager +import android.os.SystemClock +import info.nightscout.androidaps.events.EventProfileNeedsUpdate +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.bus.RxBus.send +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.LocalAlertUtils +import info.nightscout.androidaps.utils.T +import org.slf4j.LoggerFactory +import kotlin.math.abs + +class KeepAliveReceiver : BroadcastReceiver() { + private var lastReadStatus: Long = 0 + private var lastRun: Long = 0 + private var lastIobUpload: Long = 0 + + override fun onReceive(context: Context, rIntent: Intent) { + if (L.isEnabled(L.CORE)) + log.debug("KeepAlive received") + val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager + val wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:KeepAliveReceiver") + wl.acquire(T.mins(2).msecs()) + LocalAlertUtils.shortenSnoozeInterval() + LocalAlertUtils.checkStaleBGAlert() + checkPump() + checkAPS() + wl.release() + } + + companion object { + private val log = LoggerFactory.getLogger(L.CORE) + + private val KEEP_ALIVE_MILLISECONDS = T.mins(5).msecs() + private val STATUS_UPDATE_FREQUENCY = T.mins(15).msecs() + private val IOB_UPDATE_FREQUENCY = T.mins(5).msecs() + + //called by MainApp at first app start + @JvmStatic + fun setAlarm(context: Context) { + if (L.isEnabled(L.CORE)) + log.debug("KeepAlive scheduled") + SystemClock.sleep(5000) // wait for app initialization + LocalAlertUtils.shortenSnoozeInterval() + LocalAlertUtils.presnoozeAlarms() + val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + val i = Intent(context, KeepAliveReceiver::class.java) + val pi = PendingIntent.getBroadcast(context, 0, i, 0) + try { + pi.send() + } catch (e: CanceledException) { + } + am.cancel(pi) + am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), KEEP_ALIVE_MILLISECONDS, pi) + } + + @JvmStatic + fun cancelAlarm(context: Context) { + if (L.isEnabled(L.CORE)) + log.debug("KeepAlive canceled") + val intent = Intent(context, KeepAliveReceiver::class.java) + val sender = PendingIntent.getBroadcast(context, 0, intent, 0) + val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + alarmManager.cancel(sender) + } + } + + private fun checkAPS() { + val usedAPS = ConfigBuilderPlugin.getPlugin().activeAPS + var shouldUploadStatus = false + if (usedAPS == null) shouldUploadStatus = true + else if (DateUtil.isOlderThan(usedAPS.lastAPSRun, 5)) shouldUploadStatus = true + if (DateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY) && shouldUploadStatus) { + lastIobUpload = DateUtil.now() + NSUpload.uploadDeviceStatus() + } + } + + private fun checkPump() { + val pump = ConfigBuilderPlugin.getPlugin().activePump + val profile = ProfileFunctions.getInstance().profile + if (pump != null && profile != null) { + val lastConnection = pump.lastDataTime() + val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis() + val isBasalOutdated = abs(profile.basal - pump.baseBasalRate) > pump.pumpDescription.basalStep + if (L.isEnabled(L.CORE)) + log.debug("Last connection: " + DateUtil.dateAndTimeString(lastConnection)) + // sometimes keep alive broadcast stops + // as as workaround test if readStatus was requested before an alarm is generated + if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) { + LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated) + } + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().commandQueue.isRunning(Command.CommandType.BASALPROFILE)) { + send(EventProfileNeedsUpdate()) + } else if (isStatusOutdated && !pump.isBusy) { + lastReadStatus = System.currentTimeMillis() + ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("KeepAlive. Status outdated.", null) + } else if (isBasalOutdated && !pump.isBusy) { + lastReadStatus = System.currentTimeMillis() + ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("KeepAlive. Basal outdated.", null) + } + } + if (lastRun != 0L && System.currentTimeMillis() - lastRun > T.mins(10).msecs()) { + log.error("KeepAlive fail") + FabricPrivacy.getInstance().logCustom("KeepAliveFail") + } + lastRun = System.currentTimeMillis() + } +} \ No newline at end of file