【问题标题】:How send data from application to AppWidgetProvider?如何将数据从应用程序发送到 AppWidgetProvider?
【发布时间】:2012-07-30 09:12:19
【问题描述】:

我被困在一个特定的场景中。用户从应用程序更新时间后,我需要立即更新我的小部件。我确实通过 Intent Extras 发送数据来尝试广播,但没有这样做。目前,我的数据在AppWidgetProvider,我需要将此数据发送到服务

public class CountdownWidget extends AppWidgetProvider {
    // SharedPreferences userDefaults;

    // update rate in milliseconds
    public static final int UPDATE_RATE = 1800000; // 30 minute

    public static String nameOne = "";

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            setAlarm(context, appWidgetId, -1);
        }
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        Bundle extras = intent.getExtras();
        nameOne = extras.getString("NAME_ONE");

        Log.e("Name: ", nameOne);

        super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                         int[] appWidgetIds) {

        for (int appWidgetId : appWidgetIds) {
            setAlarm(context, appWidgetId, UPDATE_RATE);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    public static void setAlarm(Context context, int appWidgetId, int updateRate) {

        // Log.e("", "Updating Widget Service");

        PendingIntent newPending = makeControlPendingIntent(context,
                CountdownService.UPDATE, appWidgetId);
        AlarmManager alarms = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        if (updateRate >= 0) {
            alarms.setRepeating(AlarmManager.ELAPSED_REALTIME,
                    SystemClock.elapsedRealtime(), updateRate, newPending);
        } else {
            // on a negative updateRate stop the refreshing
            alarms.cancel(newPending);
        }
    }

    public static PendingIntent makeControlPendingIntent(Context context,
                                                         String command, int appWidgetId) {
        Intent active = new Intent(context, CountdownService.class);
        active.setAction(command);
        active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        // this Uri data is to make the PendingIntent unique, so it wont be
        // updated by FLAG_UPDATE_CURRENT
        // so if there are multiple widget instances they wont override each
        // other
        Uri data = Uri.withAppendedPath(
                Uri.parse("countdownwidget://widget/id/#" + command
                        + appWidgetId), String.valueOf(appWidgetId));
        active.setData(data);
        return (PendingIntent.getService(context, 0, active,
                PendingIntent.FLAG_UPDATE_CURRENT));
    }
}

如您所见,nameOne 是一个静态变量。我可以使用 getExtras 在onReceive 方法上接收数据,但我无法将此数据传递给我的CountdownService 服务。

我确实尝试了CountdownWidget.nameOne,但仍然无法获取服务中的数据。

我们将不胜感激。

【问题讨论】:

    标签: android android-widget android-preferences


    【解决方案1】:

    我通过在我为更新小部件而构建的意图中添加额外内容来做到这一点。此外,当小部件具有信息时,它可以再次传递到填充小部件视图的 RemoteViewsService

    在我的 UpdateWidget 辅助方法中,我传入了 userId(由应用程序中的各种活动调用,可能需要通知小部件它需要自行更新)。

    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);
        }
    

    然后小部件有一个字段来保存 userId 并在 onReceive 中更新它。我将它与用于创建集合适配器的 Intent 一起传递给 RemoteViewsService。

    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);
        }
    }
    

    然后所有这些最终都直接通过 RemoteViewsService 传递到它的 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
        }
    }
    

    【讨论】:

      【解决方案2】:

      您必须创建一个更新小部件的服务,检查this tutorial(第4节),您可以尝试通过静态变量传输数据。

      【讨论】:

      • 请查看更新后的问题,我尝试使用静态变量但未能获取数据。
      猜你喜欢
      • 2013-10-01
      • 2020-10-16
      • 2019-02-13
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多