这是一种无需依赖后台任务或向数据库添加额外(无用/浪费)数据的方法。
基本上,数据被提取出来,任何缺失的天数以及实际天数都被添加到MatrixCursor(可以动态构建的光标)。
主要方法是getExpandedRows,它有两个支持方法:-
-
setDate(根据包含try catch的yyyyDDD格式的字符串设置java Date对象)
- 和
addMatrixRow 向MatrixCursor 添加一行并将下一个日期作为java 日期返回。
getExpandedRows 以 yyyyDDDD 格式的字符串形式接受两个参数 start 和 end 日期,这些参数用于 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 行添加了几天:-
-
20017001(值100),
-
2017043(值50),
-
2017150(值 17)和
-
2017364(值33)
选择了2016364-2018004这段时间进行测试。
这是用于测试的调用活动,(请注意,您可以将矩阵光标用作普通光标)。主线是 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
注意!您可能会包括改进的错误/异常处理,尤其是对于字符串到日期的转换,因为这是一个原则示例