通过 AppWidgetManager 更新我自己的小部件时,电源控制小部件显示一小会儿,这是啥问题?

Posted

技术标签:

【中文标题】通过 AppWidgetManager 更新我自己的小部件时,电源控制小部件显示一小会儿,这是啥问题?【英文标题】:Power control widget shown for a short moment when updating my own widget via AppWidgetManager, what's the problem?通过 AppWidgetManager 更新我自己的小部件时,电源控制小部件显示一小会儿,这是什么问题? 【发布时间】:2011-06-05 00:58:36 【问题描述】:

通过 AppWidgetManager.updateAppWidget 手动更新小部件时遇到问题。 平台为 android 2.2。

代码如下: 我在清单中的现有活动中另外声明了小部件:

<receiver android:name=".Widget" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" />
</receiver>

小部件类在 Widget.java 中声明:

public class Widget extends AppWidgetProvider 
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    int use_static_ip;
    RemoteViews remoteViews;

    try 
        use_static_ip = Settings.System.getInt(context.getContentResolver(), Settings.System.WIFI_USE_STATIC_IP);
        if (use_static_ip == 0)  //DHCP
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_dhcp);
         else  //static IP
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_static);
        
        Intent call_activity = new Intent(context, StaticIPToggle.class);
        PendingIntent pending_call_activity = PendingIntent.getActivity(context, 0, call_activity, 0);
        remoteViews.setOnClickPendingIntent(R.id.widget_icon, pending_call_activity);
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
     catch (SettingNotFoundException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    


在现有活动中,我添加了一些行来手动更新小部件:

        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
        ComponentName componentName = new ComponentName(getApplicationContext(), Widget.class);
        int[] ids = appWidgetManager.getAppWidgetIds(componentName);
        Intent update_widget = new Intent();
        update_widget.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
        update_widget.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        getApplicationContext().sendBroadcast(update_widget);

但现在我有这个错误: 如果小部件是 onClicked,它会在显示所需小部件之前短时间(~0,5sec-1sec)显示能量设置小部件。

这里是这个问题的截图(从左到右的顺序):http://i.stack.imgur.com/rHkjw.jpg

首先是左图中的小部件,然后变为中间图片并在大约 0.5-1 秒后停留在那里或变为右图。

很遗憾,我在代码中看不到任何错误,是吗?

希望你能帮我解决这个问题;) 提前致谢, 问候,奥利

【问题讨论】:

哇,我也遇到了同样的问题;很高兴看到这不仅仅是我,这是一个难以描述的问题。我遇到了运行自定义 2.2 ROM 的 HTC EVO 4G 的错误,但在模拟器中没有。三星 Galaxy S 也不会出现这个问题。有人有解决方案吗?已经为此苦苦挣扎了一段时间。 我通过在自定义启动器中测试可滚动联系人小部件(源为here)看到了这一点,试图为许多联系人添加小部件。这可能与您的代码加载小部件内容的时间过长有关,也许是从小部件类开始的服务中加载? 【参考方案1】:

我使用与您相同的编程方式手动更新小部件(来自 Is it possible to throw an intent for APPWIDGET_UPDATE programmatically?)并发现这是问题的确切原因。

这仍然会在 4.2 和 2.3、官方和非官方 ROMS 上发生(当这种情况发生时,Touchwiz 会变得非常疯狂)。

我可以解决此问题的唯一方法是删除涉及广播的整个更新,并通过向小部件提供者发送常规 Broadcast 并调用来远程更新小部件

ComponentName thisWidget = new ComponentName(context,AvailabilityWidgetProvider.class);
AppWidgetManager.getInstance(context).updateAppWidget(thisWidget,views);

来自onReceive

(这对我有用,因为我的小部件是相同的)

这样,问题似乎不会发生,我可以远程更新小部件。 老问题,我知道,但值得回答,因为这是我能找到的关于这个奇怪问题的全部内容。

【讨论】:

【参考方案2】:

我遇到了完全相同的问题。我通过手动更新小部件而不是通过广播解决了这个问题,而是直接从 AsyncTask 调用 AppWidgetManager.updateAppWidget(ComponentName, RemoteViews)。

在你的 Widget 类中试试这个:

/**
 * Asynchronously builds views and updates the widget.
 */
private static class UpdateWidgetTask extends AsyncTask<Void, Void, RemoteViews> 
    private AppWidgetManager mAppWidgetManager;
    private Context mContext;

    private UpdateWidgetTask(AppWidgetManager appWidgetManager, Context context) 
        mAppWidgetManager = appWidgetManager;
        mContext = context;
    

    @Override
    protected RemoteViews doInBackground(Void... params) 
        DebugLog.d(TAG, "Asynchronously updating widget.");
        RemoteViews views = buildUpdate(mContext);
        return views;
    

    @Override
    protected void onPostExecute(RemoteViews views) 
        ComponentName thisWidget = new ComponentName(mContext, Widget.class);
        mAppWidgetManager.updateAppWidget(thisWidget, views);
    


/**
 * Asynchronously updates all widgets of this type. This is the fastest way to update the widget.
 *
 * @param context The context.
 */
public static void updateWidget(Context context) 
    new UpdateWidgetTask(AppWidgetManager.getInstance(context), context).execute();

然后通过从您的活动中调用 Widget.updateWidget(this) 进行更新。

【讨论】:

以上是关于通过 AppWidgetManager 更新我自己的小部件时,电源控制小部件显示一小会儿,这是啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

应用更新后小部件消失了

是否可以在工作线程中调用 appWidgetManager.updateAppWidget() ?

小部件不更新视图

强制 Android 小部件更新

主屏幕小部件文本视图未更新

获取当前活动的小部件