Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
    }
like image 948
Ephenodrom Avatar asked Aug 30 '18 13:08

Ephenodrom


People also ask

How pass data from BroadcastReceiver to activity in Android?

startActivity(i); Then, in your activity, you will need to getExtra as so: Intent intent = getIntent(); String message = intent. getStringExtra("message");

Is broadcast receiver deprecated?

With Android Nougat, the support for registering three different implicit BroadcastReceivers in your AndroidManifest was removed. With apps targeting Android O, all implicit BroadcastReceivers registered in the manifest (except these) will stop working.

What is the role of the onReceive () method in the BroadcastReceiver?

Creating a BroadcastReceiver The onReceiver() method is first called on the registered Broadcast Receivers when any event occurs. The intent object is passed with all the additional data. A Context object is also available and is used to start an activity or service using context.

Does broadcast receiver work in background?

The alternative is to register the receiver in the AndroidManifest. This ensures that the BroadcastReceiver runs all the time, even when the app is backgrounded. I chose this option because I want my application to receive Bluetooth events even when the app isn't in use (i.e. backgrounded). In my AndroidManifest.


1 Answers

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 !!!!

like image 79
Ephenodrom Avatar answered Oct 20 '22 10:10

Ephenodrom