Android 防止触发WidgetProvider的onUpdate
我正在实现一个具有ConfigurationActivity的小部件,它必须与Eclair(2.1)保持兼容 about AppWidgetProvidersAndroid 防止触发WidgetProvider的onUpdate,android,android-widget,appwidgetprovider,Android,Android Widget,Appwidgetprovider,我正在实现一个具有ConfigurationActivity的小部件,它必须与Eclair(2.1)保持兼容 about AppWidgetProvidersonUpdate方法明确指出: 。但是,如果您声明了配置活动,则当用户添加应用程序小部件时,不会调用此方法,而是调用后续更新。配置活动负责在配置完成时执行第一次更新。(请参阅下面的创建应用程序小部件配置活动。) 不幸的是,这不是真的(至少对于我的NexusS和JellyBean)。事实上,onUpdate在我的ConfigurationAc
onUpdate
方法明确指出:
。但是,如果您声明了配置活动,则当用户添加应用程序小部件时,不会调用此方法,而是调用后续更新。配置活动负责在配置完成时执行第一次更新。(请参阅下面的创建应用程序小部件配置活动。)
不幸的是,这不是真的(至少对于我的NexusS和JellyBean)。事实上,onUpdate
在我的ConfigurationActivity触发器的onCreate
之前被调用。我想知道,其他手机上是否有类似的行为,以及是否有可能阻止提供商内部的onUpdate
呼叫
我的解决方法是在WidgetConfigurationActivity中的SharedReferences中使用特定的AppWidgetId存储一个标志。如果没有,我可以假设没有首先调用ConfigurationActivity。这是可行的,但在我看来真的很难看。如果我无法阻止触发onUpdate,是否有更好的解决方案?是,当您在主屏幕上添加小部件时,会调用onUpdate()。
请看这里:
我不确定是否有办法在创建小部件时不触发它。但是您可以通过将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);
}
}
当第一次从窗口小部件列表中选择窗口小部件时,其appWidgetId将等于无效的APPWIDGET_ID,直到将其添加到主屏幕上。由于“super.onReceive()”在选择小部件时调用onUpdate()方法,因此不会第一次调用onUpdate()
甚至我也将updatePeriodMillis设置为0。在启动小部件活动配置之前,我的onUpdate正在运行。我认为这是android widget中的一个bug。我解决了这个问题,在onUpdate中的意图中添加了一个操作,然后在接收时进行if检查,查看widget是否被单击: 我添加了
intentClick.setAction(WIDGET\u单击)代码>仅在单击小部件时触发
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);
}
}
我真的很想知道:更新文档:这可能是为了响应已实例化此AppWidget提供程序的新实例、请求的更新间隔已过或系统启动而发送的。
VS如果您已声明配置活动,当用户添加应用程序小部件时,不会调用此方法。
我已经将updateInterval设置为“0”,并且我已经按照您的建议执行了操作(将Id存储在SharedReferences中)。找到了一种不第一次调用onUpdate()的方法。检查我编辑的答案。工作正常,我只是在我的应用程序中实现了同样的功能。我没有获得AppWidgetManager。在我的提供程序第一次触发时,无效的\u APPWIDGET\u ID
。事实上,我的AppWidgetConfigActivity
将接收到的是正确的Id。(JellyBean Galaxy Nexus)无效的_APPWIDGET_ID始终给出一个值,该值永远不会用作小部件的有效ID。我检查时它的值是0。这是创建小部件时getIntExtra返回的。之后,无论何时为同一小部件调用onReceive(),它都会返回该小部件的有效ID。可能是因为我在用Android 2.3.3(API 10),而你在用Jelly Bean。我也在用Android 2.3.3,Rafael说的似乎是对的——我想我从来没有得到过widget ID 0。此外,将updatePeriodMillis留空并不能阻止每次屏幕解锁时调用onUpdate。这只是另一篇不正确的文档——甚至谷歌有时也会出错。我看到每次在创建配置活动之前都会调用onUpdate,无论Android版本、设备或模拟器如何