mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Merge pull request 'introduce PersistanceProvider interface' (#6205)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6205
This commit is contained in:
+56
-4
@@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
|
||||
Dakhno, Daniele Gobbetti, José Rebelo, Petr Vaněk
|
||||
/* Copyright (C) 2016-2026 Andreas Shimokawa, Carsten Pfeiffer, Daniel
|
||||
Dakhno, Daniele Gobbetti, José Rebelo, Petr Vaněk, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -37,21 +42,25 @@ import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import de.greenrobot.dao.query.WhereCondition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
/**
|
||||
* Base class for all sample providers. A Sample provider is device specific and provides
|
||||
* access to the device specific samples. There are both read and write operations.
|
||||
* @param <T> the sample type
|
||||
*/
|
||||
public abstract class AbstractSampleProvider<T extends AbstractActivitySample> implements SampleProvider<T> {
|
||||
public abstract class AbstractSampleProvider<T extends AbstractActivitySample> implements SampleProvider<T>, PersistanceProvider<T> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractSampleProvider.class);
|
||||
|
||||
private static final WhereCondition[] NO_CONDITIONS = new WhereCondition[0];
|
||||
@@ -105,7 +114,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGBActivitySamples(T[] activitySamples) {
|
||||
public void addGBActivitySamples(@NonNull List<T> activitySamples) {
|
||||
getSampleDao().insertOrReplaceInTx(activitySamples);
|
||||
}
|
||||
|
||||
@@ -452,4 +461,47 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
||||
dummySample.setProvider(this);
|
||||
return dummySample;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persistSamples(@NonNull final List<T> samples, @Nullable final Context context) {
|
||||
if (samples.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG.debug(
|
||||
"Will persist {} {} samples",
|
||||
samples.size(),
|
||||
getClass().getSimpleName().replace("Provider", "")
|
||||
);
|
||||
|
||||
try {
|
||||
final DaoSession session = getSession();
|
||||
|
||||
final GBDevice gbDevice = getDevice();
|
||||
final Device device = DBHelper.findDevice(gbDevice, session);
|
||||
if (device == null) {
|
||||
LOG.warn("Device not found in database for '{}'", gbDevice.getAliasOrName());
|
||||
return false;
|
||||
}
|
||||
final long deviceId = device.getId();
|
||||
|
||||
final User user = DBHelper.getUser(session);
|
||||
final long userId = user.getId();
|
||||
|
||||
for (final T sample : samples) {
|
||||
sample.setProvider(this);
|
||||
sample.setDeviceId(deviceId);
|
||||
sample.setUserId(userId);
|
||||
}
|
||||
|
||||
addGBActivitySamples(samples);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Error saving samples", e);
|
||||
final Context ctx = (context != null) ? context : GBApplication.getContext();
|
||||
final String message = ctx.getString(R.string.persisting_samples_failed, e.getLocalizedMessage());
|
||||
toast(ctx, message, Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-9
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2023-2024 José Rebelo
|
||||
/* Copyright (C) 2023-2026 José Rebelo, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -31,6 +33,8 @@ import java.util.List;
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractTimeSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
@@ -45,7 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
*
|
||||
* @param <T> the sample type
|
||||
*/
|
||||
public abstract class AbstractTimeSampleProvider<T extends AbstractTimeSample> implements TimeSampleProvider<T> {
|
||||
public abstract class AbstractTimeSampleProvider<T extends AbstractTimeSample> implements TimeSampleProvider<T>, PersistanceProvider<T> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractTimeSampleProvider.class);
|
||||
|
||||
private final DaoSession mSession;
|
||||
@@ -207,9 +211,16 @@ public abstract class AbstractTimeSampleProvider<T extends AbstractTimeSample> i
|
||||
@NonNull
|
||||
protected abstract Property getDeviceIdentifierSampleProperty();
|
||||
|
||||
public void persistForDevice(final Context context, final GBDevice gbDevice, final List<T> samples) {
|
||||
/// @deprecated use {@link #persistSamples(List, Context)} instead
|
||||
@Deprecated
|
||||
public void persistForDevice(@NonNull final Context context, @Nullable final GBDevice gbDevice, @NonNull final List<T> samples) {
|
||||
persistSamples(samples, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persistSamples(@NonNull final List<T> samples, @Nullable final Context context) {
|
||||
if (samples.isEmpty()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG.debug(
|
||||
@@ -221,18 +232,30 @@ public abstract class AbstractTimeSampleProvider<T extends AbstractTimeSample> i
|
||||
try {
|
||||
final DaoSession session = getSession();
|
||||
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final GBDevice gbDevice = getDevice();
|
||||
final Device device = DBHelper.findDevice(gbDevice, session);
|
||||
if (device == null) {
|
||||
LOG.warn("Device not found in database for '{}'", gbDevice.getAliasOrName());
|
||||
return false;
|
||||
}
|
||||
final long deviceId = device.getId();
|
||||
|
||||
final User user = DBHelper.getUser(session);
|
||||
final long userId = user.getId();
|
||||
|
||||
for (final T sample : samples) {
|
||||
sample.setDevice(device);
|
||||
sample.setUser(user);
|
||||
sample.setDeviceId(deviceId);
|
||||
sample.setUserId(userId);
|
||||
}
|
||||
|
||||
this.addSamples(samples);
|
||||
addSamples(samples);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Error saving samples", e);
|
||||
GB.toast(context, "Error saving samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
final Context ctx = (context != null) ? context : GBApplication.getContext();
|
||||
final String message = ctx.getString(R.string.persisting_samples_failed, e.getLocalizedMessage());
|
||||
toast(ctx, message, Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/* Copyright (C) 2026 Thomas Kuehne
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class BaseActivitySummaryProvider(val device: GBDevice, val session: DaoSession) :
|
||||
PersistanceProvider<BaseActivitySummary> {
|
||||
override fun persistSamples(
|
||||
samples: List<BaseActivitySummary>, context: Context?
|
||||
): Boolean {
|
||||
if (samples.isEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
LOG.debug(
|
||||
"Will persist {} {}", samples.size, javaClass.getSimpleName().replace("Provider", "")
|
||||
)
|
||||
|
||||
try {
|
||||
val session = this.session
|
||||
|
||||
val gbDevice = this.device
|
||||
val device = DBHelper.findDevice(gbDevice, session)
|
||||
if (device == null) {
|
||||
LOG.warn("Device not found in database for '{}'", gbDevice.getAliasOrName())
|
||||
return false
|
||||
}
|
||||
val deviceId = device.id
|
||||
|
||||
val user = DBHelper.getUser(session)
|
||||
val userId = user.id
|
||||
|
||||
for (sample in samples) {
|
||||
sample.deviceId = deviceId
|
||||
sample.userId = userId
|
||||
}
|
||||
|
||||
val dao = session.baseActivitySummaryDao
|
||||
dao.insertOrReplaceInTx(samples)
|
||||
} catch (e: Exception) {
|
||||
LOG.error("Error saving samples", e)
|
||||
val ctx = context ?: GBApplication.getContext()
|
||||
val message: String =
|
||||
ctx.getString(R.string.persisting_samples_failed, e.localizedMessage)
|
||||
GB.toast(ctx, message, Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val LOG: Logger by lazy { LoggerFactory.getLogger(BaseActivitySummaryProvider::class.java) }
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2026 Thomas Kuehne
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.BatteryLevel
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class BatteryLevelProvider(val device: GBDevice, val session: DaoSession) :
|
||||
PersistanceProvider<BatteryLevel> {
|
||||
|
||||
override fun persistSamples(
|
||||
samples: List<BatteryLevel>, context: Context?
|
||||
): Boolean {
|
||||
if (samples.isEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
LOG.debug(
|
||||
"Will persist {} {} samples",
|
||||
samples.size,
|
||||
javaClass.getSimpleName().replace("Provider", "")
|
||||
)
|
||||
|
||||
try {
|
||||
val session = this.session
|
||||
|
||||
val gbDevice = this.device
|
||||
val device = DBHelper.findDevice(gbDevice, session)
|
||||
if (device == null) {
|
||||
LOG.warn("Device not found in database for '{}'", gbDevice.getAliasOrName())
|
||||
return false
|
||||
}
|
||||
val deviceId = device.id
|
||||
|
||||
for (sample in samples) {
|
||||
sample.deviceId = deviceId
|
||||
}
|
||||
|
||||
val dao = session.batteryLevelDao
|
||||
dao.insertOrReplaceInTx(samples)
|
||||
} catch (e: Exception) {
|
||||
LOG.error("Error saving samples", e)
|
||||
val ctx = context ?: GBApplication.getContext()
|
||||
val message: String =
|
||||
ctx.getString(R.string.persisting_samples_failed, e.localizedMessage)
|
||||
GB.toast(ctx, message, Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val LOG: Logger by lazy { LoggerFactory.getLogger(BatteryLevelProvider::class.java) }
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/* Copyright (C) 2026 Thomas Kuehne
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PersistanceProvider<T> {
|
||||
/// Set the relevant metadata for all samples like device ID, user ID, etc. and then
|
||||
/// stores them all in the database. Existing samples with identical primary key
|
||||
/// already stored in the database will be replaced.
|
||||
///
|
||||
/// @param context optional context for displaying error messages
|
||||
/// @return {@code false} if at least one sample couldn't be persisted.
|
||||
boolean persistSamples(@NonNull List<T> samples, @Nullable Context context);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ public interface SampleProvider<T extends AbstractActivitySample> {
|
||||
* timestamp will be overwritten.
|
||||
* @param activitySamples the samples to add
|
||||
*/
|
||||
void addGBActivitySamples(T[] activitySamples);
|
||||
void addGBActivitySamples(@NonNull List<T> activitySamples);
|
||||
|
||||
/**
|
||||
* Factory method to creates an empty sample of the correct type for this sample provider
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGBActivitySamples(AbstractActivitySample[] activitySamples) {
|
||||
public void addGBActivitySamples(@NonNull List<AbstractActivitySample> activitySamples) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ open class GenericHeartRateActivitySampleProvider(device: GBDevice, session: Dao
|
||||
throw UnsupportedOperationException("Read-only sample provider")
|
||||
}
|
||||
|
||||
override fun addGBActivitySamples(activitySamples: Array<GenericActivitySample>) {
|
||||
override fun addGBActivitySamples(activitySamples: List<GenericActivitySample>) {
|
||||
throw UnsupportedOperationException("Read-only sample provider")
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ open class GloryFitActivitySampleProvider(device: GBDevice, session: DaoSession)
|
||||
throw UnsupportedOperationException("Read-only sample provider")
|
||||
}
|
||||
|
||||
override fun addGBActivitySamples(activitySamples: Array<GenericActivitySample>) {
|
||||
override fun addGBActivitySamples(activitySamples: List<GenericActivitySample>) {
|
||||
throw UnsupportedOperationException("Read-only sample provider")
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huawei;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -239,7 +240,7 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGBActivitySamples(HuaweiActivitySample[] activitySamples) {
|
||||
public void addGBActivitySamples(@NonNull List<HuaweiActivitySample> activitySamples) {
|
||||
List<HuaweiActivitySample> newSamples = new ArrayList<>();
|
||||
for (HuaweiActivitySample sample : activitySamples) {
|
||||
HuaweiActivitySample start = copySample(sample);
|
||||
|
||||
+2
-2
@@ -52,7 +52,7 @@ public class SonyWena3ActivitySampleCombiner {
|
||||
alteredSamples.add(activitySample);
|
||||
}
|
||||
}
|
||||
activitySampleProvider.addGBActivitySamples(alteredSamples.toArray(new Wena3ActivitySample[alteredSamples.size()]));
|
||||
activitySampleProvider.addGBActivitySamples(alteredSamples);
|
||||
}
|
||||
|
||||
public void overlayHeartRateStartingAt(Date startDate, SonyWena3HeartRateSampleProvider heartRateSampleProvider) {
|
||||
@@ -73,6 +73,6 @@ public class SonyWena3ActivitySampleCombiner {
|
||||
alteredSamples.add(activitySample);
|
||||
}
|
||||
}
|
||||
activitySampleProvider.addGBActivitySamples(alteredSamples.toArray(new Wena3ActivitySample[alteredSamples.size()]));
|
||||
activitySampleProvider.addGBActivitySamples(alteredSamples);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -240,7 +240,7 @@ public class BraunBPW4500DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
final GenericBloodPressureSampleProvider provider =
|
||||
new GenericBloodPressureSampleProvider(getDevice(), session);
|
||||
provider.persistForDevice(getContext(), getDevice(), List.of(sample));
|
||||
provider.persistSamples(List.of(sample), getContext());
|
||||
|
||||
persistedMeasurements++;
|
||||
LOG.info("Persisted blood pressure measurement ({} total)", persistedMeasurements);
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ public class CmfActivitySync {
|
||||
}
|
||||
|
||||
LOG.debug("Will persist {} activity samples", samples.size());
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new CmfActivitySample[0]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Error saving activity samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
|
||||
+11
-44
@@ -41,10 +41,13 @@ import java.util.TreeMap;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractTimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.BaseActivitySummaryProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.BatteryLevelProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GarminSleepRestlessMomentsSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericMetricSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericTrainingLoadAcuteSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericTrainingLoadChronicSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.PersistanceProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminActivitySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminBodyEnergySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminEventSampleProvider;
|
||||
@@ -60,7 +63,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSleepStatsSampl
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSpo2SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminStressSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminWorkoutParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractTimeSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.BatteryLevel;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
@@ -616,7 +618,7 @@ public class FitImporter {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
final long deviceId = DBHelper.getDevice(gbDevice, session).getId();
|
||||
final long userId = DBHelper.getUser(session).getId();
|
||||
persistBattery(session, deviceId);
|
||||
persistAbstractSamples(batterySamples, new BatteryLevelProvider(gbDevice, session));
|
||||
persistGenericMetrics(session, deviceId, userId);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error saving generic samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
@@ -628,15 +630,6 @@ public class FitImporter {
|
||||
}
|
||||
}
|
||||
|
||||
private void persistBattery(final DaoSession session, final long deviceId) {
|
||||
if (!batterySamples.isEmpty()) {
|
||||
for (BatteryLevel batteryLevel : batterySamples) {
|
||||
batteryLevel.setDeviceId(deviceId);
|
||||
}
|
||||
session.getBatteryLevelDao().insertOrReplaceInTx(batterySamples);
|
||||
}
|
||||
}
|
||||
|
||||
private void persistGenericMetrics(final DaoSession session, final long deviceId, final long userId) {
|
||||
if (!genericMetricSamples.isEmpty()) {
|
||||
genericMetricSamples.forEach(sample -> {
|
||||
@@ -692,13 +685,7 @@ public class FitImporter {
|
||||
summary.setRawDetailsPath(file.getAbsolutePath());
|
||||
|
||||
try {
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final User user = DBHelper.getUser(session);
|
||||
|
||||
summary.setDevice(device);
|
||||
summary.setUser(user);
|
||||
|
||||
session.getBaseActivitySummaryDao().insertOrReplace(summary);
|
||||
persistAbstractSamples(List.of(summary), new BaseActivitySummaryProvider(gbDevice, session));
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error saving workout", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
@@ -874,20 +861,8 @@ public class FitImporter {
|
||||
}
|
||||
}
|
||||
|
||||
LOG.debug("Will persist {} activity samples", activitySamples.size());
|
||||
|
||||
try {
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final User user = DBHelper.getUser(session);
|
||||
|
||||
final GarminActivitySampleProvider sampleProvider = new GarminActivitySampleProvider(gbDevice, session);
|
||||
|
||||
for (final GarminActivitySample sample : activitySamples) {
|
||||
sample.setDevice(device);
|
||||
sample.setUser(user);
|
||||
}
|
||||
|
||||
sampleProvider.addGBActivitySamples(activitySamples.toArray(new GarminActivitySample[0]));
|
||||
persistAbstractSamples(activitySamples, new GarminActivitySampleProvider(gbDevice, session));
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error saving activity samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
@@ -924,9 +899,6 @@ public class FitImporter {
|
||||
|
||||
// We only need to fake sleep start and end times, the sample provider will take care of the rest
|
||||
try {
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final User user = DBHelper.getUser(session);
|
||||
|
||||
final GarminEventSampleProvider sampleProvider = new GarminEventSampleProvider(gbDevice, session);
|
||||
|
||||
final GarminEventSample sampleFallAsleep = new GarminEventSample();
|
||||
@@ -934,27 +906,22 @@ public class FitImporter {
|
||||
sampleFallAsleep.setEvent(74); // sleep
|
||||
sampleFallAsleep.setEventType(0); // sleep start
|
||||
sampleFallAsleep.setData(-1L); // in actual samples they're a garmin epoch, this way we can identify them
|
||||
sampleFallAsleep.setDevice(device);
|
||||
sampleFallAsleep.setUser(user);
|
||||
|
||||
final GarminEventSample sampleWakeUp = new GarminEventSample();
|
||||
sampleWakeUp.setTimestamp(wakeTimeMillis);
|
||||
sampleWakeUp.setEvent(74); // sleep
|
||||
sampleWakeUp.setEventType(1); // sleep end
|
||||
sampleWakeUp.setData(-1L); // in actual samples they're a garmin epoch, this way we can identify them
|
||||
sampleWakeUp.setDevice(device);
|
||||
sampleWakeUp.setUser(user);
|
||||
|
||||
sampleProvider.addSample(sampleFallAsleep);
|
||||
sampleProvider.addSample(sampleWakeUp);
|
||||
persistAbstractSamples(List.of(sampleFallAsleep, sampleWakeUp), sampleProvider);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error faking event samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends AbstractTimeSample> void persistAbstractSamples(final List<T> samples,
|
||||
final AbstractTimeSampleProvider<T> sampleProvider) {
|
||||
sampleProvider.persistForDevice(context, gbDevice, samples);
|
||||
private <T> void persistAbstractSamples(@NonNull final List<T> samples,
|
||||
@NonNull final PersistanceProvider<T> sampleProvider) {
|
||||
sampleProvider.persistSamples(samples, context);
|
||||
}
|
||||
|
||||
public static String getFilePath(final FitFileId fileId) {
|
||||
|
||||
+1
-4
@@ -21,9 +21,6 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Intent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -168,7 +165,7 @@ public class GenericBloodPressureSupport extends AbstractBTLESingleDeviceSupport
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
final GenericBloodPressureSampleProvider sampleProvider = new GenericBloodPressureSampleProvider(getDevice(), session);
|
||||
sampleProvider.persistForDevice(getContext(), getDevice(), List.of(sample));
|
||||
sampleProvider.persistSamples(List.of(sample), getContext());
|
||||
|
||||
persistedMeasurements++;
|
||||
} catch (final Exception e) {
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ class GenericHeartRateSupport : AbstractBTLESingleDeviceSupport(LOG) {
|
||||
}
|
||||
|
||||
val rrIntervalSampleProvider = HeartRrIntervalSampleProvider(this.device, db.getDaoSession())
|
||||
rrIntervalSampleProvider.persistForDevice(context, device, rrIntervalSampleList)
|
||||
rrIntervalSampleProvider.persistSamples(rrIntervalSampleList, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -210,7 +210,7 @@ class GloryFitFetcher(val mSupport: GloryFitSupport) {
|
||||
val session = handler.getDaoSession()
|
||||
val sampleProvider = GenericSleepStageSampleProvider(mSupport.device, session)
|
||||
|
||||
sampleProvider.persistForDevice(mSupport.context, mSupport.device, samples)
|
||||
sampleProvider.persistSamples(samples, mSupport.context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.toast(mSupport.context, "Error saving sleep session samples", Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
@@ -254,10 +254,9 @@ class GloryFitFetcher(val mSupport: GloryFitSupport) {
|
||||
val session = handler.getDaoSession()
|
||||
val sampleProvider = GloryFitStepsSampleProvider(mSupport.device, session)
|
||||
|
||||
sampleProvider.persistForDevice(
|
||||
mSupport.context,
|
||||
mSupport.device,
|
||||
Collections.singletonList(sample)
|
||||
sampleProvider.persistSamples(
|
||||
Collections.singletonList(sample),
|
||||
mSupport.context
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -306,7 +305,7 @@ class GloryFitFetcher(val mSupport: GloryFitSupport) {
|
||||
val session = handler.getDaoSession()
|
||||
val sampleProvider = GenericHeartRateSampleProvider(mSupport.device, session)
|
||||
|
||||
sampleProvider.persistForDevice(mSupport.context, mSupport.device, samples)
|
||||
sampleProvider.persistSamples(samples, mSupport.context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.toast(mSupport.context, "Error saving hr samples", Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
@@ -369,7 +368,7 @@ class GloryFitFetcher(val mSupport: GloryFitSupport) {
|
||||
val session = handler.getDaoSession()
|
||||
val sampleProvider = GenericSpo2SampleProvider(mSupport.device, session)
|
||||
|
||||
sampleProvider.persistForDevice(mSupport.context, mSupport.device, samples)
|
||||
sampleProvider.persistSamples(samples, mSupport.context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.toast(mSupport.context, "Error saving SpO2 samples", Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ public class FetchActivityOperation extends AbstractRepeatingFetchOperation {
|
||||
|
||||
timestamp.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new MiBandActivitySample[0]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
|
||||
timestamp.add(Calendar.MINUTE, -1);
|
||||
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ public class FetchHrvOperation extends AbstractRepeatingFetchOperation {
|
||||
final HuamiCoordinator coordinator = (HuamiCoordinator) getDevice().getDeviceCoordinator();
|
||||
final GenericHrvValueSampleProvider sampleProvider = coordinator.getHrvValueSampleProvider(getDevice(), session);
|
||||
|
||||
sampleProvider.persistForDevice(getContext(), getDevice(), samples);
|
||||
sampleProvider.persistSamples(samples, getContext());
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Error saving hrv samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ public class FetchSleepSessionOperation extends AbstractRepeatingFetchOperation
|
||||
|
||||
final HuamiSleepSessionSampleProvider sampleProvider = new HuamiSleepSessionSampleProvider(getDevice(), session);
|
||||
|
||||
sampleProvider.persistForDevice(getContext(), getDevice(), samples);
|
||||
sampleProvider.persistSamples(samples, getContext());
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Error saving sleep session samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ public class FetchTemperatureOperation extends AbstractRepeatingFetchOperation {
|
||||
final HuamiCoordinator coordinator = (HuamiCoordinator) getDevice().getDeviceCoordinator();
|
||||
final GenericTemperatureSampleProvider sampleProvider = coordinator.getTemperatureSampleProvider(getDevice(), session);
|
||||
|
||||
sampleProvider.persistForDevice(getContext(), getDevice(), samples);
|
||||
sampleProvider.persistSamples(samples, getContext());
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Error saving temperature samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
|
||||
+3
-7
@@ -89,7 +89,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.CameraRemote;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.ui.HuaweiStressCalibrationFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiActivitySample;
|
||||
@@ -101,9 +100,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStageSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStatsSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiStressSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSummarySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSwimSegmentsSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSwimSegmentsSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.export.AutoGpxExporter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationProviderType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationService;
|
||||
@@ -1881,7 +1877,7 @@ public class HuaweiSupportProvider {
|
||||
samples.add(activitySample);
|
||||
}
|
||||
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new HuaweiActivitySample[0]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to add sleep activity to database", e);
|
||||
}
|
||||
@@ -2734,8 +2730,8 @@ public class HuaweiSupportProvider {
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiSleepStatsSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, sleepStatsSamples);
|
||||
new HuaweiSleepStageSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, sleepStageSamples);
|
||||
new HuaweiSleepStatsSampleProvider(gbDevice, session).persistSamples(sleepStatsSamples, context);
|
||||
new HuaweiSleepStageSampleProvider(gbDevice, session).persistSamples(sleepStageSamples, context);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save sleep, continue");
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ public class HuaweiDictionarySyncEmotion implements HuaweiDictionarySyncInterfa
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiEmotionsSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, emotionsSamples);
|
||||
new HuaweiEmotionsSampleProvider(gbDevice, session).persistSamples(emotionsSamples, context);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save emotions samples, continue");
|
||||
}
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ public class HuaweiDictionarySyncHRV implements HuaweiDictionarySyncInterface {
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiHrvValueSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, hrvSamples);
|
||||
new HuaweiHrvValueSampleProvider(gbDevice, session).persistSamples(hrvSamples, context);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save HRV samples, continue");
|
||||
}
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class HuaweiDictionarySyncSkinTemperature implements HuaweiDictionarySyn
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiTemperatureSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, temperatureSamples);
|
||||
new HuaweiTemperatureSampleProvider(gbDevice, session).persistSamples(temperatureSamples, context);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save skin temperature samples, continue");
|
||||
}
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class HuaweiDictionarySyncSleepApnea implements HuaweiDictionarySyncInte
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiSleepApneaSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, sleepApneaSamples);
|
||||
new HuaweiSleepApneaSampleProvider(gbDevice, session).persistSamples(sleepApneaSamples, context);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save sleep apnea samples, continue");
|
||||
}
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ public class GetStepDataRequest extends Request {
|
||||
}
|
||||
}
|
||||
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new HuaweiActivitySample[0]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to add step data to database", e);
|
||||
}
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
@@ -146,7 +147,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
|
||||
}
|
||||
|
||||
ID115SampleProvider provider = new ID115SampleProvider(getDevice(), dbHandler.getDaoSession());
|
||||
provider.addGBActivitySamples(sampleArray);
|
||||
provider.addGBActivitySamples(Arrays.asList(sampleArray));
|
||||
} catch (Exception ex) {
|
||||
GB.toast(getContext(), "Error saving activity data: " + ex.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1638,7 +1638,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
overlayList.add(new WatchXPlusHealthActivityOverlay(sample.getTimestamp(), sample.getTimestamp()+300, sample.getRawKind(), sample.getDeviceId(), sample.getUserId(), sample.getRawWatchXPlusHealthData()));
|
||||
}
|
||||
overlayDao.insertOrReplaceInTx(overlayList);
|
||||
provider.addGBActivitySamples(samples.toArray(new WatchXPlusActivitySample[0]));
|
||||
provider.addGBActivitySamples(samples);
|
||||
|
||||
handleEndOfDataChunks(chunkNo, type);
|
||||
} else if (DataType.HEART_RATE.equals(type)) {
|
||||
@@ -1658,7 +1658,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||
samples.add(sample);
|
||||
}
|
||||
provider.addGBActivitySamples(samples.toArray(new WatchXPlusActivitySample[0]));
|
||||
provider.addGBActivitySamples(samples);
|
||||
|
||||
handleEndOfDataChunks(chunkNo, type);
|
||||
} else {
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.UUID;
|
||||
@@ -389,7 +390,7 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
||||
minutes++;
|
||||
timestampInSeconds += 60;
|
||||
}
|
||||
provider.addGBActivitySamples(samples);
|
||||
provider.addGBActivitySamples(Arrays.asList(samples));
|
||||
} finally {
|
||||
activityStruct.bufferFlushed(minutes);
|
||||
}
|
||||
|
||||
+1
-1
@@ -379,7 +379,7 @@ class OneTouchSupport : AbstractBTLESingleDeviceSupport(LOG) {
|
||||
GBApplication.acquireDB().use { handler ->
|
||||
val session = handler.getDaoSession()
|
||||
val sampleProvider = GlucoseSampleProvider(device, session)
|
||||
sampleProvider.persistForDevice(context, device, samples)
|
||||
sampleProvider.persistSamples(samples, context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.toast(context, "Error storing glucose readings", Toast.LENGTH_LONG, GB.ERROR, e)
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.UUID;
|
||||
@@ -105,7 +106,7 @@ class AppMessageHandlerMisfit extends AppMessageHandler {
|
||||
}
|
||||
LOG.info("total steps for above period: " + totalSteps);
|
||||
|
||||
sampleProvider.addGBActivitySamples(misfitSamples);
|
||||
sampleProvider.addGBActivitySamples(Arrays.asList(misfitSamples));
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error acquiring database", e);
|
||||
return null;
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@@ -115,7 +116,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth {
|
||||
samples[j].setProvider(sampleProvider);
|
||||
}
|
||||
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
sampleProvider.addGBActivitySamples(Arrays.asList(samples));
|
||||
} catch (Exception ex) {
|
||||
LOG.debug(ex.getMessage());
|
||||
}
|
||||
|
||||
+3
-2
@@ -15,6 +15,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@@ -296,7 +297,7 @@ public class PolarH10DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
final Long userId = DBHelper.getUser(db.getDaoSession()).getId();
|
||||
final Long deviceId = DBHelper.getDevice(getDevice(), db.getDaoSession()).getId();
|
||||
final PolarH10ActivitySample sample = new PolarH10ActivitySample((int) (info.getTimestamp() / 1000), deviceId, userId, info.getHeartRate());
|
||||
polarSampleProvider.addGBActivitySamples(new PolarH10ActivitySample[]{sample});
|
||||
polarSampleProvider.addGBActivitySamples(Collections.singletonList(sample));
|
||||
|
||||
final ArrayList<@NotNull Integer> rrIntervals = info.getRrIntervals();
|
||||
if (!rrIntervals.isEmpty()) {
|
||||
@@ -310,7 +311,7 @@ public class PolarH10DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
}
|
||||
|
||||
final HeartRrIntervalSampleProvider rrIntervalSampleProvider = new HeartRrIntervalSampleProvider(this.getDevice(), db.getDaoSession());
|
||||
rrIntervalSampleProvider.persistForDevice(getContext(), getDevice(), rrIntervalSampleList);
|
||||
rrIntervalSampleProvider.persistSamples(rrIntervalSampleList, getContext());
|
||||
}
|
||||
|
||||
newSamples = true;
|
||||
|
||||
+1
-1
@@ -633,7 +633,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
||||
LOG.debug("Activity samples parsed successfully: {}", Arrays.stream(samples).toList());
|
||||
}
|
||||
|
||||
provider.addGBActivitySamples(samples);
|
||||
provider.addGBActivitySamples(Arrays.asList(samples));
|
||||
|
||||
if (saveRawActivityFiles) {
|
||||
writeFile("activity_qhybrid", String.valueOf(System.currentTimeMillis()), fileData);
|
||||
|
||||
+2
-1
@@ -80,6 +80,7 @@ import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -1284,7 +1285,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
samples[i] = entries.get(i).toDAOActivitySample(userId, deviceId);
|
||||
}
|
||||
provider.addGBActivitySamples(samples);
|
||||
provider.addGBActivitySamples(Arrays.asList(samples));
|
||||
// SpO2, should be empty for an unsupported device
|
||||
ArrayList<HybridHRSpo2Sample> spo2Samples = parser.getSpo2Samples();
|
||||
HybridHRSpo2SampleProvider spo2Provider = new HybridHRSpo2SampleProvider(getDeviceSupport().getDevice(), dbHandler.getDaoSession());
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class StepsPacketParser extends OneBytePerSamplePacketParser {
|
||||
i++;
|
||||
currentSampleDate = timestampOfSampleAtIndex(i);
|
||||
}
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new Wena3ActivitySample[samples.size()]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
|
||||
SonyWena3ActivitySampleCombiner combiner = new SonyWena3ActivitySampleCombiner(sampleProvider);
|
||||
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
|
||||
sample.setDeviceId(deviceId);
|
||||
sample.setUserId(userId);
|
||||
}
|
||||
provider.addGBActivitySamples(activitySamples.toArray(new WithingsSteelHRActivitySample[0]));
|
||||
provider.addGBActivitySamples(activitySamples);
|
||||
} catch (Exception ex) {
|
||||
logger.warn("Error saving activity data: " + ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ public class DailyDetailsParser extends XiaomiActivityParser {
|
||||
sample.setUser(user);
|
||||
sample.setProvider(sampleProvider);
|
||||
}
|
||||
sampleProvider.addGBActivitySamples(samples.toArray(new XiaomiActivitySample[0]));
|
||||
sampleProvider.addGBActivitySamples(samples);
|
||||
|
||||
return true;
|
||||
} catch (final Exception e) {
|
||||
|
||||
@@ -1436,6 +1436,7 @@
|
||||
<string name="activity_db_management_empty_DB">Empty Database</string>
|
||||
<string name="activity_db_management_exportimport_label">Export and Import</string>
|
||||
<string name="activity_db_management_empty_db_warning">Warning! By pushing this button you will wipe your database and start from scratch.</string>
|
||||
<string name="persisting_samples_failed">Error saving samples: %1$s</string>
|
||||
<string name="Cancel">Cancel</string>
|
||||
<string name="Delete">Delete</string>
|
||||
<string name="delete_device_and_retain_files">Keep Files</string>
|
||||
|
||||
Reference in New Issue
Block a user