Android AppWidget在某些手机上无法显示

5
我有一个非常简单的小部件(两个文本视图和一个按钮)。我已经在Touchpad、Droid 1和Droid Razr上进行了测试。除了Razr之外,它在所有设备上都可以正常工作。当我将小部件添加到主屏幕时,它不会显示出来;它是完全不可见的。如果我按住它应该在的位置,它会选择一个小部件,如果我移动它,我会看到其他小部件移开,但它完全不可见。
我在onReceiveonEnabled方法中放置了一些Toast,并且Toast显示了所有正确的信息(即意图操作和额外信息)。
有人有这方面的经验吗?
编辑:请注意,这仅用于调试,不遵循最佳实践。
public class GoogleTalkWidget extends AppWidgetProvider {

    Button sendMessage;

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received Intent Action = " +
                intent.getAction(), Toast.LENGTH_SHORT).show();

        if(intent.getAction().equals(Utils.RECEIVED_MESSAGE_WIDGET)){
            RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.main_widget);

            views.setTextViewText(R.id.widget_message, 
                (CharSequence)intent.getStringExtra("MESSAGE"));

            views.setTextViewText(R.id.widget_sender, 
                (CharSequence)intent.getStringExtra("SENDER"));

            Toast.makeText(context, "Received " + 
                intent.getStringExtra("MESSAGE") + " FROM " + 
                intent.getStringExtra("SENDER"), Toast.LENGTH_SHORT).show();

            ComponentName cn = new ComponentName(context, 
                GoogleTalkWidget.class);  

            AppWidgetManager.getInstance(context).updateAppWidget(cn, views);

        }
        super.onReceive(context, intent);
    }

    @Override 
    public void onEnabled(final Context context){
        super.onEnabled(context);

        Toast.makeText(context, "Enabled", Toast.LENGTH_SHORT).show();
    }

}

onReceive()?你是不是指的是你的AppWidgetProvideronUpdate()方法? - CommonsWare
你可以在一个小部件中覆盖 onReceive() 方法...我认为他们保留了它,是因为早期版本的Android存在一些 onDelete 问题。 - Eliezer
我理解。然而,onUpdate() 通常是您提供 RemoteViews 以声明应放入小部件中的内容的位置。onUpdate() 被调用了吗?您是否成功提供了 RemoteViews?LogCat 中是否有任何相关信息(例如,堆栈跟踪)? - CommonsWare
请检查上面添加的代码...我不想使用更新...我将其用作广播接收器,并在需要更新时让我的服务发送广播...更像是推送通知而不是轮询 :-)。无论如何,我看不到任何堆栈跟踪或错误...实际上,除了Razr上的小部件不显示之外,代码运行得非常完美。 - Eliezer
“我不想使用更新”--至少在您的初始更新中,您没有选择。 - CommonsWare
我不知道你为什么这么在意onReceive。安卓文档明确表示,只需实现onReceive,您就可以将appwidget用作广播接收器。此外,问题不在于appwidget在任何地方都能正常工作......问题在于某些手机上无法显示......是的,我已经尝试过删除onReceive以确保没有问题,但什么也没改变......我们能否请继续讨论其他事情? - Eliezer
1个回答

1
我能想到的最好的事情(假设 Razr 的启动器没有漏洞或其他问题)就是你的资源配置不正确。也许 Razr 有一个不同的 dpi 密度,而在你的项目中没有这个密度的资源。
例如,尝试将构成您的小部件的所有可绘制对象移动到文件夹 res\drawable-nodpi 中,并查看它的运行情况。
编辑:我在你的代码中看到了一些奇怪的地方
在 GoogleTalkWidget 类的 onReceive 方法中,只有在接收到 Utils.RECEIVED_MESSAGE_WIDGET 消息时才会更新你的小部件。我不知道这个消息是用来干什么的,但是当应用程序小部件第一次添加到主屏幕上时,它会接收到 android.appwidget.action.APPWIDGET_UPDATE 和任何其他意图过滤器都在 manifest 文件中进行注册并在那时由系统广播(当然还有粘性广播意图)。
如果我处于你的位置,我会将 onReceive 方法改为如下所示:
@Override
public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "Received Intent Action = " +
            intent.getAction(), Toast.LENGTH_SHORT).show();
    super.onReceive(context, intent);

    String msg = "No messages yet";

    RemoteViews views = new RemoteViews(context.getPackageName(),
            R.layout.main_widget);

    if(intent.getAction().equals(Utils.RECEIVED_MESSAGE_WIDGET)){
        msg = intent.getStringExtra("MESSAGE");

        views.setTextViewText(R.id.widget_sender, 
            (CharSequence)intent.getStringExtra("SENDER"));

        Toast.makeText(context, "Received " + 
            intent.getStringExtra("MESSAGE") + " FROM " + 
            intent.getStringExtra("SENDER"), Toast.LENGTH_SHORT).show();

        ComponentName cn = new ComponentName(context, 
            GoogleTalkWidget.class);  
    }

    views.setTextViewText(R.id.widget_message, msg);

    AppWidgetManager.getInstance(context).updateAppWidget(cn, views);
}

看看会发生什么。

如果您的小部件未出现,则可能是Razr的问题,但这不太可能,因为我认为许多其他小部件都正常工作。

此外,尽管您的代码仅用于调试,但您的方法有点问题。更新小部件视图的最佳位置是在AppWidgetProvider的onUpdate方法中,而不是在onReceive中。Android提供了onUpdate方法来实现此目的,并提供onReceive以通知您已到达注册广播。基本区别在于,在onUpdate方法中,Android已从接收到的Intent extras中提取了所有所需的参数。关于小部件更新的另一件事是,即使您不想定期更新小部件,也应在小部件xml文件中提供android:updatePeriodMillis值(2100000是一个很好的值)。我在某个地方看到,如果此值为0,则可能不会调用onReceive方法。

还要记住,作为广播接收器的AppWidgetProvider仅在onReceive方法完成其工作时存在,之后就会被销毁,因此它不是像UI侦听器等“交互式”代码的好地方。我告诉您这个原因是因为您在GoogleTalkWidget类的顶部声明了一个Button sendMessage;。

希望这可以帮助您...


现在我只是试图让它工作,所以它非常简单......没有可绘制对象或其他任何东西......只有一个文本视图和按钮。 - Eliezer
关于onReceive的内容,我自从忘记它并且无法解决这个问题后就没有更新过这篇文章。自从我发布了这个问题以来,我尝试将代码的一部分拿出来,直到只剩下一个调用superonUpdate函数,但仍然无法解决问题。至于onUpdateonReceive之间的区别,由于这个Razr的问题,这个项目已经被搁置了,所以我没有真正考虑过,但是感谢您的建议! - Eliezer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接