将数据从App发送到小部件

mun*_*ikh 2 android android-widget android-preferences

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

公共类CountdownWidget扩展了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));
}
Run Code Online (Sandbox Code Playgroud)

}

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

我确实尝试了CountdownWidget.nameOne,但仍然无法满足服务中的数据要求。

任何帮助将不胜感激。

小智 5

我通过在构建意在更新小部件的意图中添加其他功能来实现此目的。另外,当小部件具有信息时,可以再次将其传递到填充小部件视图的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);
    }
Run Code Online (Sandbox Code Playgroud)

然后,小部件具有一个字段来保存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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,所有这些最终直接通过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
    }
}
Run Code Online (Sandbox Code Playgroud)


Ali*_*imi 1

您必须创建一个更新小部件的服务,请查看本教程(第四部分),您可以尝试通过静态变量传输数据。