Android - How to access Room database from widget

If you use a RemoteViewsService to populate your widget UI, then you can avoid using an AsyncTask by including a DAO query in its onDataSetChanged() method, rather than in the AppWidgetProvider's onUpdate() method. As stated in the onDataSetChanged() documentation,

...expensive tasks can be safely performed synchronously within this method. In the interim, the old data will be displayed within the widget.

The other advantage here is that you can include a call to AppWidgetManager.notifyAppWidgetViewDataChanged() in your app's ViewModel observer's onChanged() method; this will trigger the onDataSetChanged() and the widget will update each time the Room database is changed, rather than just at the fixed interval for onUpdate().


So answering my self here..

the only way that worked is to use the context to get the DB instance from the abstract class and run the DAO queries directly in background thread without the ViewModelProviders class

    new AsyncTask<Context, Void, List<Data>>(){
        @Override
        protected List<Quote> doInBackground(Context... context) {

            List<Data> List=null;
                AppDatabase db = AppDatabase.getDatabase(context[0]);
                List = db.DataModel().getData();


            return List;
        }

        @Override
        protected void onPostExecute(List<Quote> List) {
            super.onPostExecute(List);

            if(List != null){

                final Random random=new Random();
                for (int appWidgetId : appWidgetIds) {
                    updateAppWidget(context, appWidgetManager, appWidgetId, quoteList.get(random.nextInt(List.size())));
                }

            }

        }

    }.execute(context);

}

I know it has been a while, but I just came across this issue and wanted to add something useful following the inspiration of fellow member Aaron-dunigan-atlee.

Basically showing where the database and Dao object go... and more importantly, the onDataSetChanged() method that has the call to the Room query. The example is for a Notetaking the app to illustrate, and as it was commented above, no need of AsyncTasks anywhere.

public class MyWidgetRemoteViewsService extends RemoteViewsService
{
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent)
    {
        return new MyRemoteViewsFactory(this.getApplicationContext(), intent);
    }

    class MyRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory
    {
        private NotesDao notesDao;
        private List<Note> allNotes;

        MyRemoteViewsFactory(Context context, Intent intent)
        {
            MyDb db;
            db = MyDatabase.getDatabase(context);
            notesDao = db.notesDao();
        }

        @Override
        public void onCreate() { }

        @Override
        public void onDataSetChanged()
        {
            allNotes = notesDao.getAllNotes();
        }

        @Override
            public int getCount()
            { ...

sasa