演示运行过程

Android timer 获取定时时间 android 定时提醒_数据

主要思路
  • 关于界面
    主界面展示待办事项todolist,点击事项的textview即事项的第一个字符就会展示具体的事项名称,点击右下角的删除icon即可删除该待办事项;添加界面负责添加事项,添加事项时事项名称不能为空,日期与时间的选择必须合理,事项合理后点击添加按钮即添加成功,后返回主界面,点击取消按钮即取消添加并返回主界面。
  • 关于业务逻辑
  1. 添加待办事项后,待办事项会写入SQLite数据库同时会启动一个服务,启动服务的intent携带了事项的信息
  2. 服务根据解析接收到的intent的信息使用AlarmManager设置一个定时,时间到了会发送一条广播
  3. 广播接收器接收到广播后会跳转到提醒的activity,展示事项的具体信息
具体剖析

添加todo
写一个Todo类用以在SQLite存取事项

// TODO: 2019/8/21 将数据写入
SQLiteSQLiteOpenHelper dbHelper = new DatabaseHelper(this, "TODO", null, 1);
SQLiteDatabase sqLiteDatabase = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// values.put("id", 1); //只有在第一次提交时需要执行或者用一个布尔变量判断是否是第一次上传数据
values.put("title", editText.getText().toString());values.put("date", dateText.getText().toString());
values.put("time", timeText.getText().toString());values.put("code", remindTypeCode);
sqLiteDatabase.insert("todo", null, values);Log.d(TAG, "addTodo: " + "写入数据库");
sqLiteDatabase.close();

展示todo
从SQLite读取todo数据并展示到listview

// TODO: 2019/8/21 从SQLite数据库中查询数据
DatabaseHelper databaseHelper = new DatabaseHelper(this, "TODO", null, 1);
SQLiteDatabase sqLiteDatabase = databaseHelper.getReadableDatabase();
// TODO: 2019/8/21 遍历查询所有todo对象
String sql = "select * from todo";Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
Todo todo;
while (cursor.moveToNext()) {
    todo = new Todo();
    todo.setTodo(cursor.getString(cursor.getColumnIndex("title")));
    todo.setDate(cursor.getString(cursor.getColumnIndex("date")));
    todo.setTime(cursor.getString(cursor.getColumnIndex("time")));
    todo.setCode(cursor.getInt(cursor.getColumnIndex("code")));
    Log.d(TAG, "load(): " + todo.getTodo());todoLists.add(todo);
}
sqLiteDatabase.close();

删除todo

DatabaseHelper databaseHelper = new DatabaseHelper(getContext(), "TODO", null, 1);
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
//执行多条件sql语句进行删除具体数据项
String sql = "delete from todo where title = '" + todo.getTodo() +"' and date = '" + todo.getDate() + "' and time = '" + todo.getTime() + "' and code = '" + todo.getCode() + "'";
sqLiteDatabase.execSQL(sql);sqLiteDatabase.close();

接受广播与提醒
在AlarmReceiver的onReceive方法中接受广播并跳转至AlertActivity

Intent toAlertAct = new Intent(context, AlertActivity.class);
toAlertAct.putExtra("todo", intent.getStringExtra("todo"));
toAlertAct.putExtra("remindTypeCode", intent.getIntExtra("remindTypeCode", 0));
Log.d(TAG, "onReceive: " + intent.getStringExtra("todo") + intent.getIntExtra("remindTypeCode", 0));
toAlertAct.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(toAlertAct);
踩过的坑
  • 数据持久化
    刚开始是序列化todo对象,并用本地文件对todo数据进行存储,但是读取的时候只能读到最后一次提交的一个todo数据;后来改用SQLite数据库对todo数据进行存储,数据库不愧是数据库,存储逻辑非常清晰!
  • 发送广播
    在定时发送广播是我是用PendingIntent.getBroadcast()方法,由于对该方法的第二个、第四个参数不熟悉,导致在多次测试时广播接收器接收到的数据都是第一次设置的数据。解决方法Android PendingIntent.getBroadcast intent数据不更新问题