Back to project page GeoLog.
The source code is released under:
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUC...
If you think the Android project GeoLog listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) 2013 Jorrit "Chainfire" Jongma */* ww w . j a v a 2 s.c o m*/ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package eu.chainfire.geolog.data; import java.util.Locale; import java.util.concurrent.locks.ReentrantLock; import com.google.android.gms.location.DetectedActivity; import eu.chainfire.geolog.R; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.provider.BaseColumns; import android.support.v4.content.LocalBroadcastManager; public class Database { private static final String TYPE_TEXT = " TEXT"; private static final String TYPE_INTEGER = " INTEGER"; private static final String COMMA_SEP = ","; public static final int INTERVAL_OFF = 0; // +- 25m max distance between intervals, 6 km/h, 20 km/h, 100 km/h public static final int INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT = 15; public static final int INTERVAL_NAVIGATION_HIGH_ACCURACY_BICYCLE = 5; public static final int INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE = 1; public static final int INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED = 90; // += 150m max distance between intervals public static final int INTERVAL_NAVIGATION_LOW_POWER_FOOT = 90; public static final int INTERVAL_NAVIGATION_LOW_POWER_BICYCLE = 30; public static final int INTERVAL_NAVIGATION_LOW_POWER_VEHICLE = 6; public static final int INTERVAL_NAVIGATION_LOW_POWER_FIXED = 180; public static final int INTERVAL_VERY_FAST = 30; public static final int INTERVAL_FASTER = 60; public static final int INTERVAL_FAST = 2 * 60; public static final int INTERVAL_MEDIUM_FAST = 3 * 60; public static final int INTERVAL_MEDIUM = 5 * 60; public static final int INTERVAL_SLOW = 10 * 60; public static final int INTERVAL_SLOWER = 15 * 60; public static enum Activity { UNKNOWN, STILL, FOOT, BICYCLE, VEHICLE }; public static enum Accuracy { NONE, LOW, HIGH }; public static Activity activityFromInt(int activity) { switch (activity) { case 0: return Activity.UNKNOWN; case 1: return Activity.STILL; case 2: return Activity.FOOT; case 3: return Activity.BICYCLE; case 4: return Activity.VEHICLE; } return Activity.UNKNOWN; } public static int activityToInt(Activity activity) { switch (activity) { case UNKNOWN: return 0; case STILL: return 1; case FOOT: return 2; case BICYCLE: return 3; case VEHICLE: return 4; } return 0; } public static String activityToString(Activity activity) { switch (activity) { case UNKNOWN: return "Unknown"; case STILL: return "Still"; case FOOT: return "Foot"; case BICYCLE: return "Bicycle"; case VEHICLE: return "Vehicle"; } return "Unknown"; } public static Activity activityFromDetectedActivity(DetectedActivity activity) { switch (activity.getType()) { case DetectedActivity.UNKNOWN: return Activity.UNKNOWN; case DetectedActivity.STILL: return Activity.STILL; case DetectedActivity.ON_FOOT: return Activity.FOOT; case DetectedActivity.ON_BICYCLE: return Activity.BICYCLE; case DetectedActivity.IN_VEHICLE: return Activity.VEHICLE; } return Activity.UNKNOWN; } public static boolean isDetectedActivityValid(DetectedActivity activity) { // conversion succeeds and is not unknown (default result), unless original is actually unknown return ( (activity.getType() == DetectedActivity.UNKNOWN) || (activityFromDetectedActivity(activity) != Activity.UNKNOWN) ); } public static Accuracy accuracyFromInt(int accuracy) { if (accuracy == 0) return Accuracy.NONE; if (accuracy == 1) return Accuracy.LOW; return Accuracy.HIGH; } public static int accuracyToInt(Accuracy accuracy) { if (accuracy == Accuracy.NONE) return 0; if (accuracy == Accuracy.LOW) return 1; return 2; } public static class Helper extends SQLiteOpenHelper { public static final int DATABASE_VERSION = 1; public static final String DATABASE_NAME = "geolog.db"; public static final String NOTIFY_BROADCAST = "eu.chainfire.geolog.DATABASE.UPDATED"; public static final String EXTRA_TABLE = "eu.chainfire.geolog.EXTRA.TABLE"; public static final String EXTRA_ID = "eu.chainfire.geolog.EXTRA.ID"; private static Helper instance = null; public static Helper getInstance(Context context) { if (instance == null) instance = new Helper(context.getApplicationContext()); return instance; } private ReentrantLock lock = new ReentrantLock(true); private final Context context; private Helper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; getReadableDatabase(); createDefaultEntries(getWritableDatabase()); } public void acquireLock() { lock.lock(); } public void releaseLock() { lock.unlock(); } public void notifyUri(Uri uri) { context.getContentResolver().notifyChange(uri, null); } public void notifyBroadcast(String table, long id) { Intent i = new Intent(NOTIFY_BROADCAST); i.putExtra(EXTRA_TABLE, table); i.putExtra(EXTRA_ID, id); LocalBroadcastManager.getInstance(context).sendBroadcast(i); } @Override public void onCreate(SQLiteDatabase db) { // Profiles db.execSQL(Profile.SQL_CREATE_TABLE); for (String index : Profile.SQL_CREATE_INDICES) { db.execSQL(index); } // Locations db.execSQL(Location.SQL_CREATE_TABLE); for (String index : Location.SQL_CREATE_INDICES) { db.execSQL(index); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(Profile.SQL_DROP_TABLE); db.execSQL(Location.SQL_DROP_TABLE); onCreate(db); } private void createDefaultEntries(SQLiteDatabase db) { //db.execSQL("DELETE FROM " + Profile.TABLE_NAME); //TODO //db.execSQL("ALTER TABLE " + Location.TABLE_NAME + " ADD COLUMN " + Location.COLUMN_NAME_LOG_ID + " " + TYPE_INTEGER); //db.execSQL("UPDATE " + Location.TABLE_NAME + " SET " + Location.COLUMN_NAME_LOG_ID + " = 0"); //db.execSQL("ALTER TABLE " + Profile.TABLE_NAME + " ADD COLUMN " + Profile.COLUMN_NAME_REDUCE_ACCURACY_DELAY + " " + TYPE_INTEGER); //db.execSQL("UPDATE " + Profile.TABLE_NAME + " SET " + Profile.COLUMN_NAME_REDUCE_ACCURACY_DELAY + " = 300"); if (DatabaseUtils.queryNumEntries(db, Profile.TABLE_NAME) == 0) { { Profile p = new Profile(); p.setType(Profile.Type.OFF); p.setName(context.getString(R.string.profile_name_off)); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_low_power_slow)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE * 12).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE * 12); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT * 4).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT * 4); p.getFoot().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT * 4).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT * 4); p.getBicycle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_BICYCLE * 8).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_BICYCLE * 8); p.getVehicle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE * 12).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE * 12); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_low_power_fast)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT); p.getFoot().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FOOT); p.getBicycle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_BICYCLE).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_BICYCLE); p.getVehicle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_VEHICLE); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_low_power_fixed)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_OFF).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED); p.getStill().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED); p.getFoot().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED); p.getBicycle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED); p.getVehicle().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED).setLocationInterval(INTERVAL_NAVIGATION_LOW_POWER_FIXED); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_high_accuracy_slow)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE * 36).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE * 36); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT * 8).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT * 8); p.getFoot().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT * 8).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT * 8); p.getBicycle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_BICYCLE * 16).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_BICYCLE * 16); p.getVehicle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE * 36).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE * 36); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_high_accuracy_fast)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT); p.getFoot().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FOOT); p.getBicycle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_BICYCLE).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_BICYCLE); p.getVehicle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_VEHICLE); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_high_accuracy_fixed)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_OFF).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED); p.getStill().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED); p.getFoot().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED); p.getBicycle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED); p.getVehicle().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED).setLocationInterval(INTERVAL_NAVIGATION_HIGH_ACCURACY_FIXED); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_photo_walk_low_power)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_VERY_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_FASTER).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getFoot().setAccuracy(Accuracy.LOW).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getBicycle().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getVehicle().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.saveToDatabase(this); } { Profile p = new Profile(); p.setType(Profile.Type.PRESET); p.setName(context.getString(R.string.profile_name_photo_walk_high_accuracy)); p.setReduceAccuracyDelay(300); p.getUnknown().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_VERY_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getStill().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_FASTER).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getFoot().setAccuracy(Accuracy.HIGH).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getBicycle().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.getVehicle().setAccuracy(Accuracy.NONE).setActivityInterval(INTERVAL_MEDIUM_FAST).setLocationInterval(INTERVAL_MEDIUM_FAST); p.saveToDatabase(this); } } } } public static class Profile implements BaseColumns { public static final String BASE_INTERVAL_ACTIVITY = "%s_interval_activity"; public static final String BASE_INTERVAL_LOCATION = "%s_interval_location"; public static final String BASE_ACCURACY = "%s_accuracy"; public static final String BASE_UNKNOWN = "unknown"; public static final String BASE_STILL = "still"; public static final String BASE_FOOT = "foot"; public static final String BASE_BICYCLE = "bicycle"; public static final String BASE_VEHICLE = "vehicle"; public static final String TABLE_NAME = "profiles"; public static final String COLUMN_NAME_NAME = "name"; public static final String COLUMN_NAME_TYPE = "type"; public static final String COLUMN_NAME_REDUCE_ACCURACY_DELAY = "reduce_accuracy_delay"; public static final String COLUMN_NAME_UNKNOWN_INTERVAL_ACTIVITY = String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, BASE_UNKNOWN); public static final String COLUMN_NAME_UNKNOWN_INTERVAL_LOCATION = String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, BASE_UNKNOWN); public static final String COLUMN_NAME_UNKNOWN_ACCURACY = String.format(Locale.ENGLISH, BASE_ACCURACY, BASE_UNKNOWN); public static final String COLUMN_NAME_STILL_INTERVAL_ACTIVITY = String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, BASE_STILL); public static final String COLUMN_NAME_STILL_INTERVAL_LOCATION = String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, BASE_STILL); public static final String COLUMN_NAME_STILL_ACCURACY = String.format(Locale.ENGLISH, BASE_ACCURACY, BASE_STILL); public static final String COLUMN_NAME_FOOT_INTERVAL_ACTIVITY = String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, BASE_FOOT); public static final String COLUMN_NAME_FOOT_INTERVAL_LOCATION = String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, BASE_FOOT); public static final String COLUMN_NAME_FOOT_ACCURACY = String.format(Locale.ENGLISH, BASE_ACCURACY, BASE_FOOT); public static final String COLUMN_NAME_BICYCLE_INTERVAL_ACTIVITY = String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, BASE_BICYCLE); public static final String COLUMN_NAME_BICYCLE_INTERVAL_LOCATION = String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, BASE_BICYCLE); public static final String COLUMN_NAME_BICYCLE_ACCURACY = String.format(Locale.ENGLISH, BASE_ACCURACY, BASE_BICYCLE); public static final String COLUMN_NAME_VEHICLE_INTERVAL_ACTIVITY = String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, BASE_VEHICLE); public static final String COLUMN_NAME_VEHICLE_INTERVAL_LOCATION = String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, BASE_VEHICLE); public static final String COLUMN_NAME_VEHICLE_ACCURACY = String.format(Locale.ENGLISH, BASE_ACCURACY, BASE_VEHICLE); public static final String SQL_CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT" + COMMA_SEP + COLUMN_NAME_NAME + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_TYPE + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_REDUCE_ACCURACY_DELAY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_UNKNOWN_INTERVAL_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_UNKNOWN_INTERVAL_LOCATION + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_UNKNOWN_ACCURACY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_STILL_INTERVAL_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_STILL_INTERVAL_LOCATION + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_STILL_ACCURACY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_FOOT_INTERVAL_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_FOOT_INTERVAL_LOCATION + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_FOOT_ACCURACY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_BICYCLE_INTERVAL_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_BICYCLE_INTERVAL_LOCATION + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_BICYCLE_ACCURACY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_VEHICLE_INTERVAL_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_VEHICLE_INTERVAL_LOCATION + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_VEHICLE_ACCURACY + TYPE_INTEGER + ")"; public static final String[] SQL_CREATE_INDICES = new String[] { }; public static final String SQL_DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME; public static enum Type { OFF, PRESET, USER }; private static Type typeFromInt(int type) { if (type == 0) return Type.OFF; if (type == 1) return Type.PRESET; return Type.USER; } private static int typeToInt(Type type) { if (type == Type.OFF) return 0; if (type == Type.PRESET) return 1; return 2; } public class ActivitySettings { private int activityInterval = 0; private int locationInterval = 0; private Accuracy accuracy = Accuracy.NONE; public int getActivityInterval() { return activityInterval; } public int getLocationInterval() { return locationInterval; } public Accuracy getAccuracy() { return accuracy; } public ActivitySettings setActivityInterval(int activityInterval) { this.activityInterval = activityInterval; return this; } public ActivitySettings setLocationInterval(int locationInterval) { this.locationInterval = locationInterval; return this; } public ActivitySettings setAccuracy(Accuracy accuracy) { this.accuracy = accuracy; return this; } public void loadFromCursor(Cursor cursor, String base) { activityInterval = cursor.getInt(cursor.getColumnIndex(String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, base))); locationInterval = cursor.getInt(cursor.getColumnIndex(String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, base))); accuracy = accuracyFromInt(cursor.getInt(cursor.getColumnIndex(String.format(Locale.ENGLISH, BASE_ACCURACY, base)))); } public void saveToContentValues(ContentValues values, String base) { values.put(String.format(Locale.ENGLISH, BASE_INTERVAL_ACTIVITY, base), activityInterval); values.put(String.format(Locale.ENGLISH, BASE_INTERVAL_LOCATION, base), locationInterval); values.put(String.format(Locale.ENGLISH, BASE_ACCURACY, base), accuracyToInt(accuracy)); } } private long id = -1; private String name = "OFF"; private Type type = Type.OFF; private int reduceAccuracyDelay = 0; private final ActivitySettings unknown = new ActivitySettings(); private final ActivitySettings still = new ActivitySettings(); private final ActivitySettings foot = new ActivitySettings(); private final ActivitySettings bicycle = new ActivitySettings(); private final ActivitySettings vehicle = new ActivitySettings(); public long getId() { return id; } public String getName() { return name; } public Type getType() { return type; } public int getReduceAccuracyDelay() { return reduceAccuracyDelay; } public ActivitySettings getUnknown() { return unknown; } public ActivitySettings getStill() { return still; } public ActivitySettings getFoot() { return foot; } public ActivitySettings getBicycle() { return bicycle; } public ActivitySettings getVehicle() { return vehicle; } public ActivitySettings getActivitySettings(Activity activity) { switch (activity) { case UNKNOWN: return getUnknown(); case STILL: return getStill(); case FOOT: return getFoot(); case BICYCLE: return getBicycle(); case VEHICLE: return getVehicle(); } return getUnknown(); } public Profile setType(Type type) { this.type = type; return this; } public Profile setName(String name) { this.name = name; return this; } public Profile setReduceAccuracyDelay(int reduceAccuracyDelay) { this.reduceAccuracyDelay = reduceAccuracyDelay; return this; } public void loadFromCursor(Cursor cursor) { id = cursor.getLong(cursor.getColumnIndex(_ID)); name = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_NAME)); type = typeFromInt(cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_TYPE))); reduceAccuracyDelay = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_REDUCE_ACCURACY_DELAY)); unknown.loadFromCursor(cursor, BASE_UNKNOWN); still.loadFromCursor(cursor, BASE_STILL); foot.loadFromCursor(cursor, BASE_FOOT); bicycle.loadFromCursor(cursor, BASE_BICYCLE); vehicle.loadFromCursor(cursor, BASE_VEHICLE); } public long saveToDatabase(Helper helper) { SQLiteDatabase db = helper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_NAME_NAME, name); values.put(COLUMN_NAME_TYPE, typeToInt(type)); values.put(COLUMN_NAME_REDUCE_ACCURACY_DELAY, reduceAccuracyDelay); unknown.saveToContentValues(values, BASE_UNKNOWN); still.saveToContentValues(values, BASE_STILL); foot.saveToContentValues(values, BASE_FOOT); bicycle.saveToContentValues(values, BASE_BICYCLE); vehicle.saveToContentValues(values, BASE_VEHICLE); if (id < 0) { id = db.insert(TABLE_NAME, null, values); } else { db.update(TABLE_NAME, values, _ID + " = ?", new String[] { String.valueOf(id) }); } if (id >= 0) { helper.notifyUri(ProfilesProvider.URILocations()); helper.notifyUri(ProfilesProvider.URILocation(id)); helper.notifyBroadcast(TABLE_NAME, id); } return id; } public static Profile getById(Helper helper, long id, Profile into) { Cursor cursor = helper.getReadableDatabase().rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + _ID + " = ?", new String[] { String.valueOf(id) }); if (cursor != null) { try { if (cursor.moveToFirst()) { if (into == null) into = new Profile(); into.loadFromCursor(cursor); return into; } } finally { cursor.close(); } } return null; } public static void delete(Helper helper, long id) { helper.getWritableDatabase().delete(TABLE_NAME, _ID + " = ?", new String[] { String.valueOf(id) }); helper.notifyUri(ProfilesProvider.URILocations()); helper.notifyUri(ProfilesProvider.URILocation(id)); helper.notifyBroadcast(TABLE_NAME, id); } private static void copyActivitySettings(ActivitySettings source, ActivitySettings destination) { destination.setAccuracy(source.getAccuracy()); destination.setLocationInterval(source.getLocationInterval()); destination.setActivityInterval(source.getActivityInterval()); } public static Profile copy(Helper helper, Profile profile, String name) { Profile ret = new Profile(); ret.setName(name); ret.setType(Type.USER); ret.setReduceAccuracyDelay(profile.getReduceAccuracyDelay()); copyActivitySettings(profile.getUnknown() , ret.getUnknown() ); copyActivitySettings(profile.getStill() , ret.getStill() ); copyActivitySettings(profile.getFoot() , ret.getFoot() ); copyActivitySettings(profile.getBicycle() , ret.getBicycle() ); copyActivitySettings(profile.getVehicle() , ret.getVehicle() ); ret.saveToDatabase(helper); return ret; } public static Cursor list(Helper helper) { return helper.getReadableDatabase().query(TABLE_NAME, null, COLUMN_NAME_TYPE + " <> ?", new String[] { String.valueOf(typeToInt(Type.OFF)) }, null, null, _ID); } public static Profile getOffProfile(Helper helper) { Cursor cursor = helper.getReadableDatabase().rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_NAME_TYPE + " = ?", new String[] { String.valueOf(typeToInt(Type.OFF)) }); if (cursor != null) { try { if (cursor.moveToFirst()) { Profile into = new Profile(); into.loadFromCursor(cursor); return into; } } finally { cursor.close(); } } return null; } } public static class Location implements BaseColumns { public static final String TABLE_NAME = "locations"; public static final String COLUMN_NAME_LOG_ID = "log_id"; public static final String COLUMN_NAME_ACTIVITY = "activity"; public static final String COLUMN_NAME_CONFIDENCE = "confidence"; public static final String COLUMN_NAME_TIME = "time"; public static final String COLUMN_NAME_LATITUDE = "latitude"; public static final String COLUMN_NAME_LONGITUDE = "longitude"; public static final String COLUMN_NAME_ALTITUDE = "altitude"; public static final String COLUMN_NAME_HAS_ALTITUDE = "has_altitude"; public static final String COLUMN_NAME_BEARING = "bearing"; public static final String COLUMN_NAME_HAS_BEARING = "has_bearing"; public static final String COLUMN_NAME_SPEED = "speed"; public static final String COLUMN_NAME_HAS_SPEED = "has_speed"; public static final String COLUMN_NAME_ACCURACY_DISTANCE = "location_accuracy"; public static final String COLUMN_NAME_HAS_ACCURACY_DISTANCE = "has_location_accuracy"; public static final String COLUMN_NAME_BATTERY = "battery"; public static final String COLUMN_NAME_ACCURACY_SETTING = "accuracy_setting"; public static final String COLUMN_NAME_IS_SEGMENT_START = "is_segment_start"; public static final String SQL_CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT" + COMMA_SEP + COLUMN_NAME_LOG_ID + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_ACTIVITY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_CONFIDENCE + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_TIME + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_LATITUDE + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_LONGITUDE + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_ALTITUDE + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_HAS_ALTITUDE + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_BEARING + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_HAS_BEARING + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_SPEED + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_HAS_SPEED + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_ACCURACY_DISTANCE + TYPE_TEXT + COMMA_SEP + COLUMN_NAME_HAS_ACCURACY_DISTANCE + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_BATTERY + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_ACCURACY_SETTING + TYPE_INTEGER + COMMA_SEP + COLUMN_NAME_IS_SEGMENT_START + TYPE_INTEGER + ")"; public static final String[] SQL_CREATE_INDICES = new String[] { }; public static final String SQL_DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME; private long id = -1; private long logid = 0; private Activity activity = Activity.UNKNOWN; private int confidence = 0; private long time = 0; private double latitude = 0; private double longitude = 0; private double altitude = 0; private boolean hasAltitude = false; private float bearing = 0; private boolean hasBearing = false; private float speed = 0; private boolean hasSpeed = false; private float accuracyDistance = 0; private boolean hasAccuracyDistance = false; private int battery = 0; private Accuracy accuracySetting = Accuracy.NONE; private boolean isSegmentStart = false; public long getId() { return id; } public long getLogId() { return logid; } public Activity getActivity() { return activity; } public int getConfidence() { return confidence; } public long getTime() { return time; } public double getLatitude() { return latitude; } public double getLongitude() { return longitude; } public double getAltitude() { return altitude; } public boolean hasAltitude() { return hasAltitude; } public float getBearing() { return bearing; } public boolean hasBearing() { return hasBearing; } public float getSpeed() { return speed; } public boolean hasSpeed() { return hasSpeed; } public float getAccuracyDistance() { return accuracyDistance; } public boolean hasAccuracyDistance() { return hasAccuracyDistance; } public int getBattery() { return battery; } public Accuracy getAccuracySetting() { return accuracySetting; } public boolean isSegmentStart() { return isSegmentStart; } public Location setLogId(long logid) { this.logid = logid; return this; } public Location setActivity(Activity activity) { this.activity = activity; return this; } public Location setConfidence(int confidence) { this.confidence = confidence; return this; } public Location setTime(long time) { this.time = time; return this; } public Location setLatitude(double latitude) { this.latitude = latitude; return this; } public Location setLongitude(double longitude) { this.longitude = longitude; return this; } public Location setAltitude(double altitude) { this.altitude = altitude; return this; } public Location hasAltitude(boolean hasAltitude) { this.hasAltitude = hasAltitude; return this; } public Location setBearing(float bearing) { this.bearing = bearing; return this; } public Location hasBearing(boolean hasBearing) { this.hasBearing = hasBearing; return this; } public Location setSpeed(float speed) { this.speed = speed; return this; } public Location hasSpeed(boolean hasSpeed) { this.hasSpeed = hasSpeed; return this; } public Location setAccuracyDistance(float accuracyDistance) { this.accuracyDistance = accuracyDistance; return this; } public Location hasAccuracyDistance(boolean hasAccuracyDistance) { this.hasAccuracyDistance = hasAccuracyDistance; return this; } public Location setBattery(int battery) { this.battery = battery; return this; } public Location setAccuracySetting(Accuracy accuracySetting) { this.accuracySetting = accuracySetting; return this; } public Location isSegmentStart(boolean isSegmentStart) { this.isSegmentStart = isSegmentStart; return this; } public void loadFromCursor(Cursor cursor) { id = cursor.getLong(cursor.getColumnIndex(_ID)); logid = cursor.getLong(cursor.getColumnIndex(COLUMN_NAME_LOG_ID)); activity = activityFromInt(cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ACTIVITY))); confidence = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_CONFIDENCE)); time = cursor.getLong(cursor.getColumnIndex(COLUMN_NAME_TIME)); latitude = Double.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_LATITUDE))); longitude = Double.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_LONGITUDE))); altitude = Double.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_ALTITUDE))); hasAltitude = (cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HAS_ALTITUDE)) == 1); bearing = Float.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_BEARING))); hasBearing = (cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HAS_BEARING)) == 1); speed = Float.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SPEED))); hasSpeed = (cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HAS_SPEED)) == 1); accuracyDistance = Float.valueOf(cursor.getString(cursor.getColumnIndex(COLUMN_NAME_ACCURACY_DISTANCE))); hasAccuracyDistance = (cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HAS_ACCURACY_DISTANCE)) == 1); battery = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_BATTERY)); accuracySetting = accuracyFromInt(cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ACCURACY_SETTING))); isSegmentStart = (cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_IS_SEGMENT_START)) == 1); } public void loadFromDetectedActivity(DetectedActivity detectedActivity) { activity = activityFromDetectedActivity(detectedActivity); confidence = detectedActivity.getConfidence(); } public void loadFromLocation(android.location.Location location) { time = location.getTime(); latitude = location.getLatitude(); longitude = location.getLongitude(); altitude = location.getAltitude(); hasAltitude = location.hasAltitude(); bearing = location.getBearing(); hasBearing = location.hasBearing(); speed = location.getSpeed(); hasSpeed = location.hasSpeed(); accuracyDistance = location.getAccuracy(); hasAccuracyDistance = location.hasAccuracy(); } public long saveToDatabase(Helper helper) { SQLiteDatabase db = helper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_NAME_LOG_ID, logid); values.put(COLUMN_NAME_ACTIVITY, activityToInt(activity)); values.put(COLUMN_NAME_CONFIDENCE, confidence); values.put(COLUMN_NAME_TIME, time); values.put(COLUMN_NAME_LATITUDE, String.valueOf(latitude)); values.put(COLUMN_NAME_LONGITUDE, String.valueOf(longitude)); values.put(COLUMN_NAME_ALTITUDE, String.valueOf(altitude)); values.put(COLUMN_NAME_HAS_ALTITUDE, hasAltitude ? 1 : 0); values.put(COLUMN_NAME_BEARING, String.valueOf(bearing)); values.put(COLUMN_NAME_HAS_BEARING, hasBearing ? 1 : 0); values.put(COLUMN_NAME_SPEED, String.valueOf(speed)); values.put(COLUMN_NAME_HAS_SPEED, hasSpeed ? 1 : 0); values.put(COLUMN_NAME_ACCURACY_DISTANCE, String.valueOf(accuracyDistance)); values.put(COLUMN_NAME_HAS_ACCURACY_DISTANCE, hasAccuracyDistance ? 1 : 0); values.put(COLUMN_NAME_BATTERY, battery); values.put(COLUMN_NAME_ACCURACY_SETTING, accuracyToInt(accuracySetting)); values.put(COLUMN_NAME_IS_SEGMENT_START, isSegmentStart ? 1 : 0); if (id < 0) { id = db.insert(TABLE_NAME, null, values); } else { db.update(TABLE_NAME, values, _ID + " = ?", new String[] { String.valueOf(id) }); } if (id >= 0) { helper.notifyUri(LogsProvider.URILocations()); helper.notifyUri(LogsProvider.URILocation(id)); helper.notifyBroadcast(TABLE_NAME, id); } return id; } public static Location getById(Helper helper, long id, Location into) { Cursor cursor = helper.getReadableDatabase().rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + _ID + " = ?", new String[] { String.valueOf(id) }); if (cursor != null) { try { if (cursor.moveToFirst()) { if (into == null) into = new Location(); into.loadFromCursor(cursor); return into; } } finally { cursor.close(); } } return null; } public static void delete(Helper helper, long id) { helper.getWritableDatabase().delete(TABLE_NAME, _ID + " = ?", new String[] { String.valueOf(id) }); helper.notifyUri(LogsProvider.URILocations()); helper.notifyUri(LogsProvider.URILocation(id)); helper.notifyBroadcast(TABLE_NAME, id); } public static void deleteAll(Helper helper) { helper.getWritableDatabase().delete(TABLE_NAME, null, null); helper.notifyUri(LogsProvider.URILocations()); helper.notifyUri(LogsProvider.URILocation(0)); helper.notifyBroadcast(TABLE_NAME, 0); } public static Location copy(Helper helper, Location location) { Location ret = new Location(); ret.setLogId(location.getLogId()); ret.setActivity(location.getActivity()); ret.setConfidence(location.getConfidence()); ret.setTime(location.getTime()); ret.setLatitude(location.getLatitude()); ret.setLongitude(location.getLongitude()); ret.setAltitude(location.getAltitude()); ret.hasAltitude(location.hasAltitude()); ret.setBearing(location.getBearing()); ret.hasBearing(location.hasBearing()); ret.setSpeed(location.getSpeed()); ret.hasSpeed(location.hasSpeed()); ret.setAccuracyDistance(location.getAccuracyDistance()); ret.hasAccuracyDistance(location.hasAccuracyDistance()); ret.setBattery(location.getBattery()); ret.setAccuracySetting(location.getAccuracySetting()); ret.isSegmentStart(location.isSegmentStart()); ret.saveToDatabase(helper); return ret; } public static Cursor list(Helper helper) { return helper.getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, _ID); } } }