Loading app/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0-beta01' implementation 'androidx.preference:preference:1.1.0-beta01' implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' } app/src/main/AndroidManifest.xml +0 −4 Original line number Diff line number Diff line Loading @@ -36,9 +36,6 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".WaypointActivity" android:parentActivityName=".MainActivity" /> <activity android:name=".SettingsActivity" /> <service Loading @@ -52,7 +49,6 @@ <service android:name=".GpxExportService" android:exported="false" /> <service android:name=".LoggerSingleService" /> <receiver android:name=".RestartBroadcastReceiver" Loading app/src/main/java/net/fabiszewski/ulogger/DbAccess.java +195 −64 Original line number Diff line number Diff line Loading @@ -26,10 +26,9 @@ import java.util.TimeZone; /** * Gateway class for database access * */ class DbAccess { class DbAccess implements AutoCloseable { private static int openCount; private static DbAccess sInstance; Loading @@ -46,6 +45,7 @@ class DbAccess { /** * Get singleton instance * * @return DbAccess singleton */ static synchronized DbAccess getInstance() { Loading @@ -55,28 +55,38 @@ class DbAccess { return sInstance; } /** * Get singleton instance with open database * Needs to be closed * * @return DbAccess singleton */ static synchronized DbAccess getOpenInstance(Context context) { if (sInstance == null) { sInstance = new DbAccess(); } sInstance.open(context); return sInstance; } /** * Opens database * * @param context Context */ void open(Context context) { synchronized (DbAccess.class) { if (openCount++ == 0) { if (Logger.DEBUG) { Log.d(TAG, "[open]"); } if (Logger.DEBUG) { Log.d(TAG, "[open]"); } mDbHelper = DbHelper.getInstance(context.getApplicationContext()); db = mDbHelper.getWritableDatabase(); } if (Logger.DEBUG) { Log.d(TAG, "[+openCount = " + openCount + "]"); } if (Logger.DEBUG) { Log.d(TAG, "[+openCount = " + openCount + "]"); } } /** * Write location to database. * * @param loc Location */ void writeLocation(Location loc) { writeLocation(loc, null, null); } /** Loading @@ -86,8 +96,10 @@ class DbAccess { * @param comment Comment * @param imageUri Image URI */ void writeLocation(Location loc, String comment, String imageUri) { if (Logger.DEBUG) { Log.d(TAG, "[writeLocation]"); } private void writeLocation(Location loc, String comment, String imageUri) { if (Logger.DEBUG) { Log.d(TAG, "[writeLocation]"); } ContentValues values = new ContentValues(); values.put(DbContract.Positions.COLUMN_TIME, loc.getTime() / 1000); values.put(DbContract.Positions.COLUMN_LATITUDE, loc.getLatitude()); Loading @@ -114,6 +126,29 @@ class DbAccess { db.insert(DbContract.Positions.TABLE_NAME, null, values); } /** * Write location to database. * * @param loc Location */ static void writeLocation(Context context, Location loc) { writeLocation(context, loc, null, null); } /** * Write location to database. * * @param context Context * @param location Location * @param comment Comment * @param imageUri Image URI */ static void writeLocation(Context context, Location location, String comment, String imageUri) { try (DbAccess dbAccess = getOpenInstance(context)) { dbAccess.writeLocation(location, comment, imageUri); } } /** * Get result set containing all positions. * Loading Loading @@ -146,7 +181,7 @@ class DbAccess { * @return Error message or null if none */ @Nullable String getError() { private String getError() { Cursor query = db.query(DbContract.Positions.TABLE_NAME, new String[]{DbContract.Positions.COLUMN_ERROR}, DbContract.Positions.COLUMN_SYNCED + "=?", Loading @@ -162,6 +197,19 @@ class DbAccess { return error; } /** * Get error message from first not synchronized position. * * @param context Context * @return Error message or null if none */ @Nullable static String getError(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getError(); } } /** * Add error message to first not synchronized position. * Loading Loading @@ -208,7 +256,7 @@ class DbAccess { * * @return Count */ int countUnsynced() { private int countUnsynced() { Cursor count = db.query(DbContract.Positions.TABLE_NAME, new String[]{"COUNT(*)"}, DbContract.Positions.COLUMN_SYNCED + "=?", Loading @@ -222,16 +270,41 @@ class DbAccess { return result; } /** * Get number of not synchronized items. * * @param context Context * @return Count */ static int countUnsynced(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.countUnsynced(); } } /** * Checks if database needs synchronization, * i.e. contains non-synchronized positions. * * @return True if synchronization needed, false otherwise */ boolean needsSync() { private boolean needsSync() { return (countUnsynced() > 0); } /** * Checks if database needs synchronization, * i.e. contains non-synchronized positions. * * @param context Context * @return True if synchronization needed, false otherwise */ static boolean needsSync(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.needsSync(); } } /** * Get first saved location time. * Loading @@ -256,7 +329,7 @@ class DbAccess { * * @return UTC timestamp in seconds */ long getLastTimestamp() { private long getLastTimestamp() { Cursor query = db.query(DbContract.Positions.TABLE_NAME, new String[]{DbContract.Positions.COLUMN_TIME}, null, null, null, null, Loading @@ -270,6 +343,18 @@ class DbAccess { return timestamp; } /** * Get last saved location time. * * @param context Context * @return UTC timestamp in seconds */ static long getLastTimestamp(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getLastTimestamp(); } } /** * Get current track id. * Loading Loading @@ -308,6 +393,17 @@ class DbAccess { return trackName; } /** * Get current track name. * * @param context Context * @return Track name, null if no track in database */ static String getTrackName(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getTrackName(); } } /** * Update current track, set id. Loading Loading @@ -336,17 +432,31 @@ class DbAccess { db.insert(DbContract.Track.TABLE_NAME, null, values); } /** * Start new track. * Deletes all previous track data and positions. Adds new track. * * @param context Context * @param name New track name */ static void newTrack(Context context, String name) { try (DbAccess dbAccess = getOpenInstance(context)) { dbAccess.newTrack(name); } } /** * Get track summary * * @return TrackSummary object, null if no positions */ @Nullable TrackSummary getTrackSummary() { static TrackSummary getTrackSummary(Context context) { try (DbAccess dbAccess = getOpenInstance(context); Cursor positions = db.query(DbContract.Positions.TABLE_NAME, new String[]{"*"}, null, null, null, null, DbContract.Positions._ID); DbContract.Positions._ID)) { TrackSummary summary = null; if (positions.moveToFirst()) { double distance = 0.0; Loading @@ -369,9 +479,9 @@ class DbAccess { long duration = endTime - startTime; summary = new TrackSummary(Math.round(distance), duration, count); } positions.close(); return summary; } } /** * Deletes all track metadata. Loading @@ -390,10 +500,13 @@ class DbAccess { /** * Closes database */ void close() { @Override public void close() { synchronized (DbAccess.class) { if (--openCount == 0) { if (Logger.DEBUG) { Log.d(TAG, "[close]"); } if (Logger.DEBUG) { Log.d(TAG, "[close]"); } if (db != null) { db.close(); Loading @@ -402,12 +515,15 @@ class DbAccess { mDbHelper.close(); } } if (Logger.DEBUG) { Log.d(TAG, "[-openCount = " + openCount + "]"); } if (Logger.DEBUG) { Log.d(TAG, "[-openCount = " + openCount + "]"); } } } /** * Get accuracy from positions cursor * * @param cursor Cursor * @return String accuracy */ Loading @@ -417,6 +533,7 @@ class DbAccess { /** * Check if cursor contains accuracy data * * @param cursor Cursor * @return True if has accuracy data */ Loading @@ -426,6 +543,7 @@ class DbAccess { /** * Get speed from positions cursor * * @param cursor Cursor * @return String speed */ Loading @@ -435,6 +553,7 @@ class DbAccess { /** * Check if cursor contains speed data * * @param cursor Cursor * @return True if has speed data */ Loading @@ -444,6 +563,7 @@ class DbAccess { /** * Get bearing from positions cursor * * @param cursor Cursor * @return String bearing */ Loading @@ -453,6 +573,7 @@ class DbAccess { /** * Check if cursor contains bearing data * * @param cursor Cursor * @return True if has bearing data */ Loading @@ -462,6 +583,7 @@ class DbAccess { /** * Get altitude from positions cursor * * @param cursor Cursor * @return String altitude */ Loading @@ -471,6 +593,7 @@ class DbAccess { /** * Check if cursor contains altitude data * * @param cursor Cursor * @return True if has altitude data */ Loading @@ -480,6 +603,7 @@ class DbAccess { /** * Get provider from positions cursor * * @param cursor Cursor * @return String provider */ Loading @@ -489,6 +613,7 @@ class DbAccess { /** * Check if cursor contains provider data * * @param cursor Cursor * @return True if has provider data */ Loading @@ -498,6 +623,7 @@ class DbAccess { /** * Get latitude from positions cursor * * @param cursor Cursor * @return String latitude */ Loading @@ -507,6 +633,7 @@ class DbAccess { /** * Get longitude from positions cursor * * @param cursor Cursor * @return String longitude */ Loading @@ -516,6 +643,7 @@ class DbAccess { /** * Get time from positions cursor * * @param cursor Cursor * @return String time */ Loading @@ -525,6 +653,7 @@ class DbAccess { /** * Get ISO 8601 formatted time from positions cursor * * @param cursor Cursor * @return String time */ Loading @@ -535,6 +664,7 @@ class DbAccess { /** * Get ID from positions cursor * * @param cursor Cursor * @return String ID */ Loading @@ -544,6 +674,7 @@ class DbAccess { /** * Format unix timestamp as ISO 8601 time * * @param timestamp Timestamp * @return Formatted time */ Loading app/src/main/java/net/fabiszewski/ulogger/ExternalCommandReceiver.java +3 −10 Original line number Diff line number Diff line Loading @@ -49,18 +49,14 @@ public class ExternalCommandReceiver extends BroadcastReceiver { } /** * Start logger service * @param context Context */ private void startLoggerService(Context context) { DbAccess db = DbAccess.getInstance(); db.open(context); if (db.getTrackName() == null) { db.newTrack(AutoNamePreference.getAutoTrackName(context)); if (DbAccess.getTrackName(context) == null) { DbAccess.newTrack(context, AutoNamePreference.getAutoTrackName(context)); } db.close(); Intent intent = new Intent(context, LoggerService.class); ContextCompat.startForegroundService(context, intent); } Loading @@ -79,12 +75,9 @@ public class ExternalCommandReceiver extends BroadcastReceiver { * @param context Context */ private void uploadData(Context context) { DbAccess db = DbAccess.getInstance(); db.open(context); if (db.needsSync()) { if (DbAccess.needsSync(context)) { Intent intent = new Intent(context, WebSyncService.class); context.startService(intent); } db.close(); } } app/src/main/java/net/fabiszewski/ulogger/GpxExportService.java +1 −2 Original line number Diff line number Diff line Loading @@ -54,8 +54,7 @@ public class GpxExportService extends IntentService { super.onCreate(); if (Logger.DEBUG) { Log.d(TAG, "[gpx export create]"); } db = DbAccess.getInstance(); db.open(this); db = DbAccess.getOpenInstance(this); } /** Loading Loading
app/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0-beta01' implementation 'androidx.preference:preference:1.1.0-beta01' implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' }
app/src/main/AndroidManifest.xml +0 −4 Original line number Diff line number Diff line Loading @@ -36,9 +36,6 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".WaypointActivity" android:parentActivityName=".MainActivity" /> <activity android:name=".SettingsActivity" /> <service Loading @@ -52,7 +49,6 @@ <service android:name=".GpxExportService" android:exported="false" /> <service android:name=".LoggerSingleService" /> <receiver android:name=".RestartBroadcastReceiver" Loading
app/src/main/java/net/fabiszewski/ulogger/DbAccess.java +195 −64 Original line number Diff line number Diff line Loading @@ -26,10 +26,9 @@ import java.util.TimeZone; /** * Gateway class for database access * */ class DbAccess { class DbAccess implements AutoCloseable { private static int openCount; private static DbAccess sInstance; Loading @@ -46,6 +45,7 @@ class DbAccess { /** * Get singleton instance * * @return DbAccess singleton */ static synchronized DbAccess getInstance() { Loading @@ -55,28 +55,38 @@ class DbAccess { return sInstance; } /** * Get singleton instance with open database * Needs to be closed * * @return DbAccess singleton */ static synchronized DbAccess getOpenInstance(Context context) { if (sInstance == null) { sInstance = new DbAccess(); } sInstance.open(context); return sInstance; } /** * Opens database * * @param context Context */ void open(Context context) { synchronized (DbAccess.class) { if (openCount++ == 0) { if (Logger.DEBUG) { Log.d(TAG, "[open]"); } if (Logger.DEBUG) { Log.d(TAG, "[open]"); } mDbHelper = DbHelper.getInstance(context.getApplicationContext()); db = mDbHelper.getWritableDatabase(); } if (Logger.DEBUG) { Log.d(TAG, "[+openCount = " + openCount + "]"); } if (Logger.DEBUG) { Log.d(TAG, "[+openCount = " + openCount + "]"); } } /** * Write location to database. * * @param loc Location */ void writeLocation(Location loc) { writeLocation(loc, null, null); } /** Loading @@ -86,8 +96,10 @@ class DbAccess { * @param comment Comment * @param imageUri Image URI */ void writeLocation(Location loc, String comment, String imageUri) { if (Logger.DEBUG) { Log.d(TAG, "[writeLocation]"); } private void writeLocation(Location loc, String comment, String imageUri) { if (Logger.DEBUG) { Log.d(TAG, "[writeLocation]"); } ContentValues values = new ContentValues(); values.put(DbContract.Positions.COLUMN_TIME, loc.getTime() / 1000); values.put(DbContract.Positions.COLUMN_LATITUDE, loc.getLatitude()); Loading @@ -114,6 +126,29 @@ class DbAccess { db.insert(DbContract.Positions.TABLE_NAME, null, values); } /** * Write location to database. * * @param loc Location */ static void writeLocation(Context context, Location loc) { writeLocation(context, loc, null, null); } /** * Write location to database. * * @param context Context * @param location Location * @param comment Comment * @param imageUri Image URI */ static void writeLocation(Context context, Location location, String comment, String imageUri) { try (DbAccess dbAccess = getOpenInstance(context)) { dbAccess.writeLocation(location, comment, imageUri); } } /** * Get result set containing all positions. * Loading Loading @@ -146,7 +181,7 @@ class DbAccess { * @return Error message or null if none */ @Nullable String getError() { private String getError() { Cursor query = db.query(DbContract.Positions.TABLE_NAME, new String[]{DbContract.Positions.COLUMN_ERROR}, DbContract.Positions.COLUMN_SYNCED + "=?", Loading @@ -162,6 +197,19 @@ class DbAccess { return error; } /** * Get error message from first not synchronized position. * * @param context Context * @return Error message or null if none */ @Nullable static String getError(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getError(); } } /** * Add error message to first not synchronized position. * Loading Loading @@ -208,7 +256,7 @@ class DbAccess { * * @return Count */ int countUnsynced() { private int countUnsynced() { Cursor count = db.query(DbContract.Positions.TABLE_NAME, new String[]{"COUNT(*)"}, DbContract.Positions.COLUMN_SYNCED + "=?", Loading @@ -222,16 +270,41 @@ class DbAccess { return result; } /** * Get number of not synchronized items. * * @param context Context * @return Count */ static int countUnsynced(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.countUnsynced(); } } /** * Checks if database needs synchronization, * i.e. contains non-synchronized positions. * * @return True if synchronization needed, false otherwise */ boolean needsSync() { private boolean needsSync() { return (countUnsynced() > 0); } /** * Checks if database needs synchronization, * i.e. contains non-synchronized positions. * * @param context Context * @return True if synchronization needed, false otherwise */ static boolean needsSync(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.needsSync(); } } /** * Get first saved location time. * Loading @@ -256,7 +329,7 @@ class DbAccess { * * @return UTC timestamp in seconds */ long getLastTimestamp() { private long getLastTimestamp() { Cursor query = db.query(DbContract.Positions.TABLE_NAME, new String[]{DbContract.Positions.COLUMN_TIME}, null, null, null, null, Loading @@ -270,6 +343,18 @@ class DbAccess { return timestamp; } /** * Get last saved location time. * * @param context Context * @return UTC timestamp in seconds */ static long getLastTimestamp(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getLastTimestamp(); } } /** * Get current track id. * Loading Loading @@ -308,6 +393,17 @@ class DbAccess { return trackName; } /** * Get current track name. * * @param context Context * @return Track name, null if no track in database */ static String getTrackName(Context context) { try (DbAccess dbAccess = getOpenInstance(context)) { return dbAccess.getTrackName(); } } /** * Update current track, set id. Loading Loading @@ -336,17 +432,31 @@ class DbAccess { db.insert(DbContract.Track.TABLE_NAME, null, values); } /** * Start new track. * Deletes all previous track data and positions. Adds new track. * * @param context Context * @param name New track name */ static void newTrack(Context context, String name) { try (DbAccess dbAccess = getOpenInstance(context)) { dbAccess.newTrack(name); } } /** * Get track summary * * @return TrackSummary object, null if no positions */ @Nullable TrackSummary getTrackSummary() { static TrackSummary getTrackSummary(Context context) { try (DbAccess dbAccess = getOpenInstance(context); Cursor positions = db.query(DbContract.Positions.TABLE_NAME, new String[]{"*"}, null, null, null, null, DbContract.Positions._ID); DbContract.Positions._ID)) { TrackSummary summary = null; if (positions.moveToFirst()) { double distance = 0.0; Loading @@ -369,9 +479,9 @@ class DbAccess { long duration = endTime - startTime; summary = new TrackSummary(Math.round(distance), duration, count); } positions.close(); return summary; } } /** * Deletes all track metadata. Loading @@ -390,10 +500,13 @@ class DbAccess { /** * Closes database */ void close() { @Override public void close() { synchronized (DbAccess.class) { if (--openCount == 0) { if (Logger.DEBUG) { Log.d(TAG, "[close]"); } if (Logger.DEBUG) { Log.d(TAG, "[close]"); } if (db != null) { db.close(); Loading @@ -402,12 +515,15 @@ class DbAccess { mDbHelper.close(); } } if (Logger.DEBUG) { Log.d(TAG, "[-openCount = " + openCount + "]"); } if (Logger.DEBUG) { Log.d(TAG, "[-openCount = " + openCount + "]"); } } } /** * Get accuracy from positions cursor * * @param cursor Cursor * @return String accuracy */ Loading @@ -417,6 +533,7 @@ class DbAccess { /** * Check if cursor contains accuracy data * * @param cursor Cursor * @return True if has accuracy data */ Loading @@ -426,6 +543,7 @@ class DbAccess { /** * Get speed from positions cursor * * @param cursor Cursor * @return String speed */ Loading @@ -435,6 +553,7 @@ class DbAccess { /** * Check if cursor contains speed data * * @param cursor Cursor * @return True if has speed data */ Loading @@ -444,6 +563,7 @@ class DbAccess { /** * Get bearing from positions cursor * * @param cursor Cursor * @return String bearing */ Loading @@ -453,6 +573,7 @@ class DbAccess { /** * Check if cursor contains bearing data * * @param cursor Cursor * @return True if has bearing data */ Loading @@ -462,6 +583,7 @@ class DbAccess { /** * Get altitude from positions cursor * * @param cursor Cursor * @return String altitude */ Loading @@ -471,6 +593,7 @@ class DbAccess { /** * Check if cursor contains altitude data * * @param cursor Cursor * @return True if has altitude data */ Loading @@ -480,6 +603,7 @@ class DbAccess { /** * Get provider from positions cursor * * @param cursor Cursor * @return String provider */ Loading @@ -489,6 +613,7 @@ class DbAccess { /** * Check if cursor contains provider data * * @param cursor Cursor * @return True if has provider data */ Loading @@ -498,6 +623,7 @@ class DbAccess { /** * Get latitude from positions cursor * * @param cursor Cursor * @return String latitude */ Loading @@ -507,6 +633,7 @@ class DbAccess { /** * Get longitude from positions cursor * * @param cursor Cursor * @return String longitude */ Loading @@ -516,6 +643,7 @@ class DbAccess { /** * Get time from positions cursor * * @param cursor Cursor * @return String time */ Loading @@ -525,6 +653,7 @@ class DbAccess { /** * Get ISO 8601 formatted time from positions cursor * * @param cursor Cursor * @return String time */ Loading @@ -535,6 +664,7 @@ class DbAccess { /** * Get ID from positions cursor * * @param cursor Cursor * @return String ID */ Loading @@ -544,6 +674,7 @@ class DbAccess { /** * Format unix timestamp as ISO 8601 time * * @param timestamp Timestamp * @return Formatted time */ Loading
app/src/main/java/net/fabiszewski/ulogger/ExternalCommandReceiver.java +3 −10 Original line number Diff line number Diff line Loading @@ -49,18 +49,14 @@ public class ExternalCommandReceiver extends BroadcastReceiver { } /** * Start logger service * @param context Context */ private void startLoggerService(Context context) { DbAccess db = DbAccess.getInstance(); db.open(context); if (db.getTrackName() == null) { db.newTrack(AutoNamePreference.getAutoTrackName(context)); if (DbAccess.getTrackName(context) == null) { DbAccess.newTrack(context, AutoNamePreference.getAutoTrackName(context)); } db.close(); Intent intent = new Intent(context, LoggerService.class); ContextCompat.startForegroundService(context, intent); } Loading @@ -79,12 +75,9 @@ public class ExternalCommandReceiver extends BroadcastReceiver { * @param context Context */ private void uploadData(Context context) { DbAccess db = DbAccess.getInstance(); db.open(context); if (db.needsSync()) { if (DbAccess.needsSync(context)) { Intent intent = new Intent(context, WebSyncService.class); context.startService(intent); } db.close(); } }
app/src/main/java/net/fabiszewski/ulogger/GpxExportService.java +1 −2 Original line number Diff line number Diff line Loading @@ -54,8 +54,7 @@ public class GpxExportService extends IntentService { super.onCreate(); if (Logger.DEBUG) { Log.d(TAG, "[gpx export create]"); } db = DbAccess.getInstance(); db.open(this); db = DbAccess.getOpenInstance(this); } /** Loading