1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.locationtracker.data; 18 19 import android.content.ContentValues; 20 import android.database.Cursor; 21 import android.location.Location; 22 23 24 /** 25 * Class that holds a tracker entry. An entry can be either a valid location, or 26 * a simple log msg 27 * 28 * It provides a concrete data structure to represent data stored in the 29 * TrackerProvider 30 */ 31 class TrackerEntry { 32 33 static final String TIMESTAMP = "Timestamp"; 34 static final String TAG = "Tag"; 35 static final String ENTRY_TYPE = "Type"; 36 37 private Location mLocation; 38 private float mDistFromNetLocation; 39 private String mLogMsg; 40 41 static final String ID_COL = "_id"; 42 static final String ACCURACY = "Accuracy"; 43 static final String LATITUDE = "Latitude"; 44 static final String LONGITUDE = "Longitude"; 45 static final String ALTITUDE = "Altitude"; 46 static final String SPEED = "Speed"; 47 static final String BEARING = "Bearing"; 48 static final String DIST_NET_LOCATION = "DistFromNetLocation"; 49 static final String LOC_TIME = "LocationTime"; 50 static final String DEBUG_INFO = "DebugInfo"; 51 52 static final String STRING_DATA = "STRING"; 53 static final String INT_DATA = "INTEGER"; 54 static final String REAL_DATA = "REAL"; 55 static final String BLOB_DATA = "BLOB"; 56 57 static final String[] ATTRIBUTES = { 58 ID_COL, TIMESTAMP, TAG, ENTRY_TYPE, ACCURACY, LATITUDE, LONGITUDE, 59 ALTITUDE, SPEED, BEARING, DIST_NET_LOCATION, LOC_TIME, DEBUG_INFO}; 60 static final String[] ATTRIBUTES_DATA_TYPE = { 61 INT_DATA + " PRIMARY KEY", STRING_DATA, STRING_DATA, STRING_DATA, 62 REAL_DATA, REAL_DATA, REAL_DATA, REAL_DATA, REAL_DATA, REAL_DATA, 63 REAL_DATA, INT_DATA, STRING_DATA}; 64 65 // location extra keys used to retrieve debug info 66 private static final String NETWORK_LOCATION_SOURCE_KEY = 67 "networkLocationSource"; 68 private static final String NETWORK_LOCATION_TYPE_KEY = 69 "networkLocationType"; 70 private static final String[] LOCATION_DEBUG_KEYS = { 71 NETWORK_LOCATION_SOURCE_KEY, NETWORK_LOCATION_TYPE_KEY}; 72 73 enum EntryType { 74 LOCATION_TYPE, LOG_TYPE 75 } 76 77 private String mTimestamp; 78 private String mTag; 79 private EntryType mType; 80 TrackerEntry(String tag, EntryType type)81 private TrackerEntry(String tag, EntryType type) { 82 mType = type; 83 mTag = tag; 84 mLocation = null; 85 } 86 TrackerEntry(Location loc)87 private TrackerEntry(Location loc) { 88 this(loc.getProvider(), EntryType.LOCATION_TYPE); 89 mLocation = new Location(loc); 90 } 91 92 /** 93 * Creates a TrackerEntry from a Location 94 */ createEntry(Location loc, float distFromNetLocation)95 static TrackerEntry createEntry(Location loc, float distFromNetLocation) { 96 TrackerEntry entry = new TrackerEntry(loc); 97 98 String timestampVal = DateUtils.getCurrentKMLTimestamp(); 99 entry.setTimestamp(timestampVal); 100 entry.setDistFromNetLocation(distFromNetLocation); 101 return entry; 102 } 103 104 /** 105 * Creates a TrackerEntry from a log msg 106 */ createEntry(String tag, String msg)107 static TrackerEntry createEntry(String tag, String msg) { 108 TrackerEntry entry = new TrackerEntry(tag, EntryType.LOG_TYPE); 109 String timestampVal = DateUtils.getCurrentKMLTimestamp(); 110 entry.setTimestamp(timestampVal); 111 entry.setLogMsg(msg); 112 return entry; 113 } 114 setTimestamp(String timestamp)115 private void setTimestamp(String timestamp) { 116 mTimestamp = timestamp; 117 } 118 getType()119 EntryType getType() { 120 return mType; 121 } 122 setDistFromNetLocation(float distFromNetLocation)123 private void setDistFromNetLocation(float distFromNetLocation) { 124 mDistFromNetLocation = distFromNetLocation; 125 } 126 setLogMsg(String msg)127 private void setLogMsg(String msg) { 128 mLogMsg = msg; 129 } 130 setLocation(Location location)131 private void setLocation(Location location) { 132 mLocation = location; 133 } 134 getTimestamp()135 String getTimestamp() { 136 return mTimestamp; 137 } 138 getTag()139 String getTag() { 140 return mTag; 141 } 142 getLocation()143 Location getLocation() { 144 return mLocation; 145 } 146 getLogMsg()147 String getLogMsg() { 148 return mLogMsg; 149 } 150 getDistFromNetLocation()151 float getDistFromNetLocation() { 152 return mDistFromNetLocation; 153 } 154 buildCreationString(StringBuilder builder)155 static void buildCreationString(StringBuilder builder) { 156 if (ATTRIBUTES.length != ATTRIBUTES_DATA_TYPE.length) { 157 throw new IllegalArgumentException( 158 "Attribute length does not match data type length"); 159 } 160 for (int i = 0; i < ATTRIBUTES_DATA_TYPE.length; i++) { 161 if (i != 0) { 162 builder.append(", "); 163 } 164 builder.append(String.format("%s %s", ATTRIBUTES[i], 165 ATTRIBUTES_DATA_TYPE[i])); 166 } 167 } 168 getAsContentValues()169 ContentValues getAsContentValues() { 170 ContentValues cValues = new ContentValues(ATTRIBUTES.length); 171 cValues.put(TIMESTAMP, mTimestamp); 172 cValues.put(TAG, mTag); 173 cValues.put(ENTRY_TYPE, mType.toString()); 174 if (mType == EntryType.LOCATION_TYPE) { 175 cValues.put(LATITUDE, mLocation.getLatitude()); 176 cValues.put(LONGITUDE, mLocation.getLongitude()); 177 if (mLocation.hasAccuracy()) { 178 cValues.put(ACCURACY, mLocation.getAccuracy()); 179 } 180 if (mLocation.hasAltitude()) { 181 cValues.put(ALTITUDE, mLocation.getAltitude()); 182 } 183 if (mLocation.hasSpeed()) { 184 cValues.put(SPEED, mLocation.getSpeed()); 185 } 186 if (mLocation.hasBearing()) { 187 cValues.put(BEARING, mLocation.getBearing()); 188 } 189 cValues.put(DIST_NET_LOCATION, mDistFromNetLocation); 190 cValues.put(LOC_TIME, mLocation.getTime()); 191 StringBuilder debugBuilder = new StringBuilder(""); 192 if (mLocation.getExtras() != null) { 193 for (String key : LOCATION_DEBUG_KEYS) { 194 Object val = mLocation.getExtras().get(key); 195 if (val != null) { 196 debugBuilder.append(String.format("%s=%s; ", key, val 197 .toString())); 198 } 199 } 200 } 201 cValues.put(DEBUG_INFO, debugBuilder.toString()); 202 } else { 203 cValues.put(DEBUG_INFO, mLogMsg); 204 } 205 return cValues; 206 } 207 createEntry(Cursor cursor)208 static TrackerEntry createEntry(Cursor cursor) { 209 String timestamp = cursor.getString(cursor.getColumnIndex(TIMESTAMP)); 210 String tag = cursor.getString(cursor.getColumnIndex(TAG)); 211 String sType = cursor.getString(cursor.getColumnIndex(ENTRY_TYPE)); 212 TrackerEntry entry = new TrackerEntry(tag, EntryType.valueOf(sType)); 213 entry.setTimestamp(timestamp); 214 if (entry.getType() == EntryType.LOCATION_TYPE) { 215 Location location = new Location(tag); 216 location.setLatitude(cursor.getFloat(cursor 217 .getColumnIndexOrThrow(LATITUDE))); 218 location.setLongitude(cursor.getFloat(cursor 219 .getColumnIndexOrThrow(LONGITUDE))); 220 221 Float accuracy = getNullableFloat(cursor, ACCURACY); 222 if (accuracy != null) { 223 location.setAccuracy(accuracy); 224 } 225 Float altitude = getNullableFloat(cursor, ALTITUDE); 226 if (altitude != null) { 227 location.setAltitude(altitude); 228 } 229 Float bearing = getNullableFloat(cursor, BEARING); 230 if (bearing != null) { 231 location.setBearing(bearing); 232 } 233 Float speed = getNullableFloat(cursor, SPEED); 234 if (speed != null) { 235 location.setSpeed(speed); 236 } 237 location.setTime(cursor.getLong(cursor.getColumnIndex(LOC_TIME))); 238 entry.setLocation(location); 239 } 240 entry.setLogMsg(cursor.getString(cursor.getColumnIndex(DEBUG_INFO))); 241 242 return entry; 243 } 244 getNullableFloat(Cursor cursor, String colName)245 private static Float getNullableFloat(Cursor cursor, String colName) { 246 Float retValue = null; 247 int colIndex = cursor.getColumnIndexOrThrow(colName); 248 if (!cursor.isNull(colIndex)) { 249 retValue = cursor.getFloat(colIndex); 250 } 251 return retValue; 252 } 253 } 254