diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/PeriodicExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/PeriodicExporter.java index e3d5e3568..fb3ac9610 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/PeriodicExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/PeriodicExporter.java @@ -42,6 +42,9 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class PeriodicExporter extends BroadcastReceiver { private static final Logger LOG = LoggerFactory.getLogger(PeriodicExporter.class); + public static final String ACTION_DATABASE_EXPORT_SUCCESS = "nodomain.freeyourgadget.gadgetbridge.action.DATABASE_EXPORT_SUCCESS"; + public static final String ACTION_DATABASE_EXPORT_FAIL = "nodomain.freeyourgadget.gadgetbridge.action.DATABASE_EXPORT_FAIL"; + public static void enablePeriodicExport(Context context) { Prefs prefs = GBApplication.getPrefs(); GBApplication gbApp = GBApplication.app(); @@ -101,7 +104,8 @@ public class PeriodicExporter extends BroadcastReceiver { DBHelper helper = new DBHelper(localContext); String dst = GBApplication.getPrefs().getString(GBPrefs.AUTO_EXPORT_LOCATION, null); if (dst == null) { - LOG.info("Unable to export DB, export location not set"); + LOG.warn("Unable to export DB, export location not set"); + broadcastSuccess(false); return; } Uri dstUri = Uri.parse(dst); @@ -110,12 +114,29 @@ public class PeriodicExporter extends BroadcastReceiver { GBApplication gbApp = GBApplication.app(); gbApp.setLastAutoExportTimestamp(System.currentTimeMillis()); } + + broadcastSuccess(true); + + LOG.info("DB export completed"); } catch (Exception ex) { GB.updateExportFailedNotification(localContext.getString(R.string.notif_export_failed_title), localContext); LOG.info("Exception while exporting DB: ", ex); + broadcastSuccess(false); } } + private void broadcastSuccess(final boolean success) { + if (!GBApplication.getPrefs().getBoolean("intent_api_broadcast_export", false)) { + return; + } + + LOG.info("Broadcasting database export success={}", success); + + final String action = success ? ACTION_DATABASE_EXPORT_SUCCESS : ACTION_DATABASE_EXPORT_FAIL; + final Intent exportedNotifyIntent = new Intent(action); + localContext.sendBroadcast(exportedNotifyIntent); + } + @Override protected void onPostExecute(Object o) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/IntentApiReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/IntentApiReceiver.java new file mode 100644 index 000000000..fe85d7087 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/IntentApiReceiver.java @@ -0,0 +1,78 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.externalevents; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.database.PeriodicExporter; +import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + +public class IntentApiReceiver extends BroadcastReceiver { + private static final Logger LOG = LoggerFactory.getLogger(IntentApiReceiver.class); + + public static final String COMMAND_ACTIVITY_SYNC = "nodomain.freeyourgadget.gadgetbridge.command.ACTIVITY_SYNC"; + public static final String COMMAND_TRIGGER_EXPORT = "nodomain.freeyourgadget.gadgetbridge.command.TRIGGER_EXPORT"; + + @Override + public void onReceive(final Context context, final Intent intent) { + if (intent.getAction() == null) { + LOG.warn("Action is null"); + return; + } + + final Prefs prefs = GBApplication.getPrefs(); + + switch (intent.getAction()) { + case COMMAND_ACTIVITY_SYNC: + if (!prefs.getBoolean("intent_api_allow_activity_sync", false)) { + LOG.warn("Intent API activity sync trigger not allowed"); + return; + } + + LOG.info("Triggering activity sync"); + + GBApplication.deviceService().onFetchRecordedData(RecordedDataTypes.TYPE_ACTIVITY); + break; + case COMMAND_TRIGGER_EXPORT: + if (!prefs.getBoolean("intent_api_allow_trigger_export", false)) { + LOG.warn("Intent API export trigger not allowed"); + return; + } + + LOG.info("Triggering export"); + + final Intent exportIntent = new Intent(context, PeriodicExporter.class); + context.sendBroadcast(exportIntent); + break; + } + } + + public IntentFilter buildFilter() { + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(COMMAND_ACTIVITY_SYNC); + intentFilter.addAction(COMMAND_TRIGGER_EXPORT); + return intentFilter; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 14a36f942..28db8d06a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -61,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.CMWeatherReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.CalendarReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.DeviceSettingsReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.GenericWeatherReceiver; +import nodomain.freeyourgadget.gadgetbridge.externalevents.IntentApiReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.LineageOsWeatherReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.MusicPlaybackReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.OmniJawsObserver; @@ -328,6 +329,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere private GenericWeatherReceiver mGenericWeatherReceiver = null; private OmniJawsObserver mOmniJawsObserver = null; private final DeviceSettingsReceiver deviceSettingsReceiver = new DeviceSettingsReceiver(); + private final IntentApiReceiver intentApiReceiver = new IntentApiReceiver(); private final String[] mMusicActions = { "com.android.music.metachanged", @@ -496,6 +498,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere final IntentFilter deviceSettingsIntentFilter = new IntentFilter(); deviceSettingsIntentFilter.addAction(DeviceSettingsReceiver.COMMAND); registerReceiver(deviceSettingsReceiver, deviceSettingsIntentFilter); + + registerReceiver(intentApiReceiver, intentApiReceiver.buildFilter()); } private DeviceSupportFactory getDeviceSupportFactory() { @@ -1295,6 +1299,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere unregisterReceiver(bluetoothCommandReceiver); unregisterReceiver(deviceSettingsReceiver); + unregisterReceiver(intentApiReceiver); } @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0bf612cfb..4aa1c7e36 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -271,6 +271,7 @@ Call Dismissal Update on device Developer options + Intent API Authentication Mi Band address Pebble settings @@ -1973,6 +1974,12 @@ Flipper zero Bluetooth Intent API Allow controlling Bluetooth connection via Intent API + Allow activity sync trigger + Allow triggering activity sync via Intent API + Allow database export + Allow triggering database export via Intent API + Broadcast on database export + Broadcast an intent when database export finishes Shell Racing Turbo Speed Lights diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index d14fbc0ec..cb8356359 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -324,16 +324,15 @@ + - + + + + + + + +