首页 > 解决方案 > 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...
}

}

重要细节:

问题的根源是什么,我该如何解决?

标签: javaandroidsqlite

解决方案


推荐阅读