From a3bc0c8de2cbad06dbbb7110ab0785f50664d013 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 21:35:10 +0100 Subject: [PATCH 01/10] Use real user ids when inserting measurements in database --- .../java/com/health/openscale/DatabaseTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/android_app/app/src/androidTest/java/com/health/openscale/DatabaseTest.java b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseTest.java index ec74be40..378e7b06 100644 --- a/android_app/app/src/androidTest/java/com/health/openscale/DatabaseTest.java +++ b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseTest.java @@ -65,7 +65,7 @@ public class DatabaseTest { @Test public void userOperations() throws Exception { ScaleUser user1 = new ScaleUser(); - ScaleUser user2 = new ScaleUser(); + ScaleUser user2 = new ScaleUser(); user1.setUserName("foo"); user2.setUserName("bar"); @@ -121,8 +121,14 @@ public class DatabaseTest { @Test public void measurementOperations() throws Exception { + final ScaleUser scaleUser1 = new ScaleUser(); + final ScaleUser scaleUser2 = new ScaleUser(); + + scaleUser1.setId((int)userDao.insert(scaleUser1)); + scaleUser2.setId((int)userDao.insert(scaleUser2)); + // User 1 data initialization - final int user1 = 0; + final int user1 = scaleUser1.getId(); ScaleMeasurement measurement11 = new ScaleMeasurement(); ScaleMeasurement measurement12 = new ScaleMeasurement(); ScaleMeasurement measurement13 = new ScaleMeasurement(); @@ -140,7 +146,7 @@ public class DatabaseTest { measurement13.setDateTime(new Date(300)); // User 2 data initialization - final int user2 = 1; + final int user2 = scaleUser2.getId(); ScaleMeasurement measurement21 = new ScaleMeasurement(); ScaleMeasurement measurement22 = new ScaleMeasurement(); From 48921a4807fcfc606021dd6427c3d538701a33cb Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 21:36:04 +0100 Subject: [PATCH 02/10] Remove unused class member --- .../app/src/main/java/com/health/openscale/core/OpenScale.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 82b84af2..36d04808 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -48,7 +48,6 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -71,8 +70,6 @@ public class OpenScale { private String btDeviceName; private AlarmHandler alarmHandler; - private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); - private Context context; private ArrayList fragmentList; From 212b32f6327e413cdba80188fc0ac1c36837b3d8 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 21:39:22 +0100 Subject: [PATCH 03/10] Introduce new database version (2) - Change the unique constraint for measurements to include userId in addition to datetime. This way two users can now have measurements with the same date and time (hour and minute). - Enforce that the userId references an existing user. --- .../2.json | 195 ++++++++++++++++++ .../openscale/DatabaseMigrationTest.java | 110 ++++++++++ .../com/health/openscale/core/OpenScale.java | 15 +- .../openscale/core/database/AppDatabase.java | 46 ++++- .../core/datatypes/ScaleMeasurement.java | 9 +- 5 files changed, 372 insertions(+), 3 deletions(-) create mode 100644 android_app/app/schemas/com.health.openscale.core.database.AppDatabase/2.json create mode 100644 android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java diff --git a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/2.json b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/2.json new file mode 100644 index 00000000..1b3a5e70 --- /dev/null +++ b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/2.json @@ -0,0 +1,195 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "166a2a83c723c4117edaf1d107ac5194", + "entities": [ + { + "tableName": "scaleMeasurements", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userId` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `datetime` INTEGER, `weight` REAL NOT NULL, `fat` REAL NOT NULL, `water` REAL NOT NULL, `muscle` REAL NOT NULL, `lbw` REAL NOT NULL, `waist` REAL NOT NULL, `hip` REAL NOT NULL, `bone` REAL NOT NULL, `comment` TEXT, FOREIGN KEY(`userId`) REFERENCES `scaleUsers`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateTime", + "columnName": "datetime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "fat", + "columnName": "fat", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "water", + "columnName": "water", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "muscle", + "columnName": "muscle", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "lbw", + "columnName": "lbw", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "waist", + "columnName": "waist", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "hip", + "columnName": "hip", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "bone", + "columnName": "bone", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_scaleMeasurements_datetime_userId", + "unique": true, + "columnNames": [ + "datetime", + "userId" + ], + "createSql": "CREATE UNIQUE INDEX `index_scaleMeasurements_datetime_userId` ON `${TABLE_NAME}` (`datetime`, `userId`)" + } + ], + "foreignKeys": [ + { + "table": "scaleUsers", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "userId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "scaleUsers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `username` TEXT, `birthday` INTEGER, `bodyHeight` INTEGER NOT NULL, `scaleUnit` INTEGER NOT NULL, `gender` INTEGER NOT NULL, `initialWeight` REAL NOT NULL, `goalWeight` REAL NOT NULL, `goalDate` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userName", + "columnName": "username", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "birthday", + "columnName": "birthday", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "bodyHeight", + "columnName": "bodyHeight", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scaleUnit", + "columnName": "scaleUnit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "gender", + "columnName": "gender", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "initialWeight", + "columnName": "initialWeight", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "goalWeight", + "columnName": "goalWeight", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "goalDate", + "columnName": "goalDate", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"166a2a83c723c4117edaf1d107ac5194\")" + ] + } +} \ No newline at end of file diff --git a/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java new file mode 100644 index 00000000..562c14fc --- /dev/null +++ b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java @@ -0,0 +1,110 @@ +/* Copyright (C) 2018 Erik Johansson +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see +*/ + +package com.health.openscale; + +import android.arch.persistence.db.SupportSQLiteDatabase; +import android.arch.persistence.db.SupportSQLiteOpenHelper; +import android.arch.persistence.db.framework.FrameworkSQLiteOpenHelperFactory; +import android.arch.persistence.room.testing.MigrationTestHelper; +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import com.health.openscale.core.database.AppDatabase; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotSame; +import static junit.framework.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class DatabaseMigrationTest { + private static final String TEST_DB = "migration-test"; + + @Rule + public MigrationTestHelper helper; + + public DatabaseMigrationTest() { + helper = new MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + AppDatabase.class.getCanonicalName(), + new FrameworkSQLiteOpenHelperFactory()); + } + + @Test + public void migrate1To2() throws Exception { + SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1); + + ContentValues users = new ContentValues(); + for (int i = 1; i < 4; ++i) { + users.put("id", i); + users.put("username", String.format("test%d", i)); + users.put("bodyHeight", i * 50); + users.put("scaleUnit", 0); + users.put("gender", 0); + users.put("initialWeight", i * 25); + users.put("goalWeight", i * 20); + assertNotSame(-1, db.insert("scaleUsers", SQLiteDatabase.CONFLICT_ABORT, users)); + } + + ContentValues measurement = new ContentValues(); + for (int i = 2; i < 5; ++i) { + for (int j = 0; j < 2; ++j) { + measurement.put("userId", i); + measurement.put("enabled", j); + measurement.put("comment", "a string"); + for (String type : new String[]{"weight", "fat", "water", "muscle", "lbw", "waist", "hip", "bone"}) { + measurement.put(type, i * j); + } + + assertNotSame(-1, db.insert("scaleMeasurements", SQLiteDatabase.CONFLICT_ABORT, measurement)); + } + } + + // Prepare for the next version. + db.close(); + + // Re-open the database with version 2 and provide MIGRATION_1_2 as the migration process. + db = helper.runMigrationsAndValidate(TEST_DB, 2, true, AppDatabase.MIGRATION_1_2); + + // MigrationTestHelper automatically verifies the schema changes. + + Cursor cursor = db.query("SELECT * FROM scaleMeasurements ORDER BY id, userId"); + assertEquals(2 * 2, cursor.getCount()); + + cursor.moveToFirst(); + for (int i = 2; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + assertEquals(i, cursor.getInt(cursor.getColumnIndex("userId"))); + assertEquals(j, cursor.getInt(cursor.getColumnIndex("enabled"))); + assertEquals("a string", cursor.getString(cursor.getColumnIndex("comment"))); + for (String type : new String[]{"weight", "fat", "water", "muscle", "lbw", "waist", "hip", "bone"}) { + assertEquals((float) i * j, cursor.getFloat(cursor.getColumnIndex(type))); + } + + cursor.moveToNext(); + } + } + + assertTrue(cursor.isAfterLast()); + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 36d04808..8f7cc229 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -16,11 +16,14 @@ package com.health.openscale.core; +import android.arch.persistence.db.SupportSQLiteDatabase; import android.arch.persistence.room.Room; +import android.arch.persistence.room.RoomDatabase; import android.content.Context; import android.content.SharedPreferences; import android.os.Handler; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.text.format.DateFormat; import android.util.Log; @@ -81,7 +84,17 @@ public class OpenScale { alarmHandler = new AlarmHandler(); btCom = null; fragmentList = new ArrayList<>(); - appDB = Room.databaseBuilder(context, AppDatabase.class, "openScale.db").allowMainThreadQueries().build(); + appDB = Room.databaseBuilder(context, AppDatabase.class, "openScale.db") + .allowMainThreadQueries() + .addCallback(new RoomDatabase.Callback() { + @Override + public void onOpen(@NonNull SupportSQLiteDatabase db) { + super.onOpen(db); + db.setForeignKeyConstraintsEnabled(true); + } + }) + .addMigrations(AppDatabase.MIGRATION_1_2) + .build(); measurementDAO = appDB.measurementDAO(); userDAO = appDB.userDAO(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java index c4f68c7b..e6c8b607 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java @@ -16,18 +16,62 @@ package com.health.openscale.core.database; +import android.arch.persistence.db.SupportSQLiteDatabase; import android.arch.persistence.room.Database; import android.arch.persistence.room.RoomDatabase; import android.arch.persistence.room.TypeConverters; +import android.arch.persistence.room.migration.Migration; +import android.support.annotation.NonNull; import com.health.openscale.core.datatypes.ScaleMeasurement; import com.health.openscale.core.datatypes.ScaleUser; import com.health.openscale.core.utils.Converters; -@Database(entities = {ScaleMeasurement.class, ScaleUser.class}, version = 1) +@Database(entities = {ScaleMeasurement.class, ScaleUser.class}, version = 2) @TypeConverters({Converters.class}) public abstract class AppDatabase extends RoomDatabase { public abstract ScaleMeasurementDAO measurementDAO(); public abstract ScaleUserDAO userDAO(); + + public static final Migration MIGRATION_1_2 = new Migration(1, 2) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.beginTransaction(); + try { + // Drop old index on datetime only + database.execSQL("DROP INDEX index_scaleMeasurements_datetime"); + + // Rename old table + database.execSQL("ALTER TABLE scaleMeasurements RENAME TO scaleMeasurementsOld"); + + // Create new table with foreign key + database.execSQL("CREATE TABLE scaleMeasurements" + + " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " userId INTEGER NOT NULL, enabled INTEGER NOT NULL," + + " datetime INTEGER, weight REAL NOT NULL, fat REAL NOT NULL," + + " water REAL NOT NULL, muscle REAL NOT NULL, lbw REAL NOT NULL," + + " waist REAL NOT NULL, hip REAL NOT NULL, bone REAL NOT NULL," + + " comment TEXT, FOREIGN KEY(userId) REFERENCES scaleUsers(id)" + + " ON UPDATE NO ACTION ON DELETE CASCADE)"); + + // Create new index on datetime + userId + database.execSQL("CREATE UNIQUE INDEX index_scaleMeasurements_datetime_userId" + + " ON scaleMeasurements (datetime, userId)"); + + // Copy data from the old table, ignoring those with invalid userId (if any) + database.execSQL("INSERT INTO scaleMeasurements" + + " SELECT * FROM scaleMeasurementsOld" + + " WHERE userId IN (SELECT id from scaleUsers)"); + + // Delete old table + database.execSQL("DROP TABLE scaleMeasurementsOld"); + + database.setTransactionSuccessful(); + } + finally { + database.endTransaction(); + } + } + }; } diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java index f797ef90..ce5cb277 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java @@ -18,6 +18,7 @@ package com.health.openscale.core.datatypes; import android.arch.persistence.room.ColumnInfo; import android.arch.persistence.room.Entity; +import android.arch.persistence.room.ForeignKey; import android.arch.persistence.room.Index; import android.arch.persistence.room.PrimaryKey; @@ -26,7 +27,13 @@ import com.j256.simplecsv.common.CsvColumn; import java.util.Date; -@Entity(tableName = "scaleMeasurements", indices = {@Index(value = {"datetime"}, unique = true)}) +@Entity(tableName = "scaleMeasurements", + indices = {@Index(value = {"datetime", "userId"}, unique = true)}, + foreignKeys = @ForeignKey( + entity = ScaleUser.class, + parentColumns = "id", + childColumns = "userId", + onDelete = ForeignKey.CASCADE)) public class ScaleMeasurement implements Cloneable { @PrimaryKey(autoGenerate = true) From d2d7295a1a535556fedad643bf0caa8fb58e058b Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 21:58:13 +0100 Subject: [PATCH 04/10] Reopen database after import to have migrations run if needed --- .../com/health/openscale/core/OpenScale.java | 31 ++++++++++++------- .../gui/preferences/BackupPreferences.java | 7 +++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 8f7cc229..a01aff46 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -84,6 +84,26 @@ public class OpenScale { alarmHandler = new AlarmHandler(); btCom = null; fragmentList = new ArrayList<>(); + + reopenDatabase(); + + migrateSQLtoRoom(); + updateScaleData(); + } + + public static OpenScale getInstance(Context context) { + if (instance == null) { + instance = new OpenScale(context); + } + + return instance; + } + + public void reopenDatabase() { + if (appDB != null) { + appDB.close(); + } + appDB = Room.databaseBuilder(context, AppDatabase.class, "openScale.db") .allowMainThreadQueries() .addCallback(new RoomDatabase.Callback() { @@ -97,17 +117,6 @@ public class OpenScale { .build(); measurementDAO = appDB.measurementDAO(); userDAO = appDB.userDAO(); - - migrateSQLtoRoom(); - updateScaleData(); - } - - public static OpenScale getInstance(Context context) { - if (instance == null) { - instance = new OpenScale(context); - } - - return instance; } private void migrateSQLtoRoom() { diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java index 3f02b62c..3a852b2e 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java @@ -119,12 +119,15 @@ public class BackupPreferences extends PreferenceFragment { importBackup("openScale.db", exportDir); - List scaleUserList = OpenScale.getInstance(getActivity().getApplicationContext()).getScaleUserList(); + OpenScale openScale = OpenScale.getInstance(getActivity().getApplicationContext()); + openScale.reopenDatabase(); + + List scaleUserList = openScale.getScaleUserList(); if (!scaleUserList.isEmpty()) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); prefs.edit().putInt("selectedUserId", scaleUserList.get(0).getId()).commit(); - OpenScale.getInstance(getActivity().getApplicationContext()).updateScaleData(); + openScale.updateScaleData(); } return true; From 0ee227259ddcc99ada953ec70e38af20ee53a3b3 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 22:05:25 +0100 Subject: [PATCH 05/10] Close old database after migration is done --- .../java/com/health/openscale/core/OpenScale.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index a01aff46..aea89b09 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -65,8 +65,6 @@ public class OpenScale { private AppDatabase appDB; private ScaleMeasurementDAO measurementDAO; private ScaleUserDAO userDAO; - private ScaleDatabase scaleDB; - private ScaleUserDatabase scaleUserDB; private List scaleMeasurementList; private BluetoothCommunication btCom; @@ -79,8 +77,6 @@ public class OpenScale { private OpenScale(Context context) { this.context = context; - scaleDB = new ScaleDatabase(context); - scaleUserDB = new ScaleUserDatabase(context); alarmHandler = new AlarmHandler(); btCom = null; fragmentList = new ArrayList<>(); @@ -120,6 +116,10 @@ public class OpenScale { } private void migrateSQLtoRoom() { + // TODO: check if databases exist before opening and possibly creating them + ScaleDatabase scaleDB = new ScaleDatabase(context); + ScaleUserDatabase scaleUserDB = new ScaleUserDatabase(context); + List oldScaleUserList = scaleUserDB.getScaleUserList(); if (scaleDB.getReadableDatabase().getVersion() == 6 && userDAO.getAll().isEmpty() && !oldScaleUserList.isEmpty()) { @@ -133,6 +133,9 @@ public class OpenScale { Toast.makeText(context, "Finished migrating old SQL database to new database format", Toast.LENGTH_LONG).show(); } + + scaleUserDB.close(); + scaleDB.close(); } public void addScaleUser(final ScaleUser user) From d0fb7beea8885a2154dd33e97633353bb9e96594 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 22:11:57 +0100 Subject: [PATCH 06/10] Remove unused methods from old database classes --- .../core/database/ScaleDatabase.java | 252 +----------------- .../core/database/ScaleUserDatabase.java | 83 ------ 2 files changed, 1 insertion(+), 334 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java index e7d91118..4c78ff31 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java @@ -16,7 +16,6 @@ package com.health.openscale.core.database; -import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; @@ -29,7 +28,6 @@ import com.health.openscale.core.datatypes.ScaleMeasurement; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Locale; public class ScaleDatabase extends SQLiteOpenHelper { @@ -68,10 +66,6 @@ public class ScaleDatabase extends SQLiteOpenHelper { COLUMN_NAME_ENABLE + " INTEGER" + ")"; - private static final String SQL_DELETE_ENTRIES = - "DROP TABLE IF EXISTS " + TABLE_NAME; - - private static String[] projection = { COLUMN_NAME_ID, COLUMN_NAME_USER_ID, @@ -88,9 +82,6 @@ public class ScaleDatabase extends SQLiteOpenHelper { COLUMN_NAME_ENABLE }; - private final SQLiteDatabase dbWrite = getWritableDatabase(); - private final SQLiteDatabase dbRead = getReadableDatabase(); - private SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); public ScaleDatabase(Context context) { @@ -126,254 +117,13 @@ public class ScaleDatabase extends SQLiteOpenHelper { } } - public void clearScaleData(int userId) { - dbWrite.delete(TABLE_NAME, COLUMN_NAME_USER_ID + "=" + Integer.toString(userId), null); - } - - public boolean insertEntry(ScaleMeasurement scaleMeasurement) { - SQLiteDatabase db = getWritableDatabase(); - - Cursor cursorScaleDB = db.query(TABLE_NAME, new String[] {COLUMN_NAME_DATE_TIME}, COLUMN_NAME_DATE_TIME + "=? AND " + COLUMN_NAME_USER_ID + "=?", - new String[] {formatDateTime.format(scaleMeasurement.getDateTime()), Integer.toString(scaleMeasurement.getUserId())}, null, null, null); - - // we don't want double entries - if (cursorScaleDB.getCount() > 0) { - cursorScaleDB.close(); - return false; - } else { - ContentValues values = new ContentValues(); - values.put(COLUMN_NAME_USER_ID, scaleMeasurement.getUserId()); - values.put(COLUMN_NAME_DATE_TIME, formatDateTime.format(scaleMeasurement.getDateTime())); - values.put(COLUMN_NAME_WEIGHT, scaleMeasurement.getWeight()); - values.put(COLUMN_NAME_FAT, scaleMeasurement.getFat()); - values.put(COLUMN_NAME_WATER, scaleMeasurement.getWater()); - values.put(COLUMN_NAME_MUSCLE, scaleMeasurement.getMuscle()); - values.put(COLUMN_NAME_LBW, scaleMeasurement.getLbw()); - values.put(COLUMN_NAME_BONE, scaleMeasurement.getBone()); - values.put(COLUMN_NAME_WAIST, scaleMeasurement.getWaist()); - values.put(COLUMN_NAME_HIP, scaleMeasurement.getHip()); - values.put(COLUMN_NAME_COMMENT, scaleMeasurement.getComment()); - values.put(COLUMN_NAME_ENABLE, 1); - - try - { - db.insertOrThrow(TABLE_NAME, null, values); - } - catch (SQLException e) - { - Log.e("ScaleDatabase", "An error occured while inserting a new entry into the scale database: " + e.toString()); - cursorScaleDB.close(); - return false; - } - } - - cursorScaleDB.close(); - - return true; - } - - public void updateEntry(long id, ScaleMeasurement scaleMeasurement) { - ContentValues values = new ContentValues(); - - values.put(COLUMN_NAME_DATE_TIME, formatDateTime.format(scaleMeasurement.getDateTime())); - values.put(COLUMN_NAME_WEIGHT, scaleMeasurement.getWeight()); - values.put(COLUMN_NAME_FAT, scaleMeasurement.getFat()); - values.put(COLUMN_NAME_WATER, scaleMeasurement.getWater()); - values.put(COLUMN_NAME_MUSCLE, scaleMeasurement.getMuscle()); - values.put(COLUMN_NAME_LBW, scaleMeasurement.getLbw()); - values.put(COLUMN_NAME_BONE, scaleMeasurement.getBone()); - values.put(COLUMN_NAME_WAIST, scaleMeasurement.getWaist()); - values.put(COLUMN_NAME_HIP, scaleMeasurement.getHip()); - values.put(COLUMN_NAME_COMMENT, scaleMeasurement.getComment()); - values.put(COLUMN_NAME_ENABLE, 1); - - dbWrite.update(TABLE_NAME, values, COLUMN_NAME_ID + "=" + id, null); - } - - public ScaleMeasurement[] getTupleDataEntry(int userId, long id) - { - Cursor cursorScaleDB; - - ScaleMeasurement[] tupleScaleData = new ScaleMeasurement[3]; - - // selected scale data entry - cursorScaleDB = dbRead.query( - TABLE_NAME, // The table to query - projection, // The columns to return - COLUMN_NAME_USER_ID + "=? AND " + COLUMN_NAME_ID + "=?", // The columns for the WHERE clause - new String[] {Integer.toString(userId), Long.toString(id)}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - null, // The sort order - "1" // Limit - ); - - if (cursorScaleDB.getCount() == 1) { - cursorScaleDB.moveToFirst(); - tupleScaleData[1] = readAtCursor(cursorScaleDB); - } else { - tupleScaleData[1] = new ScaleMeasurement(); - } - - // previous scale entry - cursorScaleDB = dbRead.query( - TABLE_NAME, // The table to query - projection, // The columns to return - COLUMN_NAME_USER_ID + "=? AND " + COLUMN_NAME_DATE_TIME + "? AND " + COLUMN_NAME_ENABLE + "=1", // The columns for the WHERE clause - new String[] {Integer.toString(userId), formatDateTime.format(tupleScaleData[1].getDateTime())}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - COLUMN_NAME_DATE_TIME, // The sort order - "1" // Limit - ); - - if (cursorScaleDB.getCount() == 1) { - cursorScaleDB.moveToFirst(); - tupleScaleData[2] = readAtCursor(cursorScaleDB); - } else { - tupleScaleData[2] = null; - } - - return tupleScaleData; - } - - public void deleteEntry(long id) { - //dbWrite.delete(TABLE_NAME, COLUMN_NAME_ID + "= ?", new String[] {String.valueOf(id)}); - - ContentValues values = new ContentValues(); - values.put(COLUMN_NAME_ENABLE, 0); - - dbWrite.update(TABLE_NAME, values, COLUMN_NAME_ID + "=" + id, null); - } - - public int[] getCountsOfAllMonth(int userId, int year) { - int [] numOfMonth = new int[12]; - - Calendar start_cal = Calendar.getInstance(); - Calendar end_cal = Calendar.getInstance(); - - for (int i=0; i<12; i++) { - start_cal.set(year, i, 1, 0, 0, 0); - end_cal.set(year, i, 1, 0, 0, 0); - end_cal.add(Calendar.MONTH, 1); - - Cursor cursorScaleDB = dbRead.query( - TABLE_NAME, // The table to query - new String[]{"count(*)"}, // The columns to return - COLUMN_NAME_DATE_TIME + " >= ? AND " + COLUMN_NAME_DATE_TIME + " < ? AND " + COLUMN_NAME_USER_ID + "=? AND "+ COLUMN_NAME_ENABLE + "=1", // The columns for the WHERE clause - new String[]{formatDateTime.format(start_cal.getTime()), formatDateTime.format(end_cal.getTime()), Integer.toString(userId)}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - null // The sort order - ); - - cursorScaleDB.moveToFirst(); - - numOfMonth[i] = cursorScaleDB.getInt(0); - - cursorScaleDB.close(); - } - - return numOfMonth; - } - - public ArrayList getScaleDataOfMonth(int userId, int year, int month) { - ArrayList scaleMeasurementList = new ArrayList(); - - String sortOrder = COLUMN_NAME_DATE_TIME + " DESC"; - - Calendar start_cal = Calendar.getInstance(); - Calendar end_cal = Calendar.getInstance(); - - start_cal.set(year, month, 1, 0, 0, 0); - end_cal.set(year, month, 1, 0, 0, 0); - end_cal.add(Calendar.MONTH, 1); - - Cursor cursorScaleDB = dbRead.query( - TABLE_NAME, // The table to query - projection, // The columns to return - COLUMN_NAME_DATE_TIME + " >= ? AND " + COLUMN_NAME_DATE_TIME + " < ? AND " + COLUMN_NAME_USER_ID + "=? AND " + COLUMN_NAME_ENABLE + "=1", // The columns for the WHERE clause - new String[]{formatDateTime.format(start_cal.getTime()), formatDateTime.format(end_cal.getTime()), Integer.toString(userId)}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - sortOrder // The sort order - ); - - cursorScaleDB.moveToFirst(); - - while (!cursorScaleDB.isAfterLast()) { - scaleMeasurementList.add(readAtCursor(cursorScaleDB)); - - cursorScaleDB.moveToNext(); - } - - cursorScaleDB.close(); - - return scaleMeasurementList; - } - - public ArrayList getScaleDataOfYear(int userId, int year) { - ArrayList scaleMeasurementList = new ArrayList(); - - String sortOrder = COLUMN_NAME_DATE_TIME + " DESC"; - - Calendar start_cal = Calendar.getInstance(); - Calendar end_cal = Calendar.getInstance(); - - start_cal.set(year, Calendar.JANUARY, 1, 0, 0, 0); - end_cal.set(year+1, Calendar.JANUARY, 1, 0, 0, 0); - - Cursor cursorScaleDB = dbRead.query( - TABLE_NAME, // The table to query - projection, // The columns to return - COLUMN_NAME_DATE_TIME + " >= ? AND " + COLUMN_NAME_DATE_TIME + " < ? AND " + COLUMN_NAME_USER_ID + "=? AND " + COLUMN_NAME_ENABLE + "=1", // The columns for the WHERE clause - new String[]{formatDateTime.format(start_cal.getTime()), formatDateTime.format(end_cal.getTime()), Integer.toString(userId)}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - sortOrder // The sort order - ); - - cursorScaleDB.moveToFirst(); - - while (!cursorScaleDB.isAfterLast()) { - scaleMeasurementList.add(readAtCursor(cursorScaleDB)); - - cursorScaleDB.moveToNext(); - } - - cursorScaleDB.close(); - - return scaleMeasurementList; - } - public ArrayList getScaleDataList(int userId) { ArrayList scaleMeasurementList = new ArrayList(); try { String sortOrder = COLUMN_NAME_DATE_TIME + " DESC"; - Cursor cursorScaleDB = dbRead.query( + Cursor cursorScaleDB = getReadableDatabase().query( TABLE_NAME, // The table to query projection, // The columns to return COLUMN_NAME_USER_ID + "=? AND " + COLUMN_NAME_ENABLE + "=1", // The columns for the WHERE clause diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java index b9d10fb9..86ded30d 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java @@ -16,10 +16,8 @@ package com.health.openscale.core.database; -import android.content.ContentValues; import android.content.Context; import android.database.Cursor; -import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; @@ -60,9 +58,6 @@ public class ScaleUserDatabase extends SQLiteOpenHelper { COLUMN_NAME_GOAL_DATE + " TEXT" + ")"; - private static final String SQL_DELETE_ENTRIES = - "DROP TABLE IF EXISTS " + TABLE_NAME; - private static String[] projection = { COLUMN_NAME_ID, COLUMN_NAME_USER_NAME, @@ -99,84 +94,6 @@ public class ScaleUserDatabase extends SQLiteOpenHelper { } } - public void clearDatabase() { - SQLiteDatabase db = getWritableDatabase(); - - db.delete(TABLE_NAME, null, null); - } - - public boolean insertEntry(ScaleUser scaleUser) { - SQLiteDatabase db = getWritableDatabase(); - - ContentValues values = new ContentValues(); - values.put(COLUMN_NAME_USER_NAME, scaleUser.getUserName()); - values.put(COLUMN_NAME_BIRTHDAY, formatDateTime.format(scaleUser.getBirthday())); - values.put(COLUMN_NAME_BODY_HEIGHT, scaleUser.getBodyHeight()); - values.put(COLUMN_NAME_SCALE_UNIT, scaleUser.getScaleUnit().toInt()); - values.put(COLUMN_NAME_GENDER, scaleUser.getGender().toInt()); - values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.getInitialWeight()); - values.put(COLUMN_NAME_GOAL_WEIGHT, scaleUser.getGoalWeight()); - values.put(COLUMN_NAME_GOAL_DATE, formatDateTime.format(scaleUser.getGoalDate())); - - try - { - db.insertOrThrow(TABLE_NAME, null, values); - } - catch (SQLException e) - { - Log.e("ScaleUserDatabase", "An error occured while inserting a new entry into the scale user database: " + e.toString()); - return false; - } - - return true; - } - - public void deleteEntry(int id) { - SQLiteDatabase db = getWritableDatabase(); - - db.delete(TABLE_NAME, COLUMN_NAME_ID + "= ?", new String[] {String.valueOf(id)}); - } - - public void updateScaleUser(ScaleUser scaleUser) - { - SQLiteDatabase db = getWritableDatabase(); - - ContentValues values = new ContentValues(); - values.put(COLUMN_NAME_USER_NAME, scaleUser.getUserName()); - values.put(COLUMN_NAME_BIRTHDAY, formatDateTime.format(scaleUser.getBirthday())); - values.put(COLUMN_NAME_BODY_HEIGHT, scaleUser.getBodyHeight()); - values.put(COLUMN_NAME_SCALE_UNIT, scaleUser.getScaleUnit().toInt()); - values.put(COLUMN_NAME_GENDER, scaleUser.getGender().toInt()); - values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.getInitialWeight()); - values.put(COLUMN_NAME_GOAL_WEIGHT, scaleUser.getGoalWeight()); - values.put(COLUMN_NAME_GOAL_DATE, formatDateTime.format(scaleUser.getGoalDate())); - - db.update(TABLE_NAME, values, COLUMN_NAME_ID + "=" + scaleUser.getId(), null); - } - - public ScaleUser getScaleUser(int id) - { - SQLiteDatabase db = getReadableDatabase(); - - Cursor cursorScaleDB = db.query( - TABLE_NAME, // The table to query - projection, // The columns to return - COLUMN_NAME_ID + "=?", // The columns for the WHERE clause - new String[] {Integer.toString(id)}, // The values for the WHERE clause - null, // don't group the rows - null, // don't filter by row groups - null // The sort order - ); - - cursorScaleDB.moveToFirst(); - - ScaleUser scaleUser = readAtCursor(cursorScaleDB); - - cursorScaleDB.close(); - - return scaleUser; - } - public ArrayList getScaleUserList() { SQLiteDatabase db = getReadableDatabase(); ArrayList scaleUserDBEntries = new ArrayList(); From 447f996cd4f3b67fc4efc0ec955ef713ddc0d9ff Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 22:39:54 +0100 Subject: [PATCH 07/10] Move selectedUserId handling to OpenScale class --- .../openscale/gui/ScreenshotRecorder.java | 3 +- .../com/health/openscale/core/OpenScale.java | 35 +++++++++---------- .../core/bluetooth/BluetoothExingtechY1.java | 3 +- .../core/bluetooth/BluetoothMiScale.java | 2 +- .../core/bluetooth/BluetoothMiScale2.java | 2 +- .../core/bluetooth/BluetoothYunmaiMini.java | 2 +- .../core/bluetooth/BluetoothYunmaiSE.java | 2 +- .../gui/activities/DataEntryActivity.java | 6 ++-- .../gui/activities/UserSettingsActivity.java | 11 ++---- .../gui/fragments/OverviewFragment.java | 8 ++--- .../gui/fragments/TableFragment.java | 3 +- .../gui/preferences/BackupPreferences.java | 3 +- .../preferences/MeasurementPreferences.java | 6 ++-- .../gui/preferences/UsersPreferences.java | 10 +++--- 14 files changed, 43 insertions(+), 53 deletions(-) diff --git a/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java b/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java index 61339e4f..dcd91635 100644 --- a/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java +++ b/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java @@ -213,7 +213,8 @@ public class ScreenshotRecorder { } private void prepareData() { - openScale.addScaleUser(getTestUser()); + int userId = openScale.addScaleUser(getTestUser()); + openScale.selectScaleUser(userId); List scaleMeasurementList = getTestMeasurements(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index aea89b09..eb91a638 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -138,12 +138,18 @@ public class OpenScale { scaleDB.close(); } - public void addScaleUser(final ScaleUser user) - { - long userId = userDAO.insert(user); + public int addScaleUser(final ScaleUser user) { + return (int)userDAO.insert(user); + } + public void selectScaleUser(int userId) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.edit().putInt("selectedUserId", (int)userId).commit(); + prefs.edit().putInt("selectedUserId", userId).commit(); + } + + public int getSelectedScaleUserId() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getInt("selectedUserId", -1); } public List getScaleUserList() @@ -161,8 +167,7 @@ public class OpenScale { ScaleUser scaleUser = new ScaleUser(); try { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = getSelectedScaleUserId(); if (selectedUserId == -1) { return scaleUser; @@ -355,8 +360,7 @@ public class OpenScale { } public int[] getCountsOfMonth(int year) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = getSelectedScaleUserId(); int [] numOfMonth = new int[12]; @@ -375,8 +379,7 @@ public class OpenScale { } public List getScaleDataOfMonth(int year, int month) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = getSelectedScaleUserId(); Calendar startCalender = Calendar.getInstance(); Calendar endCalender = Calendar.getInstance(); @@ -389,8 +392,7 @@ public class OpenScale { } public List getScaleDataOfYear(int year) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = getSelectedScaleUserId(); Calendar startCalender = Calendar.getInstance(); Calendar endCalender = Calendar.getInstance(); @@ -430,18 +432,15 @@ public class OpenScale { public void registerFragment(FragmentUpdateListener fragment) { fragmentList.add(fragment); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = getSelectedScaleUserId(); scaleMeasurementList = measurementDAO.getAll(selectedUserId); fragment.updateOnView(scaleMeasurementList); } - public void updateScaleData() - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + public void updateScaleData() { + int selectedUserId = getSelectedScaleUserId(); scaleMeasurementList = measurementDAO.getAll(selectedUserId); diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExingtechY1.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExingtechY1.java index e535a334..4b858f2a 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExingtechY1.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExingtechY1.java @@ -62,8 +62,7 @@ public class BluetoothExingtechY1 extends BluetoothCommunication { byte height = (byte)(selectedUser.getBodyHeight() & 0xff); // cm byte age = (byte)(selectedUser.getAge(new Date()) & 0xff); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int userId = prefs.getInt("selectedUserId", -1); + int userId = selectedUser.getId(); byte cmdByte[] = {(byte)0x10, (byte)userId, gender, age, height}; diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java index e8179d96..652959d3 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java @@ -285,7 +285,7 @@ public class BluetoothMiScale extends BluetoothCommunication { prefs.edit().putInt("uniqueNumber", uniqueNumber).commit(); } - int userId = prefs.getInt("selectedUserId", -1); + int userId = OpenScale.getInstance(context).getSelectedScaleUserId(); return uniqueNumber + userId; } diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale2.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale2.java index 45e939f0..b0d6afde 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale2.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale2.java @@ -257,7 +257,7 @@ public class BluetoothMiScale2 extends BluetoothCommunication { prefs.edit().putInt("uniqueNumber", uniqueNumber).commit(); } - int userId = prefs.getInt("selectedUserId", -1); + int userId = OpenScale.getInstance(context).getSelectedScaleUserId(); return uniqueNumber + userId; } diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiMini.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiMini.java index 4d15e824..dd575c4c 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiMini.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiMini.java @@ -154,7 +154,7 @@ public class BluetoothYunmaiMini extends BluetoothCommunication { prefs.edit().putInt("uniqueNumber", uniqueNumber).commit(); } - int userId = prefs.getInt("selectedUserId", -1); + int userId = OpenScale.getInstance(context).getSelectedScaleUserId(); return uniqueNumber + userId; } diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE.java index 24d8f8a8..d9fc00bf 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE.java @@ -152,7 +152,7 @@ public class BluetoothYunmaiSE extends BluetoothCommunication { prefs.edit().putInt("uniqueNumber", uniqueNumber).commit(); } - int userId = prefs.getInt("selectedUserId", -1); + int userId = OpenScale.getInstance(context).getSelectedScaleUserId(); return uniqueNumber + userId; } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java index afb8759c..4d351f57 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java @@ -301,8 +301,9 @@ public class DataEntryActivity extends Activity { private class onClickListenerAdd implements View.OnClickListener { @Override public void onClick(View v) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + OpenScale openScale = OpenScale.getInstance(getApplicationContext()); + + int selectedUserId = openScale.getSelectedScaleUserId(); if (selectedUserId == -1) { AlertDialog.Builder infoDialog = new AlertDialog.Builder(context); @@ -317,7 +318,6 @@ public class DataEntryActivity extends Activity { measurement.saveTo(scaleMeasurement); } - OpenScale openScale = OpenScale.getInstance(getApplicationContext()); openScale.addScaleData(scaleMeasurement); finish(); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java index 49a538ea..80465764 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java @@ -246,9 +246,7 @@ public class UserSettingsActivity extends Activity { lastUserId = scaleUser.get(0).getId(); } - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.edit().putInt("selectedUserId", lastUserId).commit(); - + openScale.selectScaleUser(lastUserId); openScale.updateScaleData(); Intent returnIntent = new Intent(); @@ -325,13 +323,10 @@ public class UserSettingsActivity extends Activity { scaleUser.setId(id); openScale.updateScaleUser(scaleUser); } else { - openScale.addScaleUser(scaleUser); - - id = openScale.getScaleUserList().get(openScale.getScaleUserList().size() - 1).getId(); + id = openScale.addScaleUser(scaleUser); } - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.edit().putInt("selectedUserId", id).commit(); + openScale.selectScaleUser(id); openScale.updateScaleData(); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java index 5acb9111..8896d292 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java @@ -476,13 +476,13 @@ public class OverviewFragment extends Fragment implements FragmentUpdateListener if (parent.getChildCount() > 0) { ((TextView) parent.getChildAt(0)).setTextColor(Color.GRAY); - List scaleUserList = OpenScale.getInstance(getContext()).getScaleUserList(); + OpenScale openScale = OpenScale.getInstance(getContext()); + List scaleUserList = openScale.getScaleUserList(); ScaleUser scaleUser = scaleUserList.get(position); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.edit().putInt("selectedUserId", scaleUser.getId()).commit(); - OpenScale.getInstance(getContext()).updateScaleData(); + openScale.selectScaleUser(scaleUser.getId()); + openScale.updateScaleData(); } } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java index c95d586c..d022678f 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java @@ -263,8 +263,7 @@ public class TableFragment extends Fragment implements FragmentUpdateListener { @Override public void onClick(View v) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(v.getContext()); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = OpenScale.getInstance(getContext()).getSelectedScaleUserId(); if (selectedUserId == -1) { diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java index 3a852b2e..82b4fda6 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java @@ -125,8 +125,7 @@ public class BackupPreferences extends PreferenceFragment { List scaleUserList = openScale.getScaleUserList(); if (!scaleUserList.isEmpty()) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - prefs.edit().putInt("selectedUserId", scaleUserList.get(0).getId()).commit(); + openScale.selectScaleUser(scaleUserList.get(0).getId()); openScale.updateScaleData(); } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/MeasurementPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/MeasurementPreferences.java index 64aff159..fe195dd4 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/MeasurementPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/MeasurementPreferences.java @@ -247,10 +247,10 @@ public class MeasurementPreferences extends PreferenceFragment implements Shared deleteAllDialog.setPositiveButton(getResources().getString(R.string.label_yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - int selectedUserId = prefs.getInt("selectedUserId", -1); + OpenScale openScale = OpenScale.getInstance(getActivity().getApplicationContext()); + int selectedUserId = openScale.getSelectedScaleUserId(); - OpenScale.getInstance(getActivity().getApplicationContext()).clearScaleData(selectedUserId); + openScale.clearScaleData(selectedUserId); Toast.makeText(getActivity().getApplicationContext(), getResources().getString(R.string.info_data_all_deleted), Toast.LENGTH_SHORT).show(); } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java index 0e5bc1af..1fdfa944 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java @@ -41,15 +41,13 @@ public class UsersPreferences extends PreferenceFragment { updateUserPreferences(); } - private void updateUserPreferences() - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - int selectedUserId = prefs.getInt("selectedUserId", -1); + private void updateUserPreferences() { + OpenScale openScale = OpenScale.getInstance(getActivity().getApplicationContext()); + + int selectedUserId = openScale.getSelectedScaleUserId(); getPreferenceScreen().removeAll(); - OpenScale openScale = OpenScale.getInstance(getActivity().getApplicationContext()); - List scaleUserList = openScale.getScaleUserList(); for (ScaleUser scaleUser : scaleUserList) From c463efe521fb4fda84d7836e457991f04b242b5a Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 22:49:52 +0100 Subject: [PATCH 08/10] Cache the selected scale user --- .../com/health/openscale/core/OpenScale.java | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index eb91a638..a2e59bca 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -65,6 +65,8 @@ public class OpenScale { private AppDatabase appDB; private ScaleMeasurementDAO measurementDAO; private ScaleUserDAO userDAO; + + private ScaleUser selectedScaleUser; private List scaleMeasurementList; private BluetoothCommunication btCom; @@ -145,50 +147,55 @@ public class OpenScale { public void selectScaleUser(int userId) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); prefs.edit().putInt("selectedUserId", userId).commit(); + + selectedScaleUser = null; } public int getSelectedScaleUserId() { + if (selectedScaleUser != null) { + return selectedScaleUser.getId(); + } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); return prefs.getInt("selectedUserId", -1); } - public List getScaleUserList() - { + public List getScaleUserList() { return userDAO.getAll(); } - public ScaleUser getScaleUser(int userId) - { + public ScaleUser getScaleUser(int userId) { + if (selectedScaleUser != null && selectedScaleUser.getId() == userId) { + return selectedScaleUser; + } return userDAO.get(userId); } - public ScaleUser getSelectedScaleUser() - { - ScaleUser scaleUser = new ScaleUser(); + public ScaleUser getSelectedScaleUser() { + if (selectedScaleUser != null) { + return selectedScaleUser; + } try { - int selectedUserId = getSelectedScaleUserId(); - - if (selectedUserId == -1) { - return scaleUser; + final int selectedUserId = getSelectedScaleUserId(); + if (selectedUserId != -1) { + selectedScaleUser = userDAO.get(selectedUserId); + return selectedScaleUser; } - - scaleUser = userDAO.get(selectedUserId); } catch (Exception e) { Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } - return scaleUser; + return new ScaleUser(); } - public void deleteScaleUser(int id) - { + public void deleteScaleUser(int id) { userDAO.delete(userDAO.get(id)); + selectedScaleUser = null; } - public void updateScaleUser(ScaleUser user) - { + public void updateScaleUser(ScaleUser user) { userDAO.update(user); + selectedScaleUser = null; } public List getScaleMeasurementList() { From 17887c8663eb06c3713ca7f9b18ea6c13adba5c5 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Wed, 24 Jan 2018 22:53:00 +0100 Subject: [PATCH 09/10] Use unit and gender enum directly --- .../gui/activities/UserSettingsActivity.java | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java index 80465764..9dc4b49d 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java @@ -280,54 +280,52 @@ public class UserSettingsActivity extends Activity { float initial_weight = Float.valueOf(txtInitialWeight.getText().toString()); float goal_weight = Float.valueOf(txtGoalWeight.getText().toString()); - int scale_unit = -1; + Converters.WeightUnit scale_unit = Converters.WeightUnit.KG; switch (checkedRadioButtonId) { case R.id.btnRadioKG: - scale_unit = 0; + scale_unit = Converters.WeightUnit.KG; break; case R.id.btnRadioLB: - scale_unit = 1; + scale_unit = Converters.WeightUnit.LB; break; case R.id.btnRadioST: - scale_unit = 2; + scale_unit = Converters.WeightUnit.ST; break; } - int gender = -1; + Converters.Gender gender = Converters.Gender.MALE; switch (checkedGenderId) { case R.id.btnRadioMale: - gender = 0; + gender = Converters.Gender.MALE; break; case R.id.btnRadioWoman: - gender = 1; + gender = Converters.Gender.FEMALE; break; } - int id = 0; - final ScaleUser scaleUser = new ScaleUser(); scaleUser.setUserName(name); scaleUser.setBirthday(birthday); scaleUser.setBodyHeight(body_height); - scaleUser.setScaleUnit(Converters.fromWeightUnitInt(scale_unit)); - scaleUser.setGender(Converters.fromGenderInt(gender)); + scaleUser.setScaleUnit(scale_unit); + scaleUser.setGender(gender); scaleUser.setConvertedInitialWeight(initial_weight); scaleUser.setGoalWeight(goal_weight); scaleUser.setGoalDate(goal_date); if (getIntent().getExtras().getInt("mode") == EDIT_USER_REQUEST) { - id = getIntent().getExtras().getInt("id"); + int id = getIntent().getExtras().getInt("id"); scaleUser.setId(id); openScale.updateScaleUser(scaleUser); } else { - id = openScale.addScaleUser(scaleUser); + int id = openScale.addScaleUser(scaleUser); + scaleUser.setId(id); } - openScale.selectScaleUser(id); - + openScale.selectScaleUser(scaleUser.getId()); openScale.updateScaleData(); Intent returnIntent = new Intent(); From dd2944f83d44ace7a8184a4463c381ac5b6d2f33 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Tue, 23 Jan 2018 23:16:07 +0100 Subject: [PATCH 10/10] Move measurements forward in time instead of setting year Otherwise most measurements will end up in the future. Also let the user's birthday and goal date be an offset from the current date. --- .../openscale/gui/ScreenshotRecorder.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java b/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java index dcd91635..fb928431 100644 --- a/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java +++ b/android_app/app/src/androidTest/java/com/health/openscale/gui/ScreenshotRecorder.java @@ -35,6 +35,7 @@ import com.health.openscale.core.OpenScale; import com.health.openscale.core.datatypes.ScaleMeasurement; import com.health.openscale.core.datatypes.ScaleUser; import com.health.openscale.core.utils.CsvHelper; +import com.health.openscale.core.utils.DateTimeHelpers; import org.junit.Before; import org.junit.Rule; @@ -113,26 +114,22 @@ public class ScreenshotRecorder { ScaleUser getTestUser() { ScaleUser user = new ScaleUser(); - user.setUserName("test"); + user.setUserName("Test"); user.setBodyHeight(180); user.setInitialWeight(80.0f); user.setGoalWeight(60.0f); Calendar birthday = Calendar.getInstance(); - birthday.setTimeInMillis(0); - birthday.set(Calendar.YEAR, 1990); - birthday.set(Calendar.MONTH, Calendar.JANUARY); - birthday.set(Calendar.DAY_OF_MONTH, 19); - birthday.set(Calendar.HOUR_OF_DAY, 0); + birthday.add(Calendar.YEAR, -28); + birthday.set(birthday.get(Calendar.YEAR), Calendar.JANUARY, 19, 0, 0, 0); + birthday.set(Calendar.MILLISECOND, 0); user.setBirthday(birthday.getTime()); Calendar goalDate = Calendar.getInstance(); - goalDate.setTimeInMillis(0); - goalDate.set(Calendar.YEAR, 2018); - goalDate.set(Calendar.MONTH, Calendar.JANUARY); - goalDate.set(Calendar.DAY_OF_MONTH, 31); - goalDate.set(Calendar.HOUR_OF_DAY, 0); + goalDate.add(Calendar.YEAR, 1); + goalDate.set(goalDate.get(Calendar.YEAR), Calendar.JANUARY, 31, 0, 0, 0); + goalDate.set(Calendar.MILLISECOND, 0); user.setGoalDate(goalDate.getTime()); @@ -199,13 +196,16 @@ public class ScreenshotRecorder { e.printStackTrace(); } - // set current year to the measurement data + // Move measurements forward in time Calendar measurementDate = Calendar.getInstance(); - int year = measurementDate.get(Calendar.YEAR); + if (!scaleMeasurementList.isEmpty()) { + measurementDate.setTime(scaleMeasurementList.get(0).getDateTime()); + } + final int daysToAdvance = DateTimeHelpers.daysBetween(measurementDate, Calendar.getInstance()); for (ScaleMeasurement measurement : scaleMeasurementList) { measurementDate.setTime(measurement.getDateTime()); - measurementDate.set(Calendar.YEAR, year); + measurementDate.add(Calendar.DAY_OF_YEAR, daysToAdvance); measurement.setDateTime(measurementDate.getTime()); }