1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-30 22:12:55 +01:00

More WIP on db refactoring

This commit is contained in:
cpfeiffer 2016-05-13 23:47:47 +02:00
parent d0c8483d92
commit 8ca821ab8a
25 changed files with 360 additions and 176 deletions

View File

@ -51,7 +51,7 @@ public class GBDaoGenerator {
user.addIdProperty(); user.addIdProperty();
user.addStringProperty("name").notNull(); user.addStringProperty("name").notNull();
user.addDateProperty("birthday").notNull(); user.addDateProperty("birthday").notNull();
user.addIntProperty("sex").notNull(); user.addIntProperty("gender").notNull();
Property userId = userAttributes.addLongProperty("userId").notNull().getProperty(); Property userId = userAttributes.addLongProperty("userId").notNull().getProperty();
user.addToMany(userAttributes, userId); user.addToMany(userAttributes, userId);
@ -78,7 +78,7 @@ public class GBDaoGenerator {
device.addIdProperty(); device.addIdProperty();
device.addStringProperty("name").notNull(); device.addStringProperty("name").notNull();
device.addStringProperty("manufacturer").notNull(); device.addStringProperty("manufacturer").notNull();
device.addStringProperty("identifier").notNull().javaDocGetterAndSetter("The fixed identifier, i.e. MAC address of the device."); device.addStringProperty("identifier").notNull().unique().javaDocGetterAndSetter("The fixed identifier, i.e. MAC address of the device.");
Property deviceId = deviceAttributes.addLongProperty("deviceId").notNull().getProperty(); Property deviceId = deviceAttributes.addLongProperty("deviceId").notNull().getProperty();
device.addToMany(deviceAttributes, deviceId); device.addToMany(deviceAttributes, deviceId);
@ -99,22 +99,25 @@ public class GBDaoGenerator {
private static Entity addMiBandActivitySample(Schema schema, Entity user, Entity device) { private static Entity addMiBandActivitySample(Schema schema, Entity user, Entity device) {
// public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type, int customValue) { // public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type, int customValue) {
Entity activitySample = addEntity(schema, "MiBandActivitySample"); Entity activitySample = addEntity(schema, "MiBandActivitySample");
addCommonActivitySampleProperties(schema, activitySample, user, device);
addHeartRateProperties(activitySample);
return activitySample;
}
private static void addHeartRateProperties(Entity activitySample) {
activitySample.addImport(MODEL_PACKAGE + ".HeartRateSample"); activitySample.addImport(MODEL_PACKAGE + ".HeartRateSample");
activitySample.implementsInterface("HeartRateSample"); activitySample.implementsInterface("HeartRateSample");
addCommonAcivitySampleProperties(schema, activitySample, user, device);
activitySample.addIntProperty("heartRate"); activitySample.addIntProperty("heartRate");
return activitySample;
} }
private static Entity addPebbleActivitySample(Schema schema, Entity user, Entity device) { private static Entity addPebbleActivitySample(Schema schema, Entity user, Entity device) {
// public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type, int customValue) { // public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type, int customValue) {
Entity activitySample = addEntity(schema, "PebbleActivitySample"); Entity activitySample = addEntity(schema, "PebbleActivitySample");
addCommonAcivitySampleProperties(schema, activitySample, user, device); addCommonActivitySampleProperties(schema, activitySample, user, device);
// activitySample.addIntProperty("heartrate").notNull();
return activitySample; return activitySample;
} }
private static void addCommonAcivitySampleProperties(Schema schema, Entity activitySample, Entity user, Entity device) { private static void addCommonActivitySampleProperties(Schema schema, Entity activitySample, Entity user, Entity device) {
activitySample.setSuperclass("AbstractActivitySample"); activitySample.setSuperclass("AbstractActivitySample");
activitySample.addImport(MODEL_PACKAGE + ".ActivitySample"); activitySample.addImport(MODEL_PACKAGE + ".ActivitySample");
activitySample.addImport(MAIN_PACKAGE + ".devices.SampleProvider"); activitySample.addImport(MAIN_PACKAGE + ".devices.SampleProvider");

View File

@ -6,8 +6,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build; import android.os.Build;
import android.os.Build.VERSION; import android.os.Build.VERSION;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -27,10 +27,8 @@ import java.util.concurrent.locks.ReentrantLock;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender; import ch.qos.logback.core.Appender;
import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBConstants; import nodomain.freeyourgadget.gadgetbridge.database.DBConstants;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DaoHandler;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService;
@ -52,7 +50,6 @@ public class GBApplication extends Application {
// Since this class must not log to slf4j, we use plain android.util.Log // Since this class must not log to slf4j, we use plain android.util.Log
private static final String TAG = "GBApplication"; private static final String TAG = "GBApplication";
private static GBApplication context; private static GBApplication context;
private static DBHandler mActivityDatabaseHandler;
private static final Lock dbLock = new ReentrantLock(); private static final Lock dbLock = new ReentrantLock();
private static DeviceService deviceService; private static DeviceService deviceService;
private static SharedPreferences sharedPrefs; private static SharedPreferences sharedPrefs;
@ -210,7 +207,6 @@ public class GBApplication extends Application {
SQLiteDatabase db = helper.getWritableDatabase(); SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db); DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession(); daoSession = daoMaster.newSession();
mActivityDatabaseHandler = new DaoHandler(daoMaster, helper);
} }
public static DaoSession getDaoSession() { public static DaoSession getDaoSession() {
@ -242,6 +238,7 @@ public class GBApplication extends Application {
* @see #releaseDB() * @see #releaseDB()
*/ */
public static DBHandler acquireDB() throws GBException { public static DBHandler acquireDB() throws GBException {
// TODO: implement locking with greendao?
try { try {
if (dbLock.tryLock(30, TimeUnit.SECONDS)) { if (dbLock.tryLock(30, TimeUnit.SECONDS)) {
return mActivityDatabaseHandler; return mActivityDatabaseHandler;
@ -303,12 +300,13 @@ public class GBApplication extends Application {
* @return true on successful deletion * @return true on successful deletion
*/ */
public static synchronized boolean deleteActivityDatabase() { public static synchronized boolean deleteActivityDatabase() {
if (mActivityDatabaseHandler != null) { // TODO: flush, close, reopen db
mActivityDatabaseHandler.close(); // if (mActivityDatabaseHandler != null) {
mActivityDatabaseHandler = null; // mActivityDatabaseHandler.close();
} // mActivityDatabaseHandler = null;
// }
boolean result = getContext().deleteDatabase(DBConstants.DATABASE_NAME); boolean result = getContext().deleteDatabase(DBConstants.DATABASE_NAME);
mActivityDatabaseHandler = new ActivityDatabaseHandler(getContext()); // mActivityDatabaseHandler = new Activity7DatabaseHandler(getContext());
return result; return result;
} }

View File

@ -23,7 +23,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
/** /**
* Implementation of SleepAlarmWidget functionality. When pressing the widget, an alarm will be set * Implementation of SleepAlarmWidget functionality. When pressing the widget, an alarm will be set
* to trigger after a predefined number of hours. A toast will confirm the user about this. The * to trigger after a predefined number of hours. A toast will confirm the user about this. The
* value is retrieved using ActivityUser.().getActivityUserSleepDuration(). * value is retrieved using ActivityUser.().getSleepDuration().
*/ */
public class SleepAlarmWidget extends AppWidgetProvider { public class SleepAlarmWidget extends AppWidgetProvider {
@ -71,7 +71,7 @@ public class SleepAlarmWidget extends AppWidgetProvider {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); super.onReceive(context, intent);
if (ACTION.equals(intent.getAction())) { if (ACTION.equals(intent.getAction())) {
int userSleepDuration = new ActivityUser().getActivityUserSleepDuration(); int userSleepDuration = new ActivityUser().getSleepDuration();
// current timestamp // current timestamp
GregorianCalendar calendar = new GregorianCalendar(); GregorianCalendar calendar = new GregorianCalendar();
// add preferred sleep duration // add preferred sleep duration

View File

@ -48,6 +48,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
@ -463,13 +464,13 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
colors.add(akActivity.color); colors.add(akActivity.color);
} }
activityEntries.add(createBarEntry(value, i)); activityEntries.add(createBarEntry(value, i));
if (hr && isValidHeartRateValue(sample.getCustomValue())) { if (hr && isValidHeartRateValue(((HeartRateSample)sample).getHeartRate())) {
if (lastHrSampleIndex > -1 && i - lastHrSampleIndex > HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) { if (lastHrSampleIndex > -1 && i - lastHrSampleIndex > HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) {
heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1)); heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
heartrateEntries.add(createLineEntry(0, i - 1)); heartrateEntries.add(createLineEntry(0, i - 1));
} }
heartrateEntries.add(createLineEntry(sample.getCustomValue(), i)); heartrateEntries.add(createLineEntry(((HeartRateSample)sample).getHeartRate(), i));
lastHrSampleIndex = i; lastHrSampleIndex = i;
} }

View File

@ -17,6 +17,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationScript; import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationScript;
import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration; import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
@ -68,7 +69,7 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
values.put(KEY_PROVIDER, sample.getProvider().getID()); values.put(KEY_PROVIDER, sample.getProvider().getID());
values.put(KEY_INTENSITY, sample.getRawIntensity()); values.put(KEY_INTENSITY, sample.getRawIntensity());
values.put(KEY_STEPS, sample.getSteps()); values.put(KEY_STEPS, sample.getSteps());
values.put(KEY_CUSTOM_SHORT, sample.getCustomValue()); // values.put(KEY_CUSTOM_SHORT, sample.getCustomValue());
values.put(KEY_TYPE, sample.getRawKind()); values.put(KEY_TYPE, sample.getRawKind());
db.insert(TABLE_GBACTIVITYSAMPLES, null, values); db.insert(TABLE_GBACTIVITYSAMPLES, null, values);
@ -86,7 +87,13 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
* @param customShortValue * @param customShortValue
*/ */
@Override @Override
public void addGBActivitySample(int timestamp, int provider, int intensity, int steps, int kind, int customShortValue) { public void addGBActivitySample(AbstractActivitySample sample) {
float intensity = sample.getIntensity();
int steps = sample.getSteps();
int kind = sample.getRawKind();
int timestamp = sample.getTimestamp();
int customShortValue = 0;
if (intensity < 0) { if (intensity < 0) {
LOG.error("negative intensity received, ignoring"); LOG.error("negative intensity received, ignoring");
intensity = 0; intensity = 0;
@ -104,7 +111,7 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
try (SQLiteDatabase db = this.getWritableDatabase()) { try (SQLiteDatabase db = this.getWritableDatabase()) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(KEY_TIMESTAMP, timestamp); values.put(KEY_TIMESTAMP, timestamp);
values.put(KEY_PROVIDER, provider); // values.put(KEY_PROVIDER, provider);
values.put(KEY_INTENSITY, intensity); values.put(KEY_INTENSITY, intensity);
values.put(KEY_STEPS, steps); values.put(KEY_STEPS, steps);
values.put(KEY_TYPE, kind); values.put(KEY_TYPE, kind);
@ -115,7 +122,7 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
} }
@Override @Override
public void addGBActivitySamples(ActivitySample[] activitySamples) { public void addGBActivitySamples(AbstractActivitySample[] activitySamples) {
try (SQLiteDatabase db = this.getWritableDatabase()) { try (SQLiteDatabase db = this.getWritableDatabase()) {
String sql = "INSERT INTO " + TABLE_GBACTIVITYSAMPLES + " (" + KEY_TIMESTAMP + "," + String sql = "INSERT INTO " + TABLE_GBACTIVITYSAMPLES + " (" + KEY_TIMESTAMP + "," +
@ -131,7 +138,7 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
statement.bindLong(3, activitySample.getRawIntensity()); statement.bindLong(3, activitySample.getRawIntensity());
statement.bindLong(4, activitySample.getSteps()); statement.bindLong(4, activitySample.getSteps());
statement.bindLong(5, activitySample.getRawKind()); statement.bindLong(5, activitySample.getRawKind());
statement.bindLong(6, activitySample.getCustomValue()); // statement.bindLong(6, activitySample.getCustomValue());
statement.execute(); statement.execute();
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();

View File

@ -7,6 +7,7 @@ import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public interface DBHandler { public interface DBHandler {
@ -29,9 +30,9 @@ public interface DBHandler {
List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider); List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider);
void addGBActivitySample(int timestamp, int provider, int intensity, int steps, int kind, int heartrate); void addGBActivitySample(AbstractActivitySample sample);
void addGBActivitySamples(ActivitySample[] activitySamples); void addGBActivitySamples(AbstractActivitySample[] activitySamples);
SQLiteDatabase getWritableDatabase(); SQLiteDatabase getWritableDatabase();

View File

@ -9,10 +9,26 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import de.greenrobot.dao.query.Query;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes;
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributesDao;
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceDao;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.entities.UserAttributes;
import nodomain.freeyourgadget.gadgetbridge.entities.UserDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
public class DBHelper { public class DBHelper {
private final Context context; private final Context context;
@ -99,4 +115,70 @@ public class DBHelper {
} }
return ""; return "";
} }
public static User getUser() {
DaoSession session = GBApplication.getDaoSession();
UserDao userDao = session.getUserDao();
List<User> users = userDao.loadAll();
if (users.isEmpty()) {
User user = createUser(session);
return user;
}
return users.get(0); // TODO: multiple users support?
}
private static User createUser(DaoSession session) {
ActivityUser prefsUser = new ActivityUser();
User user = new User();
user.setName(prefsUser.getName());
user.setBirthday(prefsUser.getUserBirthday());
user.setGender(prefsUser.getGender());
session.getUserDao().insert(user);
List<UserAttributes> userAttributes = user.getUserAttributesList();
UserAttributes attributes = new UserAttributes();
attributes.setValidFromUTC(DateTimeUtils.todayUTC());
attributes.setHeightCM(prefsUser.getHeightCm());
attributes.setWeightKG(prefsUser.getWeightKg());
attributes.setUserId(user.getId());
session.getUserAttributesDao().insert(attributes);
userAttributes.add(attributes);
return user;
}
public static Device getDevice(GBDevice gbDevice) {
DaoSession session = GBApplication.getDaoSession();
DeviceDao deviceDao = session.getDeviceDao();
Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build();
List<Device> devices = query.list();
if (devices.isEmpty()) {
Device device = createDevice(session, gbDevice);
return device;
}
return devices.get(0);
}
private static Device createDevice(DaoSession session, GBDevice gbDevice) {
Device device = new Device();
device.setIdentifier(gbDevice.getAddress());
device.setName(gbDevice.getName());
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
device.setManufacturer(coordinator.getManufacturer());
session.getDeviceDao().insert(device);
List<DeviceAttributes> deviceAttributes = device.getDeviceAttributesList();
DeviceAttributes attributes = new DeviceAttributes();
attributes.setDeviceId(device.getId());
attributes.setValidFromUTC(DateTimeUtils.todayUTC());
attributes.setFirmwareVersion1(gbDevice.getFirmwareVersion());
// TODO: firmware version2? generically or through DeviceCoordinator?
DeviceAttributesDao attributesDao = session.getDeviceAttributesDao();
attributesDao.insert(attributes);
deviceAttributes.add(attributes);
return device;
}
} }

View File

@ -1,85 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.database;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.List;
import de.greenrobot.dao.AbstractDao;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public class DaoHandler implements DBHandler {
private final DaoMaster mDaoMaster;
private final SQLiteOpenHelper openHelper;
public DaoHandler(DaoMaster master, DaoMaster.DevOpenHelper helper) {
mDaoMaster = master;
openHelper = helper;
}
@Override
public void close() {
getHelper().close();
}
@Override
public SQLiteOpenHelper getHelper() {
return openHelper;
}
@Override
public void release() {
GBApplication.releaseDB();
}
@Override
public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return null;
}
@Override
public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return null;
}
@Override
public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) {
return null;
}
@Override
public void addGBActivitySample(int timestamp, int provider, int intensity, int steps, int kind, int heartrate) {
}
@Override
public void addGBActivitySamples(ActivitySample[] activitySamples, AbstractDao<ActivitySample,?> dao) {
for (ActivitySample sample : activitySamples) {
dao.insert(sample);
}
}
@Override
public SQLiteDatabase getWritableDatabase() {
return mDaoMaster.getDatabase();
}
@Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind, SampleProvider provider) {
}
@Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) {
}
@Override
public int fetchLatestTimestamp(SampleProvider provider) {
return 0;
}
}

View File

@ -1,16 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.devices; package nodomain.freeyourgadget.gadgetbridge.devices;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.Arrays;
import java.util.List; import java.util.List;
import de.greenrobot.dao.AbstractDao; import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.query.QueryBuilder; import de.greenrobot.dao.query.QueryBuilder;
import de.greenrobot.dao.query.WhereCondition; import de.greenrobot.dao.query.WhereCondition;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public abstract class AbstractSampleProvider<T extends ActivitySample> implements SampleProvider { public abstract class AbstractSampleProvider<T extends ActivitySample> implements SampleProvider, DBHandler {
private static final WhereCondition[] NO_CONDITIONS = new WhereCondition[0]; private static final WhereCondition[] NO_CONDITIONS = new WhereCondition[0];
private final DaoSession mSession; private final DaoSession mSession;
@ -34,22 +40,76 @@ public abstract class AbstractSampleProvider<T extends ActivitySample> implement
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP); return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP);
} }
public void addGBActivitySample(int timestamp, int provider, int intensity, int steps, int kind, int heartrate) { @Override
public void close() {
// TESTING: NOOP
}
@Override
public SQLiteOpenHelper getHelper() {
// TESTING: NOOP
return null;
}
@Override
public void release() {
// TESTING: NOOP
}
@Override
public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ALL);
}
@Override
public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ACTIVITY);
}
@Override
public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_SLEEP);
}
@Override
public void addGBActivitySample(AbstractActivitySample activitySample) {
getSampleDao().insert((T) activitySample);
}
@Override
public void addGBActivitySamples(AbstractActivitySample[] activitySamples) {
getSampleDao().insertInTx((T[]) activitySamples);
}
@Override
public SQLiteDatabase getWritableDatabase() {
// TESTING: NOOP
return null;
}
@Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind, SampleProvider provider) {
} }
public void addGBActivitySamples(ActivitySample[] activitySamples) { @Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) {
} }
@Override
public int fetchLatestTimestamp(SampleProvider provider) {
return 0;
}
// SQLiteDatabase getWritableDatabase(); // SQLiteDatabase getWritableDatabase();
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) { public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) {
// TODO: implement
} }
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) { public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) {
// TODO: implement
} }
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) { protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {

View File

@ -109,4 +109,9 @@ public interface DeviceCoordinator {
boolean supportsAlarmConfiguration(); boolean supportsAlarmConfiguration();
int getTapString(); int getTapString();
/**
* Returns the readable name of the manufacturer.
*/
String getManufacturer();
} }

View File

@ -93,4 +93,9 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
public int getTapString() { public int getTapString() {
return 0; return 0;
} }
@Override
public String getManufacturer() {
return "unknown";
}
} }

View File

@ -84,6 +84,11 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
return R.string.tap_connected_device_for_activity; return R.string.tap_connected_device_for_activity;
} }
@Override
public String getManufacturer() {
return "Xiaomi";
}
public static boolean hasValidUserInfo() { public static boolean hasValidUserInfo() {
String dummyMacAddress = MiBandService.MAC_ADDRESS_FILTER_1_1A + ":00:00:00"; String dummyMacAddress = MiBandService.MAC_ADDRESS_FILTER_1_1A + ":00:00:00";
try { try {
@ -122,10 +127,10 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
UserInfo info = UserInfo.create( UserInfo info = UserInfo.create(
miBandAddress, miBandAddress,
prefs.getString(MiBandConst.PREF_USER_ALIAS, null), prefs.getString(MiBandConst.PREF_USER_ALIAS, null),
activityUser.getActivityUserGender(), activityUser.getGender(),
activityUser.getActivityUserAge(), activityUser.getAge(),
activityUser.getActivityUserHeightCm(), activityUser.getHeightCm(),
activityUser.getActivityUserWeightKg(), activityUser.getWeightKg(),
0 0
); );
return info; return info;

View File

@ -16,7 +16,7 @@ public class MorpheuzSampleProvider extends AbstractSampleProvider<PebbleActivit
protected float movementDivisor = 5000f; protected float movementDivisor = 5000f;
protected MorpheuzSampleProvider(DaoSession session) { public MorpheuzSampleProvider(DaoSession session) {
super(session); super(session);
} }

View File

@ -88,4 +88,9 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator {
public int getTapString() { public int getTapString() {
return R.string.tap_connected_device_for_app_mananger; return R.string.tap_connected_device_for_app_mananger;
} }
@Override
public String getManufacturer() {
return "Pebble";
}
} }

View File

@ -335,6 +335,15 @@ public class GBDevice implements Parcelable {
return getDeviceInfos().size() > 0; return getDeviceInfos().size() > 0;
} }
public ItemWithDetails getDeviceInfo(String name) {
for (ItemWithDetails item : getDeviceInfos()) {
if (name.equals(item.getName())) {
return item;
}
}
return null;
}
public List<ItemWithDetails> getDeviceInfos() { public List<ItemWithDetails> getDeviceInfos() {
List<ItemWithDetails> result = new ArrayList<>(); List<ItemWithDetails> result = new ArrayList<>();
if (mDeviceInfos != null) { if (mDeviceInfos != null) {

View File

@ -1,8 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.model; package nodomain.freeyourgadget.gadgetbridge.model;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
/** /**
@ -10,12 +14,14 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
*/ */
public class ActivityUser { public class ActivityUser {
private String activityUserName;
private Integer activityUserGender; private Integer activityUserGender;
private Integer activityUserYearOfBirth; private Integer activityUserYearOfBirth;
private Integer activityUserHeightCm; private Integer activityUserHeightCm;
private Integer activityUserWeightKg; private Integer activityUserWeightKg;
private Integer activityUserSleepDuration; private Integer activityUserSleepDuration;
private static final String defaultUserName = "gadgetbridge-user";
public static final int defaultUserGender = 0; public static final int defaultUserGender = 0;
public static final int defaultUserYearOfBirth = 0; public static final int defaultUserYearOfBirth = 0;
public static final int defaultUserAge = 0; public static final int defaultUserAge = 0;
@ -23,37 +29,34 @@ public class ActivityUser {
public static final int defaultUserWeightKg = 70; public static final int defaultUserWeightKg = 70;
public static final int defaultUserSleepDuration = 7; public static final int defaultUserSleepDuration = 7;
public static final String PREF_USER_NAME = "mi_user_alias";
public static final String PREF_USER_YEAR_OF_BIRTH = "activity_user_year_of_birth"; public static final String PREF_USER_YEAR_OF_BIRTH = "activity_user_year_of_birth";
public static final String PREF_USER_GENDER = "activity_user_gender"; public static final String PREF_USER_GENDER = "activity_user_gender";
public static final String PREF_USER_HEIGHT_CM = "activity_user_height_cm"; public static final String PREF_USER_HEIGHT_CM = "activity_user_height_cm";
public static final String PREF_USER_WEIGHT_KG = "activity_user_weight_kg"; public static final String PREF_USER_WEIGHT_KG = "activity_user_weight_kg";
public static final String PREF_USER_SLEEP_DURATION = "activity_user_sleep_duration"; public static final String PREF_USER_SLEEP_DURATION = "activity_user_sleep_duration";
public int getActivityUserWeightKg() { public ActivityUser() {
if (activityUserWeightKg == null) {
fetchPreferences(); fetchPreferences();
} }
public String getName() {
return activityUserName;
}
public int getWeightKg() {
return activityUserWeightKg; return activityUserWeightKg;
} }
public int getActivityUserGender() { public int getGender() {
if (activityUserGender == null) {
fetchPreferences();
}
return activityUserGender; return activityUserGender;
} }
public int getActivityUserYearOfBirth() { public int getYearOfBirth() {
if (activityUserYearOfBirth == null) {
fetchPreferences();
}
return activityUserYearOfBirth; return activityUserYearOfBirth;
} }
public int getActivityUserHeightCm() { public int getHeightCm() {
if (activityUserHeightCm == null) {
fetchPreferences();
}
return activityUserHeightCm; return activityUserHeightCm;
} }
@ -61,18 +64,15 @@ public class ActivityUser {
* @return the user defined sleep duration or the default value when none is set or the stored * @return the user defined sleep duration or the default value when none is set or the stored
* value is out of any logical bounds. * value is out of any logical bounds.
*/ */
public int getActivityUserSleepDuration() { public int getSleepDuration() {
if (activityUserSleepDuration == null) {
fetchPreferences();
}
if (activityUserSleepDuration < 1 || activityUserSleepDuration > 24) { if (activityUserSleepDuration < 1 || activityUserSleepDuration > 24) {
activityUserSleepDuration = defaultUserSleepDuration; activityUserSleepDuration = defaultUserSleepDuration;
} }
return activityUserSleepDuration; return activityUserSleepDuration;
} }
public int getActivityUserAge() { public int getAge() {
int userYear = getActivityUserYearOfBirth(); int userYear = getYearOfBirth();
int age = 25; int age = 25;
if (userYear > 1900) { if (userYear > 1900) {
age = Calendar.getInstance().get(Calendar.YEAR) - userYear; age = Calendar.getInstance().get(Calendar.YEAR) - userYear;
@ -85,10 +85,17 @@ public class ActivityUser {
private void fetchPreferences() { private void fetchPreferences() {
Prefs prefs = GBApplication.getPrefs(); Prefs prefs = GBApplication.getPrefs();
activityUserName = prefs.getString(PREF_USER_NAME, defaultUserName);
activityUserGender = prefs.getInt(PREF_USER_GENDER, defaultUserGender); activityUserGender = prefs.getInt(PREF_USER_GENDER, defaultUserGender);
activityUserHeightCm = prefs.getInt(PREF_USER_HEIGHT_CM, defaultUserHeightCm); activityUserHeightCm = prefs.getInt(PREF_USER_HEIGHT_CM, defaultUserHeightCm);
activityUserWeightKg = prefs.getInt(PREF_USER_WEIGHT_KG, defaultUserWeightKg); activityUserWeightKg = prefs.getInt(PREF_USER_WEIGHT_KG, defaultUserWeightKg);
activityUserYearOfBirth = prefs.getInt(PREF_USER_YEAR_OF_BIRTH, defaultUserYearOfBirth); activityUserYearOfBirth = prefs.getInt(PREF_USER_YEAR_OF_BIRTH, defaultUserYearOfBirth);
activityUserSleepDuration = prefs.getInt(PREF_USER_SLEEP_DURATION, defaultUserSleepDuration); activityUserSleepDuration = prefs.getInt(PREF_USER_SLEEP_DURATION, defaultUserSleepDuration);
} }
public Date getUserBirthday() {
Calendar cal = DateTimeUtils.getCalendarUTC();
cal.set(GregorianCalendar.YEAR, getYearOfBirth());
return cal.getTime();
}
} }

View File

@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter;
@ -312,7 +313,8 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
DBHandler dbHandler = null; DBHandler dbHandler = null;
try { try {
dbHandler = GBApplication.acquireDB(); // dbHandler = GBApplication.acquireDB();
dbHandler = new MiBandSampleProvider(GBApplication.getDaoSession());
int minutes = 0; int minutes = 0;
try (SQLiteDatabase db = dbHandler.getWritableDatabase()) { // explicitly keep the db open while looping over the samples try (SQLiteDatabase db = dbHandler.getWritableDatabase()) { // explicitly keep the db open while looping over the samples
int timestampInSeconds = (int) (activityStruct.activityDataTimestampProgress.getTimeInMillis() / 1000); int timestampInSeconds = (int) (activityStruct.activityDataTimestampProgress.getTimeInMillis() / 1000);
@ -321,9 +323,6 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
} }
int numSamples = activityStruct.activityDataHolderProgress / bpm; int numSamples = activityStruct.activityDataHolderProgress / bpm;
AbstractActivitySample[] samples = new AbstractActivitySample[numSamples]; AbstractActivitySample[] samples = new AbstractActivitySample[numSamples];
DaoSession daoSession = GBApplication.getDaoSession();
SampleProvider sampleProvider = new MiBandSampleProvider(daoSession);
MiBandActivitySampleDao dao = daoSession.getMiBandActivitySampleDao();
for (int i = 0; i < activityStruct.activityDataHolderProgress; i += bpm) { for (int i = 0; i < activityStruct.activityDataHolderProgress; i += bpm) {
category = activityStruct.activityDataHolder[i]; category = activityStruct.activityDataHolder[i];
@ -334,6 +333,7 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
LOG.debug("heartrate received: " + (heartrate & 0xff)); LOG.debug("heartrate received: " + (heartrate & 0xff));
} }
// TODO: user and device id
Long userId = null; Long userId = null;
Long deviceId = null; Long deviceId = null;
@ -346,13 +346,13 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
userId, userId,
deviceId, deviceId,
heartrate & 0xff); heartrate & 0xff);
samples[minutes].setProvider(sampleProvider); // samples[minutes].setProvider(dbHandler);
// next minute // next minute
minutes++; minutes++;
timestampInSeconds += 60; timestampInSeconds += 60;
} }
dbHandler.addGBActivitySamples(samples, dao); dbHandler.addGBActivitySamples(samples);
} finally { } finally {
activityStruct.bufferFlushed(minutes); activityStruct.bufferFlushed(minutes);
} }

View File

@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
public class AppMessageHandler { public class AppMessageHandler {
protected final PebbleProtocol mPebbleProtocol; protected final PebbleProtocol mPebbleProtocol;
@ -28,4 +29,11 @@ public class AppMessageHandler {
public GBDeviceEvent[] pushMessage() { public GBDeviceEvent[] pushMessage() {
return null; return null;
} }
protected PebbleActivitySample createSample(int timestamp, int intensity, int steps, int type) {
// TODO: user and device id
Long userId = null;
Long deviceId = null;
return new PebbleActivitySample(null, timestamp, intensity, steps, type, userId, deviceId);
}
} }

View File

@ -18,6 +18,9 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleGadgetBridgeSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public class AppMessageHandlerGBPebble extends AppMessageHandler { public class AppMessageHandlerGBPebble extends AppMessageHandler {
@ -49,17 +52,21 @@ public class AppMessageHandlerGBPebble extends AppMessageHandler {
int offset_seconds = 0; int offset_seconds = 0;
DBHandler db = null; DBHandler db = null;
try { try {
db = GBApplication.acquireDB(); // db = GBApplication.acquireDB();
db = new PebbleGadgetBridgeSampleProvider(GBApplication.getDaoSession());
AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples_remaining];
int i = 0;
while (samples_remaining-- > 0) { while (samples_remaining-- > 0) {
short sample = samplesBuffer.getShort(); short sample = samplesBuffer.getShort();
int type = ((sample & 0xe000) >>> 13); int type = ((sample & 0xe000) >>> 13);
int intensity = ((sample & 0x1f80) >>> 7); int intensity = ((sample & 0x1f80) >>> 7);
int steps = (sample & 0x007f); int steps = (sample & 0x007f);
db.addGBActivitySample(timestamp + offset_seconds, SampleProvider.PROVIDER_PEBBLE_GADGETBRIDGE, intensity, steps, type, 0); activitySamples[i++] = createSample(timestamp + offset_seconds, intensity, steps, type);
offset_seconds += 60; offset_seconds += 60;
} }
} catch (GBException e) { db.addGBActivitySamples(activitySamples);
LOG.error("Error acquiring database", e); // } catch (GBException e) {
// LOG.error("Error acquiring database", e);
} finally { } finally {
if (db != null) { if (db != null) {
db.release(); db.release();

View File

@ -18,6 +18,8 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MisfitSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MisfitSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
@ -70,7 +72,10 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
LOG.info("got data from " + startDate + " to " + endDate); LOG.info("got data from " + startDate + " to " + endDate);
int totalSteps = 0; int totalSteps = 0;
GBActivitySample[] activitySamples = new GBActivitySample[samples]; AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples];
// TODO: user and device id
Long userId = null;
Long deviceId = null;
for (int i = 0; i < samples; i++) { for (int i = 0; i < samples; i++) {
short sample = buf.getShort(); short sample = buf.getShort();
int steps = 0; int steps = 0;
@ -101,17 +106,18 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
totalSteps += steps; totalSteps += steps;
LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")"); LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")");
activitySamples[i] = new GBActivitySample(sampleProvider, timestamp + i * 60, intensity, steps, activityKind); activitySamples[i] = new PebbleActivitySample(null, timestamp + i * 60, intensity, steps, activityKind, userId, deviceId);
} }
LOG.info("total steps for above period: " + totalSteps); LOG.info("total steps for above period: " + totalSteps);
DBHandler db = null; DBHandler db = null;
try { try {
db = GBApplication.acquireDB(); // db = GBApplication.acquireDB();
db = sampleProvider;
db.addGBActivitySamples(activitySamples); db.addGBActivitySamples(activitySamples);
} catch (GBException e) { // } catch (GBException e) {
LOG.error("Error acquiring database", e); // LOG.error("Error acquiring database", e);
return null; // return null;
} finally { } finally {
if (db != null) { if (db != null) {
db.release(); db.release();

View File

@ -92,10 +92,11 @@ public class AppMessageHandlerMorpheuz extends AppMessageHandler {
if (index >= 0) { if (index >= 0) {
DBHandler db = null; DBHandler db = null;
try { try {
db = GBApplication.acquireDB(); // db = GBApplication.acquireDB();
db.addGBActivitySample(recording_base_timestamp + index * 600, SampleProvider.PROVIDER_PEBBLE_MORPHEUZ, intensity, 0, type, 0); db = new MorpheuzSampleProvider(GBApplication.getDaoSession());
} catch (GBException e) { db.addGBActivitySample(createSample(recording_base_timestamp + index * 600, intensity, 0, type));
LOG.error("Error acquiring database", e); // } catch (GBException e) {
// LOG.error("Error acquiring database", e);
} finally { } finally {
if (db != null) { if (db != null) {
db.release(); db.release();

View File

@ -11,6 +11,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.HealthSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.HealthSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
@ -70,22 +72,27 @@ public class DatalogSessionHealthSteps extends DatalogSession {
private void store(StepsRecord[] stepsRecords) { private void store(StepsRecord[] stepsRecords) {
DBHandler dbHandler = null; HealthSampleProvider sampleProvider = new HealthSampleProvider(GBApplication.getDaoSession());
SampleProvider sampleProvider = new HealthSampleProvider(GBApplication.getDaoSession()); DBHandler dbHandler = sampleProvider;
ActivitySample[] samples = new ActivitySample[stepsRecords.length]; AbstractActivitySample[] samples = new AbstractActivitySample[stepsRecords.length];
// TODO: user and device
Long userId = null;
Long deviceId = null;
for (int j = 0; j < stepsRecords.length; j++) { for (int j = 0; j < stepsRecords.length; j++) {
StepsRecord stepsRecord = stepsRecords[j]; StepsRecord stepsRecord = stepsRecords[j];
samples[j] = new GBActivitySample( samples[j] = new PebbleActivitySample(
sampleProvider, null,
stepsRecord.timestamp, stepsRecord.timestamp,
stepsRecord.intensity, stepsRecord.intensity,
stepsRecord.steps, stepsRecord.steps,
sampleProvider.toRawActivityKind(ActivityKind.TYPE_ACTIVITY)); sampleProvider.toRawActivityKind(ActivityKind.TYPE_ACTIVITY),
userId, deviceId);
} }
try { try {
dbHandler = GBApplication.acquireDB(); // dbHandler = GBApplication.acquireDB();
dbHandler = sampleProvider;
dbHandler.addGBActivitySamples(samples); dbHandler.addGBActivitySamples(samples);
} catch (Exception ex) { } catch (Exception ex) {
LOG.debug(ex.getMessage()); LOG.debug(ex.getMessage());

View File

@ -696,15 +696,15 @@ public class PebbleProtocol extends GBDeviceProtocol {
buf.order(ByteOrder.LITTLE_ENDIAN); buf.order(ByteOrder.LITTLE_ENDIAN);
ActivityUser activityUser = new ActivityUser(); ActivityUser activityUser = new ActivityUser();
Integer heightMm = activityUser.getActivityUserHeightCm() * 10; Integer heightMm = activityUser.getHeightCm() * 10;
buf.putShort(heightMm.shortValue()); buf.putShort(heightMm.shortValue());
Integer weigthDag = activityUser.getActivityUserWeightKg() * 100; Integer weigthDag = activityUser.getWeightKg() * 100;
buf.putShort(weigthDag.shortValue()); buf.putShort(weigthDag.shortValue());
buf.put((byte) 0x01); //activate tracking buf.put((byte) 0x01); //activate tracking
buf.put((byte) 0x00); //activity Insights buf.put((byte) 0x00); //activity Insights
buf.put((byte) 0x00); //sleep Insights buf.put((byte) 0x00); //sleep Insights
buf.put((byte) activityUser.getActivityUserAge()); buf.put((byte) activityUser.getAge());
buf.put((byte) activityUser.getActivityUserGender()); buf.put((byte) activityUser.getGender());
blob = buf.array(); blob = buf.array();
} else { } else {
blob = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; blob = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

View File

@ -4,14 +4,20 @@ import android.text.format.DateUtils;
import com.github.pfichtner.durationformatter.DurationFormatter; import com.github.pfichtner.durationformatter.DurationFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
public class DateTimeUtils { public class DateTimeUtils {
private static SimpleDateFormat DAY_STORAGE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
public static String formatDateTime(Date date) { public static String formatDateTime(Date date) {
return DateUtils.formatDateTime(GBApplication.getContext(), date.getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME); return DateUtils.formatDateTime(GBApplication.getContext(), date.getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
} }
@ -55,4 +61,21 @@ public class DateTimeUtils {
cal.setTimeInMillis(timestamp * 1000L); // make sure it's converted to long cal.setTimeInMillis(timestamp * 1000L); // make sure it's converted to long
return cal.getTime(); return cal.getTime();
} }
public static String dayToString(Date date) {
return DAY_STORAGE_FORMAT.format(date);
}
public static Date dayFromString(String day) throws ParseException {
return DAY_STORAGE_FORMAT.parse(day);
}
public static Date todayUTC() {
Calendar cal = getCalendarUTC();
return cal.getTime();
}
public static Calendar getCalendarUTC() {
return GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
}
} }

View File

@ -1,9 +1,17 @@
package nodomain.freeyourgadget.gadgetbridge.util; package nodomain.freeyourgadget.gadgetbridge.util;
import java.text.ParseException;
import java.util.Date;
public class GBPrefs { public class GBPrefs {
public static final String AUTO_RECONNECT = "general_autocreconnect"; public static final String AUTO_RECONNECT = "general_autocreconnect";
public static boolean AUTO_RECONNECT_DEFAULT = true; public static boolean AUTO_RECONNECT_DEFAULT = true;
public static final String USER_NAME = "mi_user_alias";
public static final String USER_NAME_DEFAULT = "gadgetbridge-user";
private static final String USER_BIRTHDAY = "";
private final Prefs mPrefs; private final Prefs mPrefs;
public GBPrefs(Prefs prefs) { public GBPrefs(Prefs prefs) {
@ -13,4 +21,25 @@ public class GBPrefs {
public boolean getAutoReconnect() { public boolean getAutoReconnect() {
return mPrefs.getBoolean(AUTO_RECONNECT, AUTO_RECONNECT_DEFAULT); return mPrefs.getBoolean(AUTO_RECONNECT, AUTO_RECONNECT_DEFAULT);
} }
public String getUserName() {
return mPrefs.getString(USER_NAME, USER_NAME_DEFAULT);
}
public Date getUserBirthday() {
String date = mPrefs.getString(USER_BIRTHDAY, null);
if (date == null) {
return null;
}
try {
return DateTimeUtils.dayFromString(date);
} catch (ParseException ex) {
GB.log("Error parsing date: " + date, GB.ERROR, ex);
return null;
}
}
public int getUserSex() {
return 0;
}
} }