我构建的应用程序,读取当前位置的坐标(每10-20米)时移动移动的街道和显示当前的纬度/经度,现在我想开发的应用程序,保存(存储)这些纬度/经度到sqlite数据库。任何帮助(指南)作为起点,将不胜感激。
首先需要设计数据库模式。仅仅存储晚/晚可能是相当无用的。你说每隔10-20米,所以还有别的东西,也许是时间使经纬线/纬度有用。
因此,假设时间是与经纬线结合的因素,使其有用。然后每一行你想要存储的时间,长度和时间。
因此,在您的模式中将有3列,因为row(一个特殊的列)包含在所有表中(除了一些不太常用的例外)。然后是4列(行号唯一标识一行)。
所以你的schema可以是:-
- 一个用于存储行的列,但只是在情况下,标准android baseccolumns将被使用等同于_ID,存储的值将是一个唯一的整数(长),它将是主键(这意味着一个唯一的列)。
- 最后一个双精度的列应该足够了
- 同样适用于lon
- 日期/时间可以存储为长
下一个阶段是做所有数据库处理的东西。这可以通过扩展SQLiteOpenHelper类来大大简化。
你可以有一个类来做这个。该类必须实现两个覆盖方法onCreate和onUpgrade.
- onCreate在创建数据库时被调用,并且是创建表和其他组件(例如设置模式)的地方。
- 注意,这是在数据库生命周期内的一次
- onUpgrade用于处理数据库版本更改,超出了本答案的范围。它什么也不做。
您可能希望最小化数据库的打开和关闭,因为这两种操作都可能相对地消耗资源。因此,建议使用不关闭数据库的单例方法。
您可能希望在类中包含访问数据库(CRUD)的方法。
那么把上面的内容放在一起你就可以得到,例如类DBHelper: -
class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "the_database.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME_LATLON = "_latlon";
public static final String COL_NAME_LATLON_ID = BaseColumns._ID;
public static final String COL_NAME_LATLON_LAT = "_lat";
public static final String COl_NAME_LATLON_LON = "_lon";
public static final String COL_NAME_TIMESTAMP = "_timestamp";
private static final String TABLE_LATLON_CRTSQL = "CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME_LATLON + "("
+ COL_NAME_LATLON_ID + " INTEGER PRIMARY KEY"
+ "," + COL_NAME_LATLON_LAT + " REAL "
+ "," + COl_NAME_LATLON_LON + " REAL "
+ "," + COL_NAME_TIMESTAMP + " INTEGER "
+ ")";
/* protect the constructor from being used elsewhere, thus forcing use of the singleton */
private SQLiteDatabase db;
private DBHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
db = this.getWritableDatabase();
}
/* Use a singleton approach */
private volatile static DBHelper INSTANCE=null;
public static DBHelper getInstance(Context context) {
if (INSTANCE==null) {
INSTANCE = new DBHelper(context);
}
return INSTANCE;
}
@Override /* REQUIRED - ****NOTE ONLY EVER RUNS ONCE FOR THE LIFETIME OF THE DATABASE**** */
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_LATLON_CRTSQL);
}
@Override /* REQUIRED (but doesn't have to do anything)*/
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
/* Full Insert method */
public long insertLatLonRow(Long id,double lat, double lon,Long timestamp) {
ContentValues cv = new ContentValues();
if (id != null && id > -1) {
cv.put(COL_NAME_LATLON_ID,id);
}
cv.put(COL_NAME_LATLON_LAT,lat);
cv.put(COl_NAME_LATLON_LON,lon);
if (timestamp == null) {
timestamp = System.currentTimeMillis() / 1000;
}
cv.put(COL_NAME_TIMESTAMP,timestamp);
return db.insert(TABLE_NAME_LATLON,null,cv);
}
/* Partial Insert method lat,lon and timestamp */
public long insertLatLonRow(double lat, double lon, long timestamp) {
return insertLatLonRow(null, lat,lon,timestamp);
}
/* Partial Insert method (calls full method) */
public long insertLatLonRow(double lat, double lon) {
return insertLatLonRow(null,lat,lon,null);
}
/* Extract data */
public Cursor getLatLonsForAPeriod(long start_timestamp, long end_timestamp) {
return db.query(
TABLE_NAME_LATLON, /* The table that the rows will be SELECTed from */
null /* ALL COLUMNS */,
COL_NAME_TIMESTAMP + " BETWEEN ? AND ?", /* The WHERE clause (less the WHERE keyword) note that ?'s will be bound (replaced)*/
new String[]{String.valueOf(start_timestamp),String.valueOf(end_timestamp)}, /* The values to be bound first replaces the first?, 2nd the 2nd .... */
null, /* no GROUP BY clause*/
null, /* no HAVING clause */
COL_NAME_TIMESTAMP /* ORDER BY clause */
);
}
}
DBHelper自己不会做任何事情,所以这里有一个使用它的示例。这将插入一些数据(2行),然后提取数据并将其写入日志:-
public class MainActivity extends AppCompatActivity {
DBHelper mDBHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHelper = DBHelper.getInstance(this);
/* Add some test data */
mDBHelper.insertLatLonRow(10.1,100.5678);
mDBHelper.insertLatLonRow(null,11.1,11.6789,(System.currentTimeMillis() / 1000) - (60 * 60)); /* 1 hour before */
/* Extract the data */
Cursor csr = mDBHelper.getLatLonsForAPeriod((System.currentTimeMillis() / 1000) - (10 * 60 * 60),System.currentTimeMillis() / 1000 + (60 * 60));
int id_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_ID);
int lat_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_LAT);
int lon_offset = csr.getColumnIndex(DBHelper.COl_NAME_LATLON_LON);
int ts_offset = csr.getColumnIndex(DBHelper.COL_NAME_TIMESTAMP);
while (csr.moveToNext()) {
Log.d(
"LATLONINFO",
"ID is " + csr.getString(id_offset)
+ " LAT is " + csr.getDouble(lat_offset)
+ " LON is " + csr.getDouble(lon_offset)
+ " TimeStamp is " + csr.getLong(ts_offset)
);
}
}
}
结果: -
当运行2行时,将插入第二行,第二行时间比第一行早1小时。然后提取数据(从10小时前到未来1小时之间的行(所有行都符合此标准))。然而,由于它们是根据时间戳排序的(按升序排列(默认)),第2行首先显示。
日志因此包括(如预期的):-
D/LATLONINFO: ID is 2 LAT is 11.1 LON is 11.6789 TimeStamp is 1656841299
D/LATLONINFO: ID is 1 LAT is 10.1 LON is 100.5678 TimeStamp is 1656844899