【问题标题】:Saving data to SQLite db automatically once per day每天自动将数据保存到 SQLite 数据库一次
【发布时间】:2017-10-03 17:48:57
【问题描述】:

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

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

Col 2 int 出现次数

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

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

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

编辑

我没有提到即使在应用程序从未打开的日子里也必须添加零。这是一个重要的区别,我之前没有提到。这些行可以在应用程序启动时追溯添加(可能在关闭几天后)。感谢您迄今为止的回复。

【问题讨论】:

  • 我发现GCMTaskService 很干净。但它(一般来说)用于网络调用。您可能想查看JobScheduler
  • 您没有提到要绘制什么样的数据,但一般来说,将“空”数据集添加到数据库并不是一个非常优雅且不可靠的解决方案。为了提供更详细的建议,了解您正在绘制哪些数据以及您正在创建哪种图表会很有帮助。
  • @Barns。这是用户超过一定速度的次数的简单折线图。如果用户从未超过速度,即使真正的答案为零,也不会输入任何数据。
  • 这样你就有了“事件”的时间和速度。因此,只需使用数据库中的数据生成一个 X-Y 图,速度为“Y”,日期为“X”。数据库中不需要“空”行。

标签: android sqlite alarmmanager repeatingalarm


【解决方案1】:

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

基本上,数据被提取出来,任何缺失的天数以及实际天数都被添加到MatrixCursor(可以动态构建的光标)。

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

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

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

【讨论】:

  • 非常感谢。这将需要我一点时间来吸收和尝试。 :) 我正在努力
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 2013-01-18
  • 2021-06-05
  • 2020-02-10
  • 1970-01-01
  • 2018-04-07
  • 2021-09-30
相关资源
最近更新 更多