Android Open Source - GeoLog Database






From Project

Back to project page GeoLog.

License

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.

Java Source Code

/*
 * 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);      
    }    
  }
}




Java Source Code List

eu.chainfire.geolog.Application.java
eu.chainfire.geolog.CrashCatcher.java
eu.chainfire.geolog.Debug.java
eu.chainfire.geolog.data.Database.java
eu.chainfire.geolog.data.Exporter.java
eu.chainfire.geolog.data.LogsProvider.java
eu.chainfire.geolog.data.ProfilesProvider.java
eu.chainfire.geolog.service.BackgroundService.java
eu.chainfire.geolog.service.BootCompleteReceiver.java
eu.chainfire.geolog.ui.ExportActivity.java
eu.chainfire.geolog.ui.LogsFragment.java
eu.chainfire.geolog.ui.MainActivity.java
eu.chainfire.geolog.ui.Pref.java
eu.chainfire.geolog.ui.PreferenceListFragment.java
eu.chainfire.geolog.ui.ProfileActivity.java
eu.chainfire.geolog.ui.ProfilesFragment.java
eu.chainfire.geolog.ui.SettingsFragment.java