每天自动将数据保存到SQLite数据库

时间:2017-10-03 17:48:58

标签: android sqlite alarmmanager repeatingalarm

我有一个简单的SQLite数据库,有两列。

Col 1 SimpleDateFormat(“yyyyDDD”)例如2017001(2017年1月1日)

Col 2 int of occurrence

因此,在极少数情况下,一整天都没有发生任何事情,当天没有任何东西插入我的数据库。我希望在这种情况下填充零,否则在绘制数据时会绕过那一天。

我做了一些研究,我正在考虑的解决方案是设置一个RTC警报,并且每24小时填充一个零发生行。在发生事件的可能事件中,零点在汇总并发送到图表时不会影响我的数据。如果没有发生,我会在那里得零。

更优雅的解决方案是退出吗?我没有使用android警报的经验。  RTC报警的任何缺点?也许SQLite有一些我可以利用的功能?我愿意接受任何解决方案。

修改

我没有提到即使在应用程序永远不会打开的几天内也必须添加零。这是一个重要的区别,我之前没有提到过。可以在应用程序启动时追溯添加行(可能在关闭几天之后)。感谢到目前为止的回复。

1 个答案:

答案 0 :(得分:1)

这是一种不依赖后台任务或向数据库添加额外(无用/浪费)数据的方法。

基本上提取数据,并将任何缺失的天数和实际天数添加到MatrixCursor(可以动态构建的光标)。

主要方法是getExpandedRows,它有两种支持方法: -

  • setDate(根据包含try catch的yyyyDDD格式的字符串设置java Date对象)
  • addMatrixRowMatrixCursor添加一行,并将下一个日期作为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天的行数: -

  • 20017001 (值 100 ),
  • 2017043 (值 50 ),
  • 2017150 (值 17 )和
  • 2017364 (值 33

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

注意!您可能会包含改进的错误/异常处理,尤其是对于字符串到日期的转换,因为这是一个原则上的示例