5

我正在实现一个具有 ConfigurationActivity 的小部件,并且必须与 Eclair(2.1) 保持兼容。

有关 AppWidgetProviders方法的文档onUpdate明确指出:

... .但是,如果你声明了一个配置Activity,则在用户添加App Widget时不会调用该方法,而是在后续更新时调用该方法。配置完成后执行第一次更新是配置活动的责任。(请参阅下面的创建应用小部件配置活动。)

不幸的是,这不是真的(至少对于我的带有 JellyBean 的 Nexus S)。事实上,在我的 ConfigurationActivity 触发器之前onUpdate被调用。我想知道,其他手机上是否有类似的行为,是否可以阻止我的 Provider 内部的呼叫? onCreateonUpdate

我的解决方法是在我的 WidgetConfigurationActivity 内的 SharedPreferences 中使用该特定 AppWidgetId 存储一个标志。如果它不存在,我可以假设没有首先调用 ConfigurationActivity。这可行,但在我看来真的很难看。如果我无法阻止onUpdate触发,是否有更好的解决方案?

4

3 回答 3

4

是的,当您在主屏幕上添加小部件时会调用 onUpdate()。看这里:

http://developer.android.com/reference/android/appwidget/AppWidgetProvider.html

http://developer.android.com/reference/android/appwidget/AppWidgetManager.html#ACTION_APPWIDGET_UPDATE

我不确定是否有办法在创建小部件时不触发它。但是您可以通过将 Widget Info XML 文件中的“updatePeriodMillis”字段设置为0或将其留空来阻止它再次触发。

另一种方法是将小部件 ID 存储在某处。现在,无论何时添加新的小部件,在您的 Receiver 类中,检查 ID 是否已经存在。如果它不存在(意味着一个新的小部件),那么不要执行任何代码。此外,每当删除小部件时,请从您的记录中删除小部件 ID。由于您可能删除了一个小部件,然后添加了一个与旧小部件具有相同 ID 的新小部件。

希望有帮助!

编辑:在 Receiver 类的 onReceive() 方法中,执行以下操作:

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

    int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    if( appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID )
    {
        super.onReceive(context, intent);
    }

}

当第一次从 Widgets 列表中选择一个小部件时,它的 appWidgetId 将等于 INVALID_APPWIDGET_ID 直到它被添加到主屏幕上。由于“super.onReceive()”在选择小部件时会调用 onUpdate() 方法,因此不会第一次调用 onUpdate()。

于 2012-08-05T19:02:00.900 回答
0

我也有这个错误。

即使我将 updatePeriodMillis 设置为 0。我的 onUpdate 在我开始 Widget 活动配置之前正在运行。我认为这是 android 小部件中的错误。

于 2014-04-09T07:00:00.623 回答
0

我通过在 onUpdate 中向 Intent 添加一个操作然后对 onReceive 进行 if 检查以查看是否单击了小部件,从而解决了这个问题:

我添加intentClick.setAction(WIDGET_CLICKED);了仅在单击小部件时触发的内容。

public class WidgetProvider extends AppWidgetProvider {

    private static final String TAG = WidgetProvider.class.getSimpleName();
    private static String WIDGET_CLICKED = "widget_clicked";

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    Log.e(TAG, "onUpdate()");

    remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
    watchWidget = new ComponentName(context, WidgetProvider.class);

    Intent intentClick = new Intent(context, WidgetProvider.class);
    intentClick.setAction(WIDGET_CLICKED);
    intentClick.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, "" + appWidgetIds[0]);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[0], intentClick, 0);
    remoteViews.setOnClickPendingIntent(R.id.img_btn, pendingIntent);
    remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.play);

    appWidgetManager.updateAppWidget(watchWidget, remoteViews);
}

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);

    Log.e(TAG, "onReceive()");
    Bundle extras = intent.getExtras();

    //If AND ONLY IF WIDGET_CLICKED
    if (extras != null && intent.getAction().equals(WIDGET_CLICKED)) {
        remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);

        //If isPlaying
        if (isPlaying) {
            //setBackground as PLAY
            remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.play);
            isPlaying = false;

            Intent i = new Intent(context, MediaPlayerService.class);
            i.putExtra("command", "stopSong");
            context.startService(i);

            //If NOT playing
        } else {
            //setBackground as STOP
            remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.stop);
            isPlaying = true;

            Intent i = new Intent(context, MediaPlayerService.class);
            i.putExtra("command", "playRandomSong");
            context.startService(i);
        }

        watchWidget = new ComponentName(context, WidgetProvider.class);

        (AppWidgetManager.getInstance(context)).updateAppWidget(watchWidget, remoteViews);
    }
}
于 2016-07-20T15:55:46.653 回答