两种方式:
1、自己加载小部件列表做选择要显示的小部件
2、调用系统的弹窗做选择要显示的小部件
直接贴代码:
public class TempActivity extends FragmentActivity {private ActivityTempBinding viewBinding;private AppWidgetManager appWidgetManager;private AppWidgetHost appWidgetHost;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewBinding = ActivityTempBinding.inflate(getLayoutInflater());setContentView(viewBinding.getRoot());Context applicationContext = getApplicationContext();appWidgetManager = AppWidgetManager.getInstance(applicationContext);appWidgetHost = new AppWidgetHost(applicationContext, 0x200);appWidgetHost.startListening();FrameLayout frameLayout = viewBinding.framelayout;// 方式一:自己加载小部件列表做选择显示RecyclerView recyclerView = viewBinding.recycler;List<AppWidgetProviderInfo> installedProviders = appWidgetManager.getInstalledProviders();MyRecyclerAdapter adapter = new MyRecyclerAdapter(installedProviders);recyclerView.setAdapter(adapter);recyclerView.setLayoutManager(new LinearLayoutManager(this));adapter.setListener(v -> {AppWidgetProviderInfo info = (AppWidgetProviderInfo) v.getTag();int widgetId = appWidgetHost.allocateAppWidgetId();AppWidgetHostView appWidgetHostView = appWidgetHost.createView(this, widgetId, info);int widgetWidth = ViewGroup.LayoutParams.WRAP_CONTENT;int widgetHeight = ViewGroup.LayoutParams.WRAP_CONTENT;FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widgetWidth, widgetHeight);frameLayout.removeAllViews();frameLayout.addView(appWidgetHostView, params);Bundle options = appWidgetManager.getAppWidgetOptions(widgetId);boolean success = appWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info.provider, options);if (!success) {startBind(widgetId, info, options);}});// 方式二:使用系统自带的弹窗选择小部件viewBinding.btn.setOnClickListener(v -> {int widgetId = appWidgetHost.allocateAppWidgetId();Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);startActivityForResult(pickIntent, 200);});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK && data != null) {if (requestCode == 100) {createWidget(data);} else if (requestCode == 200) {addWidget(data);} else if (requestCode == 300) {addWidget(data);}}}private void createWidget(Intent data) {// 获取选择的widget的idint appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);// 获取所选的Widget的AppWidgetProviderInfo信息AppWidgetProviderInfo appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);// 根据AppWidgetProviderInfo信息,创建HostViewView hostView = appWidgetHost.createView(this, appWidgetId, appWidget);FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);viewBinding.framelayout.removeAllViews();viewBinding.framelayout.addView(hostView, params);Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);boolean success = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidget.provider, options);// 系统调起的总是return false
// if (!success) {
// startBind(appWidgetId, appWidget, options);
// }}private void startBind(int appWidgetId, AppWidgetProviderInfo info, Bundle options) {Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider);// This is the options bundle described in the preceding section.intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);startActivityForResult(intent, 300);}// 添加选择的widget。需要判断其是否含有配置,如果有,需要首先进入配置private void addWidget(Intent data) {int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,-1);AppWidgetProviderInfo appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);Log.d("AppWidget", "configure:" + appWidget.configure);if (appWidget.configure != null) {// 有配置,弹出配置Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);intent.setComponent(appWidget.configure);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);startActivityForResult(intent, 200);} else {// 没有配置,直接添加onActivityResult(100, RESULT_OK, data);}}}
注意,Activity一定不能继承AppCompatActivity,他会将小部件内部的控件都改写成了AppCompatXXXX,导致小部件不能显示。