java - IllegalStateException 当我尝试从 BroadcastReceiver 查询我的数据库时
问题描述
我正在开发一个应用程序来安排付款日期,它的功能之一是在每个必须付款的日期向您发送通知。为此,我每天检查是否是付款日期,如果是,我激活通知以便稍后显示。
该应用程序已投入生产,Play 控制台告诉我以下错误已发生 90 次:
类型:java.lang.RuntimeException
java.lang.RuntimeException:
at android.app.ActivityThread.handleReceiver (ActivityThread.java:3990)
at android.app.ActivityThread.access$1500 (ActivityThread.java:233)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2006)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loop (Looper.java:241)
at android.app.ActivityThread.main (ActivityThread.java:7582)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:941)
Caused by: java.lang.IllegalStateException:
at androidx.room.RoomOpenHelper.onUpgrade (RoomOpenHelper.java:117)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade (FrameworkSQLiteOpenHelper.java:177)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:417)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase (FrameworkSQLiteOpenHelper.java:145)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase (FrameworkSQLiteOpenHelper.java:106)
at androidx.room.RoomDatabase.inTransaction (RoomDatabase.java:622)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction (RoomDatabase.java:399)
at com.mypackagename.crud.PaymentDao_Impl.getPaymentsOfDate (PaymentDao_Impl.java:447)
at com.mypackagename.AlarmReceiver.aviactivateTodayReminders (AlarmReceiver.java:95)
at com.mypackagename.AlarmReceiver.onReceive (AlarmReceiver.java:35)
at android.app.ActivityThread.handleReceiver (ActivityThread.java:3981)
我不知道问题可能是什么,但我读到其他人在从 BroadcastReceiver 访问数据库时遇到问题,我做错了什么吗?这是我的代码:
报警接收器:
public class AlarmReceiver extends BroadcastReceiver {
static AppDataBase appDataBase;
@Override
public void onReceive(Context context, Intent intent) {
if (appDataBase == null){
appDataBase = Room.databaseBuilder(context, AppDataBase.class, Constants.DB_NAME)
.allowMainThreadQueries()
.build();
}
String action = intent.getAction();
if (action != null && context != null) {
if("ACTIVATOR".equals(action)) {
aviactivateTodayReminders(context, appDataBase);
} else if (action.equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {//Reactivate after restart
NotificationScheduler.enableDailyActivator(context);
aviactivateTodayReminders(context, appDataBase);
return;
}
}
if (action == null){//Show notification
//Code omitted for better understanding...
}
}
static void aviactivateTodayReminders(Context context, AppDataBase appDataBase){//Enable today's notifications
List<Long> idPaymentList = appDataBase.paymentDao().getPaymentsOfDate(todayDate());
for (int i = 0; i < idPaymentList.size(); i++){
long idPayment = idPaymentList.get(i);
NotificationScheduler.setNotification(context, (int) idPayment);
}
}
static String todayDate(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
return dateFormat.format(new Date());
}
}
getPaymentsOfDate:
@Query("SELECT _id FROM Payment WHERE date =:xDate ")
List<Long> getPaymentsOfDate(String xDate);
通知调度程序(我认为不需要包含它,但在这里)
public class NotificationScheduler {
public static final String NOTIFICATION_CHANNEL_ID = "10000";
static void enableDailyActivator(Context context){//Enable activator service
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("ACTIVATOR");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cHourActivation = Calendar.getInstance();
cHourActivation.set(Calendar.HOUR_OF_DAY, Constants.HOUR_ACTIVATION);
cHourActivation.set(Calendar.MINUTE, 0);
cHourActivation.set(Calendar.SECOND, 0);
cHourActivation.set(Calendar.MILLISECOND, 0);
if (cHourActivation.getTimeInMillis() <= System.currentTimeMillis())
cHourActivation.add(Calendar.DATE, 1);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cHourActivation.getTimeInMillis(), (24 * 60 * 60 * 1000), pendingIntent);
}
public static void setNotification(Context context, int idPayment){
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("idPayment", idPayment);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, idPayment, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
am.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
am.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
public static void showNotification(Context context, String title, String content, int idTanda){
//Code omitted for better understanding...
}
}
重要细节:
EnableDailyActivator 在首次启动应用程序并重新启动设备时运行。
“ACTIVATOR” 它应该在每天大约 00:00 执行,这将调用 aviactivateTodayReminders 方法,该方法旨在(从数据库)获取当天付款的 id 以安排通知,不幸的是我在播放控制台
List<Long> idPaymentList = appDataBase.paymentDao().getPaymentsOfDate(todayDate());
问题的根源是什么,我该如何解决?
解决方案
推荐阅读
- wordpress - 将 Bootstrap 4 JS 导入项目
- javascript - 智能在 VS Code 中不适用于 Gsap
- python - 从 R 的 system() 调用 python:找不到熊猫
- python - 使用 ElementTree 从 XML 中获取值
- javascript - 在多构建 Vue js 应用程序中定义多个配置的最佳方法是什么?
- html - 使用 HTML 和 css 使整个形状可点击
- python - 尝试使用 tkinter 网格创建数独游戏,GUI 网格出现问题
- javascript - 如何计算动画 gif 循环的次数并在 javascript 中显示该计数?
- android - 获取 java.io.IOException:当我从一个片段导航到另一个片段时取消
- kotlin - 定义默认注释