小部件不显示数据列表

时间:2018-07-23 17:21:55

标签: android widget

我有一个小部件,它应该显示信息列表。但是,在研究了许多教程和文档之后,我无法弄清为什么它没有显示列表。它将始终显示空白视图。甚至不会调用WidgetService.java类。

我的代码可以在github here上找到:

RecipeWidgetProvider.java

public class RecipeWidgetProvider extends AppWidgetProvider {

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    for (int appWidgetId : appWidgetIds) {
        updateAppWidget(context, appWidgetManager, appWidgetId);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {
    SharedPreferences preferences = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
    long recipeId = preferences.getLong(WidgetConfigurationActivity.PREF_PREFIX_KEY+appWidgetId, 0);
    Intent serviceIntent = new Intent(context, WidgetService.class);
    serviceIntent.putExtra(WidgetService.EXTRA_RECIPE_ID, recipeId);
    serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
    Intent intent = new Intent(context, RecipeListActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);


    RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_recipes);
    widget.setRemoteAdapter(appWidgetId, R.id.widget_configuration_list_view, serviceIntent);
    widget.setEmptyView(R.id.widget_recipe_list_view, R.id.empty_view);
    widget.setOnClickPendingIntent(R.id.widget_container, pendingIntent);

    //appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_recipe_list_view);
    appWidgetManager.updateAppWidget(appWidgetId, widget);
}
}

WidgetService.java

public class WidgetService extends RemoteViewsService {
    public static String EXTRA_RECIPE_ID = "recipeId";

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        int recipeId = intent.getIntExtra(EXTRA_RECIPE_ID, -1);
        return new WidgetViewFactory(getApplicationContext(), recipeId);
    }
}

WidgetViewFactory.java

public class WidgetViewFactory implements RemoteViewsService.RemoteViewsFactory {
    private Context context;
    private long recipeId;
    private ArrayList<IngredientEntity> ingredients = new ArrayList<>();

    public WidgetViewFactory(Context context, long recipeId) {
        this.context = context;
        this.recipeId = recipeId;
        RecipeLocalSource source = RecipeLocalSource.getInstance(context);
        RecipeEntity recipe = source.getRecipe(recipeId);
        if (recipe != null) {
            ingredients.addAll(recipe.getIngredients());
        }
    }

    @Override
    public void onCreate() {
        Log.e("","");
    }

    @Override
    public void onDataSetChanged() {
        RecipeLocalSource source = RecipeLocalSource.getInstance(context);
        RecipeEntity recipe = source.getRecipe(recipeId);
        if (recipe != null) {
            ingredients.addAll(recipe.getIngredients());
        }
    }

    @Override
    public void onDestroy() {
        Log.e("","");
    }

    @Override
    public int getCount() {
        Log.d("","");
        return ingredients.size();
    }

    @Override
    public RemoteViews getViewAt(int position) {
        final IngredientEntity ingredient = ingredients.get(position);
        RemoteViews row = new RemoteViews(context.getPackageName(),
                R.layout.item_widget_ingredient);

        row.setTextViewText(R.id.item_widget_ingredient_name, ingredient.getIngredient());
        row.setTextViewText(R.id.item_widget_ingredient_quantity_measure, String.format("%s %s", ingredient.getQuantity(), ingredient.getMeasure()));
        return row;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
}

1 个答案:

答案 0 :(得分:1)

此方法存在问题:

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {
    SharedPreferences preferences = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
    long recipeId = preferences.getLong(WidgetConfigurationActivity.PREF_PREFIX_KEY+appWidgetId, 0);
    Intent serviceIntent = new Intent(context, WidgetService.class);
    serviceIntent.putExtra(WidgetService.EXTRA_RECIPE_ID, recipeId);
    serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
    Intent intent = new Intent(context, RecipeListActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);


    RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_recipes);
    widget.setRemoteAdapter(appWidgetId, R.id.widget_configuration_list_view, serviceIntent);
    widget.setEmptyView(R.id.widget_recipe_list_view, R.id.empty_view);
    widget.setOnClickPendingIntent(R.id.widget_container, pendingIntent);

    //appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_recipe_list_view);
    appWidgetManager.updateAppWidget(appWidgetId, widget);
}

在线:

  

widget.setRemoteAdapter(appWidgetId,   R.id.widget_configuration_list_view,serviceIntent);

这是错误的列表视图,这是使用R.id全局名称空间容易犯的错误。应该是:

  

widget.setRemoteAdapter(R.id.widget_recipe_list_view,serviceIntent);

这是小部件的远程视图中的ListView。

还请注意,我将“ setRemoteAdapter”更改为使用不推荐使用的其他版本。

进行此更改后,将在WidgetService内部调用onGetViewFactory。但是,这会导致数据库崩溃:

java.lang.RuntimeException: Unable to bind to service intellidev.co.bakingapp.widget.WidgetService@15361cf with Intent { dat=intent: cmp=intellidev.co.bakingapp/.widget.WidgetService (has extras) }: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    at android.app.ActivityThread.handleBindService(ActivityThread.java:3538)
    at android.app.ActivityThread.-wrap2(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1758)
    at android.os.Handler.dispatchMessage(Handler.java:108)
    at android.os.Looper.loop(Looper.java:206)
    at android.app.ActivityThread.main(ActivityThread.java:6749)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:845)
 Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:204)
    at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:232)
    at intellidev.co.bakingapp.data.daos.RecipeDao_Impl.getRecipe(RecipeDao_Impl.java:129)
    at intellidev.co.bakingapp.data.sources.RecipeLocalSource.getRecipe(RecipeLocalSource.java:47)
    at intellidev.co.bakingapp.widget.WidgetViewFactory.<init>(WidgetViewFactory.java:24)
    at intellidev.co.bakingapp.widget.WidgetService.onGetViewFactory(WidgetService.java:12)
    at android.widget.RemoteViewsService.onBind(RemoteViewsService.java:241)
    at android.app.ActivityThread.handleBindService(ActivityThread.java:3524)
    at android.app.ActivityThread.-wrap2(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1758) 
    at android.os.Handler.dispatchMessage(Handler.java:108) 
    at android.os.Looper.loop(Looper.java:206) 
    at android.app.ActivityThread.main(ActivityThread.java:6749) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:845) 

但是我会把那个留给你,因为我认为在调用RemoteViewsFactory之后,您已经准备好取得更大的进步。干杯!