我有一个小部件,希望它在单击时打开活动。这是场景:用户应该能够向小部件添加配方,这样,如果单击小部件,它将打开包含该配方的活动。 我注意到小部件类中的onUpdate回调仅在应用启动时被调用一次。
这是我的活动代码(我将食谱保存在SharedPreferences中,以便小部件在要使用该食谱数据打开活动时可以检索其数据):
public class RecipeDetailsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recipe_details);
FloatingActionButton floatingActionButton = findViewById(R.id.recipe_fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
storeRecipe(ingredients, steps);
Intent intent = new Intent(RecipeDetailsActivity.this, RecipeWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
AppWidgetManager widgetManager = AppWidgetManager.getInstance(RecipeDetailsActivity.this);
int [] ids = widgetManager.getAppWidgetIds(new ComponentName(getApplication(), RecipeWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, ids);
sendBroadcast(intent);
Toast.makeText(RecipeDetailsActivity.this, "clicked", Toast.LENGTH_LONG).show();
}
});
}
private void storeRecipe (ArrayList <Ingredient> ingredients, ArrayList <Step> steps){
//The Gson trick is obtained from here: https://www.youtube.com/watch?v=jcliHGR3CHo
//Convert the ingredients and steps to Json string using Gson library so we can store those strings in SharedPreferences:
Gson GsonObj = new Gson();
String ingredientsJson = GsonObj.toJson(ingredients);
String stepsJson = GsonObj.toJson(steps);
//Store the data in SahredPreferences
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("ingredients", ingredientsJson).apply();
editor.putString("steps", stepsJson).apply();
}
}
这是我的AppWidget Java类:
public class RecipeWidget extends AppWidgetProvider {
static ArrayList <Ingredient> ingredients;
static ArrayList <Step> steps;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// To add interaction through the widget, construct a remoteviews object and associate it with the widget layout
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.recipe_widget);
//Create an intent that will open the details (ingredients and steps) for the desired recipe, then add it to a pending intent that will be fired when the widget is clicked
Intent intent = new Intent (context, RecipeDetailsActivity.class);
//Load the ArrayLists of the steps and ingredients of the selected recipe from SharedPrefs
loadRecipe(context);
//Prepare a bundle to add it to the pending intent
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("ingredients", ingredients);
bundle.putParcelableArrayList("steps", steps);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0, bundle);
remoteViews.setOnClickPendingIntent(appWidgetId, pendingIntent);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
Log.i("msg", "on update is called");
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
static private void loadRecipe (Context context){
//The Gson trick is obtained from here: https://www.youtube.com/watch?v=jcliHGR3CHo
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String ingredientsString = sharedPreferences.getString("ingredients", null);
String stepsString = sharedPreferences.getString("steps", null);
//Convert the ingredients and steps from Strings to ArrayLists:
Gson GsonObj = new Gson();
Type ingredientsType = new TypeToken<ArrayList<Ingredient>>() {}.getType();
Type stepsType = new TypeToken<ArrayList<Step>>() {}.getType();
ingredients = GsonObj.fromJson(ingredientsString, ingredientsType);
steps = GsonObj.fromJson(stepsString, stepsType);
}
}
最后,这是清单中定义窗口小部件的方式:
<receiver android:name=".widgets.RecipeWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.example.backingapp.RecipeWidget.ACTION_CLICK"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/recipe_widget_info" />
</receiver>
我将不胜感激。 谢谢。