Android AppWidget未在某些电话上显示

时间:2012-03-30 22:32:40

标签: android android-widget android-appwidget

我有一个非常简单的appwidget(两个文本视图和一个按钮)。我在触摸板,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();
    }

}

1 个答案:

答案 0 :(得分:1)

我能想到的最好的事情(假设Razr的启动程序没有错误或其他问题)是您的资源配置不正确。也许Razr具有不同的dpi密度,并且项目中没有用于密度的资源。

例如,尝试将构成窗口小部件的所有drawable移动到文件夹res \ drawable-nodpi,看看它是如何进行的。

编辑:我在您的代码中看到了一些奇怪的内容

在您的GoogleTalkWidget类onReceive方法中,只有在收到消息Utils.RECEIVED_MESSAGE_WIDGET时才会更新您的窗口小部件。我不知道这个消息是什么,但是app-widget,第一次在主屏幕上添加,它接收到android.appwidget.action.APPWIDGET_UPDATE,并且任何其他的intent过滤器都在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附加内容中提取了所有需要的参数。关于窗口小部件更新的另一件事是,即使您不希望定期更新窗口小部件,也应在窗口小部件xml文件中提供除0以外的android:updatePeriodMillis值(2100000是一个很好的值)。我看到某个地方,如果此值为0,则可能无法调用onReceive方法。

请记住,只要onReceive方法完成其工作,AppWidgetProvider作为广播接收器就会生存,之后它就会被破坏,因此它不适合像UI听众等“交互式”代码。我告诉你这是因为你在GoogleTalkWidget类的顶部有一个Button声明(Button sendMessage;)。

希望这会有所帮助......