簡體   English   中英

通過意圖將數據從應用程序傳遞到小部件時,空指針

[英]Null Pointer When Passing Data from App to Widget via Intent

我有使用翻新功能檢索的食譜列表。 然后,我獲得了配方名稱,並且我想更新與我的應用程序關聯的Widget,以顯示選定的recipeName recipeName反映在下面的我的RecyclerView適配器中。

當用戶單擊RecylcerView的項目時,我想更新該應用程序所具有的關聯小部件。

下面是RecyclerView的適配器,其中有.setOnClickListener()方法,並通過Intent傳遞我的所有數據。

        @Override
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder holder, final int position) {
        String id = mRecipeDataSet.get(position).getId();
        //The recipe name I want to pass to my widget
        final String recipeName = mRecipeDataSet.get(position).getName();
        holder.mTextView.setText(id);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(con, BakingWidgetProvider.class);
                intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                int[] ids = AppWidgetManager.getInstance(con).getAppWidgetIds(new ComponentName(con, BakingWidgetProvider.class));
                if(ids != null && ids.length > 0) {
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
                    intent.putExtra(RECIPE_NAME, recipeName);
                    con.sendBroadcast(intent);
                }
                Intent i = new Intent(con, IndividualRecipeActivity.class);
                Bundle bundle = new Bundle();
                bundle.putParcelableArrayList("Recipe_List", (ArrayList<? extends Parcelable>) mRecipeDataSet);
                i.putExtras(bundle);
                i.putExtra("Position",position);
                con.startActivity(i);
            }
        });

}

下面是管理我的窗口小部件的BakingWidgetProvider類。 每當用戶從RecyclerView單擊新項目時,我想更新小部件界面:

公共類BakingWidgetProvider擴展了AppWidgetProvider {

private static final String RECIPE_NAME = "RECIPE_NAME";
public static final String ACTION_TEXT_CHANGED = "kitchenpal.troychuinard.com.kitchenpal.TEXT_CHANGED";
private static String mRecipeName;

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {

    CharSequence widgetText = context.getString(R.string.appwidget_text);
    // Construct the RemoteViews object
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.baking_widget_provider);
    Log.v("WIDGET", mRecipeName);
    views.setTextViewText(R.id.selected_recipe, mRecipeName);
    Intent intent = new Intent(context, MainActivity.class);
    PendingIntent pIntent = PendingIntent.getActivity(context, 0, 
     intent, 0);
    //TODO: Why isn't my widget launching my MainActivity onClick?
    //TODO: I am trying to add a ListView of ingredients to my Widget 
     but have no idea where to begin
    views.setOnClickPendingIntent(R.id.chef, pIntent);

}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // There may be multiple widgets active, so update all of them
    for (int appWidgetId : appWidgetIds) {
        updateAppWidget(context, appWidgetManager, appWidgetId);
    }
}

@Override
public void onEnabled(Context context) {
    // Enter relevant functionality for when the first widget is created
}

@Override
public void onDisabled(Context context) {
    // Enter relevant functionality for when the last widget is disabled
}

//TODO: I cannot pass data from MyAdapter to the BakingWidgerProvider. I am simply trying to display the most recently
//TODO: selected recipe on the widget. I have scoured StackOverflow to no avail
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION_TEXT_CHANGED)) {
        // handle intent here
        mRecipeName = intent.getStringExtra(RECIPE_NAME);
    }
    super.onReceive(context, intent);

     //        if(intent.getAction().equals("UPDATE_ACTION")) {
     //            mRecipeName = intent.getStringExtra(RECIPE_NAME);
     //            int[] appWidgetIds = 


   intent.getExtras().getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
     //            if (appWidgetIds != null && appWidgetIds.length > 0) 
     {
     //                this.onUpdate(context, 
     AppWidgetManager.getInstance(context), appWidgetIds);
     //            }
     //        } else {
     //            super.onReceive(context, intent);
     //        }
     //    }
        }
      }

更新:我已包含代碼以包括對.onReceive()的覆蓋,並且在此覆蓋方法中設置了該字段。 我試圖然后使用它來更新.onUpdateAppWidget()界面,但是該小部件未基於mRecipeName字段來更新TextView,因為mRecipeName字段為null。

您應該在AppWidgetClass中重寫onReceive。 這接收到廣播的意圖,因此您可以從中檢索數據

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);
    //Insert code here
}

並繼續添加代碼以從Intent接收/分配數據。

通過將廣播發送到窗口小部件(類固醇上的BroadcastReceiver)來觸發窗口小部件時,就從包中設置了字段mRecipeName ,但是在設置字段mRecipeName之前,您要更新RemoteView(因此mRecipeName此時為null)。 做這樣的事情:

@Override
public void onReceive(Context context, Intent intent) {
   mRecipeName = intent.getStringExtra(RECIPE_NAME);
   super.onReceive(context, intent);
}

實際上,使其更清潔用於生產。 做類似的事情:

Intent intent = new Intent(con, BakingWidgetProvider.class);
intent.setAction("UPDATE_ACTION");
int[] ids = AppWidgetManager.getInstance(con).getAppWidgetIds(new ComponentName(con, BakingWidgetProvider.class));
if(ids != null && ids.length > 0) {
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
      intent.putExtra(RECIPE_NAME, recipeName);
      con.sendBroadcast(intent);
}

您的onReceive將像:

@Override
public void onReceive(Context context, Intent intent) {
   if(intent.getAction().equals("UPDATE_ACTION") {
       mRecipeName = intent.getStringExtra(RECIPE_NAME);
       int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
       if (appWidgetIds != null && appWidgetIds.length > 0) {
            this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
       }
   } else {
      super.onReceive(context, intent);
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM