Android AppWidget未在某些电话上显示

Eli*_*zer 5 android android-widget android-appwidget

我有一个非常简单的appwidget(两个文本视图和一个按钮).我在触摸板,Droid 1和Droid Razr上进行了测试.它适用于除Razr之外的所有事物.当我将小部件添加到主屏幕时,它不会显示; 它只是看不见的.如果我按住它会选择一个小部件的位置,如果我移动它,我会看到其他小部件移开,但它完全不可见.

我在onReceiveand和onEnabled方法中放了一些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();
    }

}
Run Code Online (Sandbox Code Playgroud)

ChD*_*ers 1

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

例如,尝试将构成小部件的所有可绘制对象移动到文件夹 res\drawable-nodpi 并查看效果如何。

编辑:我在你的代码中看到一些奇怪的东西

在您的 GoogleTalkWidget 类 onReceive 方法中,您的小部件仅在收到消息 Utils.RECEIVED_MESSAGE_WIDGET 时更新。我不知道这条消息的用途,但是应用程序小部件,第一次添加到主屏幕上,它接收 android.appwidget.action.APPWIDGET_UPDATE ,并且任何其他意图过滤器都在清单文件中注册,并且它们是当时由系统广播(当然还有粘性广播意图)。

如果我处于你的位置,我会更改 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);
}
Run Code Online (Sandbox Code Playgroud)

看看会发生什么。

如果你的小部件未能出现,那么可能是 Razr 的问题,但这与此不同,因为我认为一大堆其他小部件都可以正常工作。

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

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

希望这可以帮助...