У меня есть JobIntentService, который повторно устанавливает ожидающие уведомления о тревоге из базы данных SQLite. Он использует запрос и курсор для получения дат уведомлений из 4 разных столбцов в базе данных. Я конвертирую в базу данных Room и не знаю, как преобразовать курсор в метод Dao. Нужно ли мне использовать @Transaction, если я получаю уведомления из нескольких столбцов в базе данных? Буду признателен за любые идеи или мысли о том, как построить в комнате.
Service
public class Service extends JobIntentService {
static final int JOB_ID = 9;
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, RebootService.class, JOB_ID, work);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
AlarmManager alarmManager1;
Intent brIntent1;
PendingIntent pendingIntent1;
SQLiteDB sqLiteDB = SQLiteDB.getInstance(this);
Calendar cal1 = Calendar.getInstance();
Cursor cursor = sqLiteDB.resetNotifications();
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
int dueDatentimeColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_DUEDATENTIME);
int notifColumnIndex1 = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_NOTIFTIME);
int notif2ColumnIndex2 = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_NOTIFTIME2);
int randColumnIndex1 = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_RANDINT);
while (!cursor.isAfterLast()) {
do {
long notifTime1 = cursor.getLong(notifColumnIndex1);
int randInt1 = cursor.getInt(randColumnIndex1);
cal1.setTime(new Date(notifTime1));
// Set up a system AlarmManager to fire a future alarm that sends a Notification
// even if the app is in the background or closed.
alarmManager1 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (cal1.getTimeInMillis() > System.currentTimeMillis()) {
brIntent1 = new Intent(this, AlarmReceiver.class);
brIntent1.setAction("24Hour");
pendingIntent1 = PendingIntent.getBroadcast(this, randInt1, brIntent1,
PendingIntent.FLAG_ONE_SHOT);
if (alarmManager1 != null && notifTime1 != -1) {
alarmManager1.set(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), pendingIntent1);
}
...
}
SQLiteDB.java
...
public Cursor resetNotifications() {
SQLiteDatabase db = getReadableDatabase();
String[] columns = new String[]{
ItemContract.ItemEntry.COLUMN_NOTIFTIME,
ItemContract.ItemEntry.COLUMN_NOTIFTIME2,
ItemContract.ItemEntry.COLUMN_DUEDATENTIME,
ItemContract.ItemEntry.COLUMN_RANDINT};
return db.query(
TABLE_NAME,
columns, // The columns to return
null,
null,
null,
null,
null
);
}
This is the code I came up as a replacement:
public class RebootService extends JobIntentService {
// Unique job ID for this service
static final int JOB_ID = 10000;
// Convenience method for enqueueing work to this service.
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, RebootService.class, JOB_ID, work);
}
private QuickcardRepository reposit1;
@Override
protected void onHandleWork(@NonNull Intent intent) {
reposit1 = new QuickcardRepository(getApplication());
Bundle extras = intent.getExtras(); // Returns the Intent *that started this Service.*
if (extras != null) {
String classname = extras.getString("TAG");
if (classname != null && classname.equals("bootCompleted")) {
AlarmManager alarmManager1;
Intent brIntent1, brIntent2, brIntent3;
PendingIntent pendingIntent1, pendingIntent2, pendingIntent3;
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
Calendar cal3 = Calendar.getInstance();
List<Quickcard> resetNotificationsList = reposit1.getNotifications();
// Cycle through the Room database rows to get the Notifications data
for (Quickcard quickcard: resetNotificationsList) {
// Quickcards without a Due date get a Due date in the database of -1.
// Therefore, only cycle through and get data for those quickcards that have
// a Due data and therefore have Notifications (reminders) where the actual
// "Due date" is != -1.
if(quickcard.getDuedatentime() != -1) {
// Set up the 24-Hour calendar object.
long notifTime1 = quickcard.getNotiftime();
int randInt1 = quickcard.getRandint();
cal1.setTime(new Date(notifTime1));
// Set up a system AlarmManager to fire a future alarm that sends a Notification
// even if the app is in the background or closed. Have to add "context" here.
alarmManager1 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// If the stated alarm trigger time is in the past, the alarm will be triggered immediately.
// So only set Alarms to fire Notifications for Duedates in the future
// (meaning > than the current System time). Ignore those in the past.
if (cal1.getTimeInMillis() > System.currentTimeMillis()) {
// For the 24Hour Notifications.
// Set up a PendingIntent that will perform broadcast to the BroadcastReceiver.
brIntent1 = new Intent(this, AlarmReceiver.class);
brIntent1.setAction("24Hour");
// Need to use FLAG_ONE_SHOT on the PendingIntent, not FLAG_UPDATE_CURRENT.
// A random int is used to be able to set multiple alarms and then to be able to
// delete them later (if the user for ex., deletes the quickCards Duedate) using
// the same random int.
pendingIntent1 = PendingIntent.getBroadcast(this, randInt1, brIntent1,
PendingIntent.FLAG_ONE_SHOT);
// Alarms have 3 properties below after "set(...)":
// 1) Alarm type: RTC_WAKEUP type is chosen here to wake the device from sleep.
// 2) Trigger time: in this case, 24 hours before the Duedate/Duetime is reached.
// 3) Pending Intent: A future Intent that is sent when the trigger time is reached.
int SDK_INT1 = Build.VERSION.SDK_INT;
if (SDK_INT1 >= Build.VERSION_CODES.M) {
// Wakes up the device in Doze Mode for API Level 23 and higher.
// The "... != -1" test only sets up pendingIntents for quickCards that have
// a Notification. quickCards with no Duedate & Duetime are bypassed.
if (alarmManager1 != null && notifTime1 != -1) {
alarmManager1.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(),
pendingIntent1);
}
} else if (SDK_INT1 >= Build.VERSION_CODES.KITKAT) {
// Wakes up the device in Idle Mode for API Level 19 to 22.
// The "... != -1" test only sets up pendingIntents for quickCards that have
// a Notification. quickCards with no Duedate & Duetime are bypassed.
if (alarmManager1 != null && notifTime1 != -1) {
alarmManager1.setExact(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), pendingIntent1);
}
} else {
// Old APIs Level 18 and below.
// The "... != -1" test only sets up pendingIntents for quickCards that have
// a Notification. quickCards with no Duedate & Duetime are bypassed.
if (alarmManager1 != null && notifTime1 != -1) {
alarmManager1.set(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), pendingIntent1);
}
}
}