How send data from application to AppWidgetProvider?

前端 未结 2 1544
一生所求
一生所求 2021-01-15 11:16

I am stuck in a particular scenario. I need to get my widget updated as soon as the user update the time from the app. I did try Broadcast by sending the data through Intent

2条回答
  •  说谎
    说谎 (楼主)
    2021-01-15 11:34

    I do this by adding extras in the intent that I build to update the widget. Also, when the widget has the information it can be passed again into the RemoteViewsService that populates the views for the widget

    In my UpdateWidget helper method I pass in the userId (called by various activities in the app that may need to notify the widget that it needs to update itself).

    public static void updateWorkoutsWidget(Context context) {
        Intent intent = new Intent(context, WorkoutsWidget.class);
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        intent.putExtra(WorkoutsWidgetService.USER_ID_EXTRA, userId);
        int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, WorkoutsWidget.class));
        if(ids != null && ids.length > 0) {
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
            context.sendBroadcast(intent);
        }
    

    Then the widget has a field to hold the userId and updates it in onReceive. I pass it into the RemoteViewsService with the Intent that is used to create the collection adapter.

    public class WorkoutsWidget extends AppWidgetProvider {
        private long userId;
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getLongExtra(WorkoutsWidgetService.USER_ID_EXTRA, -1) != -1) {
                 userId = intent.getLongExtra(WorkoutsWidgetService.USER_ID_EXTRA, -1);
            }
            super.onReceive(context, intent);
        }
    
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            // update each of the app widgets with the remote adapter
            for (Integer widgetId : appWidgetIds) {
                Intent intent = new Intent(context, WorkoutsWidgetService.class);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
                intent.putExtra(WorkoutsWidgetService.USER_ID_EXTRA, userId);
                intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
    
                RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_workouts);
                rv.setRemoteAdapter(R.id.workouts_list, intent);
    
                rv.setEmptyView(R.id.workouts_list, R.id.empty_view);
    
                //(Pending intent stuff ommitted for brrevity)
    
                appWidgetManager.updateAppWidget(widgetId, rv);
            }
            super.onUpdate(context, appWidgetManager, appWidgetIds);
        }
    }
    

    And then all that ends up passing straight on through the RemoteViewsService into its RemoteViewsFactory:

    public class WorkoutsWidgetService extends RemoteViewsService {
        public static final String TRACK_WORKOUT_ACTION = "com.bodybuilding.mobile.service.TRACK_WORKOUT_ACTION";
        public static final String USER_ID_EXTRA = "userId";
    
        @Override
        public RemoteViewsFactory onGetViewFactory(Intent intent) {
            return new WorkoutWidgetViewsFactory(this.getApplicationContext(), intent);
        }
    
        class WorkoutWidgetViewsFactory implements RemoteViewsFactory, ServiceConnection {
    
            WorkoutWidgetViewsFactory(Context context, Intent intent) {
                this.context = context;
                appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
                userId = intent.getLongExtra(USER_ID_EXTRA, -1);
            }
    
            //Lots of other stuff in here
        }
    }
    

提交回复
热议问题