我有一个简单的SQLite数据库,有两列。
Col 1 SimpleDateFormat(“yyyyDDD”)例如2017001(2017年1月1日)
Col 2 int of occurrence
因此,在极少数情况下,一整天都没有发生任何事情,当天没有任何东西插入我的数据库。我希望在这种情况下填充零,否则在绘制数据时会绕过那一天。
我做了一些研究,我正在考虑的解决方案是设置一个RTC警报,并且每24小时填充一个零发生行。在发生事件的可能事件中,零点在汇总并发送到图表时不会影响我的数据。如果没有发生,我会在那里得零。
更优雅的解决方案是退出吗?我没有使用android警报的经验。 RTC报警的任何缺点?也许SQLite有一些我可以利用的功能?我愿意接受任何解决方案。
修改
我没有提到即使在应用程序永远不会打开的几天内也必须添加零。这是一个重要的区别,我之前没有提到过。可以在应用程序启动时追溯添加行(可能在关闭几天之后)。感谢到目前为止的回复。
答案 0 :(得分:1)
这是一种不依赖后台任务或向数据库添加额外(无用/浪费)数据的方法。
基本上提取数据,并将任何缺失的天数和实际天数添加到MatrixCursor
(可以动态构建的光标)。
主要方法是getExpandedRows
,它有两种支持方法: -
setDate
(根据包含try catch
的yyyyDDD格式的字符串设置java Date对象)addMatrixRow
向MatrixCursor
添加一行,并将下一个日期作为Java日期返回。 getExpandedRows
将两个参数的开始日期和结束日期作为yyyyDDDD格式的字符串,这些用于a)从数据库中选择适当的行,b)驱动逻辑添加缺失的行(天)。
所有这些都在SQLiteOpenHelper
子类 DBHelper 中: -
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mystats";
public static final String TBNAME = "mystats";
public static final String COL1 = "date";
public static final String COL2 = "value";
SQLiteDatabase mDB;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyDDD");
long oneday = 1000 * 60 * 60 * 24;
DBHelper(Context context) {
super(context, DBNAME, null, 1);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " + TBNAME + "(" +
COL1 + " TEXT UNIQUE NOT NULL, " +
COL2 + " INTEGER " +
")";
db.execSQL(crtsql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public void addData(String date, int value) {
ContentValues cv = new ContentValues();
cv.put(COL1,date);
cv.put(COL2,value);
mDB.insert(TBNAME,null,cv);
}
public Cursor getAllRows(String filter) {
return mDB.query(TBNAME,null,filter,null,null,null,null);
}
public Cursor getExpandedRows(String startdate, String enddate) {
Date lastdate = setDate(startdate), finishdate = setDate(enddate), currentdate = new Date(0);
int daysinperiod = (int)((finishdate.getTime() - lastdate.getTime()) / oneday);
// get the base data
String filter = COL1 + " BETWEEN " + startdate + " AND " + enddate + " ";
Cursor base = getAllRows(filter);
Log.d("GetExpRows","Rows Extracted from base data = " + Integer.toString(base.getCount()));
MatrixCursor mc = new MatrixCursor(new String[]{COL1,COL2},daysinperiod);
while (base.moveToNext()) {
currentdate = setDate(base.getString(base.getColumnIndex(COL1)));
while (lastdate.getTime() < currentdate.getTime()) {
lastdate = addMatrixRow(mc, lastdate, 0L);
}
lastdate = addMatrixRow(mc, currentdate, base.getLong(base.getColumnIndex(COL2)));
}
while (currentdate.getTime() <= finishdate.getTime()) {
currentdate = addMatrixRow(mc,currentdate, 0L);
}
base.close();
return mc;
}
private Date addMatrixRow(MatrixCursor mc, Date date, Long value) {
mc.addRow(new Object[]{sdf.format(date.getTime()),value});
return new Date(date.getTime() + oneday);
}
private Date setDate(String date) {
Date rv = new Date(0L);
try {
rv = sdf.parse(date);
} catch (Exception e) {
}
return rv;
} }
要测试4天的行数: -
2016364-2018004 期间被选中进行测试。
这是用于测试的调用活动,(注意您可以使用Matrix Cursor作为普通Cursor)。主线是 Cursor mydata = dbhlpr.getExpandedRows("2016364","2018005");
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DBHelper dbhlpr = new DBHelper(this);
Cursor csr = dbhlpr.getAllRows("");
if (csr.getCount() == 0) {
dbhlpr.addData("2017001",100);
dbhlpr.addData("2017035",50);
dbhlpr.addData("2017150",17);
dbhlpr.addData("2017364",33);
}
csr.close();
Cursor mydata = dbhlpr.getExpandedRows("2016364","2018005");
int limit = 0;
while (mydata.moveToNext()) {
if(limit++ > 400) {
break;
}
Log.d("MYDATA","Row " + Integer.toString(mydata.getPosition()) +
" for Date " + mydata.getString(mydata.getColumnIndex(DBHelper.COL1)) +
" has Value " + Integer.toString(mydata.getInt(mydata.getColumnIndex(DBHelper.COL2)))
);
}
mydata.close();
}
}
对日志的结果输出是(.......表示为简洁而未包括的类似行): -
10-04 12:25:18.495 6727-6727/mjt.so46550513 D/GetExpRows: Rows Extracted from base data = 4
10-04 12:25:18.505 6727-6727/mjt.so46550513 D/MYDATA: Row 0 for Date 2016364 has Value 0
10-04 12:25:18.505 6727-6727/mjt.so46550513 D/MYDATA: Row 1 for Date 2016365 has Value 0
10-04 12:25:18.505 6727-6727/mjt.so46550513 D/MYDATA: Row 2 for Date 2016366 has Value 0
10-04 12:25:18.505 6727-6727/mjt.so46550513 D/MYDATA: Row 3 for Date 2017001 has Value 100
10-04 12:25:18.505 6727-6727/mjt.so46550513 D/MYDATA: Row 4 for Date 2017002 has Value 0
.......
10-04 12:25:18.506 6727-6727/mjt.so46550513 D/MYDATA: Row 36 for Date 2017034 has Value 0
10-04 12:25:18.506 6727-6727/mjt.so46550513 D/MYDATA: Row 37 for Date 2017035 has Value 50
10-04 12:25:18.506 6727-6727/mjt.so46550513 D/MYDATA: Row 38 for Date 2017036 has Value 0
10-04 12:25:18.506 6727-6727/mjt.so46550513 D/MYDATA: Row 39 for Date 2017037 has Value 0
....
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 151 for Date 2017148 has Value 0
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 152 for Date 2017149 has Value 0
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 153 for Date 2017150 has Value 17
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 154 for Date 2017151 has Value 0
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 155 for Date 2017152 has Value 0
10-04 12:25:18.508 6727-6727/mjt.so46550513 D/MYDATA: Row 156 for Date 2017153 has Value 0
.......
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 365 for Date 2017362 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 366 for Date 2017363 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 367 for Date 2017364 has Value 33
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 368 for Date 2017364 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 369 for Date 2017365 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 370 for Date 2018001 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 371 for Date 2018002 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 372 for Date 2018003 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 373 for Date 2018004 has Value 0
10-04 12:25:18.510 6727-6727/mjt.so46550513 D/MYDATA: Row 374 for Date 2018005 has Value 0
注意!您可能会包含改进的错误/异常处理,尤其是对于字符串到日期的转换,因为这是一个原则上的示例