Search code examples
androidbroadcastreceiverandroid-roomandroid-broadcastreceiverandroid-database

Android BroadcastReceiver Database Access with Room


I have setup an alarm that calls each hour a broadcast receiver. This receiver tries to load data from the sqlite database.

The problem is, that the list of reminders is null. The same codes works in an activity, but not in the receiver. Is there anything i have to change to access the database in the receiver. Is this a problem with the different context in the activity and in the receiver ?

The "setAlarm" method is the one i use, to create the alarm on an activity.

Regards

public class AppReceiver extends BroadcastReceiver {

    private static final String TAG = "AppReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        ReminderRepository mRepository; = new ReminderRepository(context);
        List<Reminder> list = mRepository.getAllReminder();
        for(Reminder r : list) {
            // TODO
        }
    }
}


public class ReminderRepository {

    private ReminderDao mReminderDao;
    private List<Reminder> mAllReminder;

    public DisposalCalenderRepository(Context context) {
        ReminderRoomDatabase db = ReminderRoomDatabase.getDatabase(context);
        mReminderDao = db.reminderDao();
        mAllReminder = mReminderDao.getAll();
    }

    public List<Reminder> getAllReminder(){
        return mAllReminder;
    }

}

@Dao
public interface ReminderDao {

    @Query("SELECT * from reminder")
    List<Reminder> getAll();

}

public void setAlarm(){
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.HOUR, 1);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);

    AlarmManager alarmMgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(mContext, AppReceiver.class);
    PendingIntent alarmIntent = PendingIntent.getBroadcast(mContext, 0, i, 0);

    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_HOUR, alarmIntent);
    }

Solution

  • I found two possible answers for my question.

    Solution 1: Start an async task. Create an AsyncTask class and do the stuff in the doBackground method. There are no more problem accessing the database.

    @Override
    public void onReceive(Context context, Intent intent) {
        new notifyAsyncTask().execute(context);
    }
    
    private static class notifyAsyncTask extends AsyncTask<Context, Void, Void> {
    
            private String CHANNEL_ID = "1a2b3c4d";
    
            private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            @Override
            protected Void doInBackground(Context... params) {
                Log.i(TAG, "Notify async started");
            ReminderRepository mRepository; = new ReminderRepository(context);
            List<Reminder> list = mRepository.getAllReminder();
            for(Reminder r : list) {
                    // TODO
            }
        }
    }
    

    Solution 2: Allow queries on the main thread. When the database is build, use allowMainThreadQueries() to allow queries on the main thread.

    !!!! ATTENTION !!!! NOT RECOMMENDED !!!! ATTENTION !!!!