Android:加载三方应用的小部件到自己APP显示

两种方式:

1、自己加载小部件列表做选择要显示的小部件

2、调用系统的弹窗做选择要显示的小部件

直接贴代码:

public class TempActivity extends FragmentActivity {
    private ActivityTempBinding viewBinding;
    private AppWidgetManager appWidgetManager;
    private AppWidgetHost appWidgetHost;

    @Override
    protected 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);
        });
    }

    @Override
    protected 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的id
        int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,	-1);
        // 获取所选的Widget的AppWidgetProviderInfo信息
        AppWidgetProviderInfo appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);
        // 根据AppWidgetProviderInfo信息,创建HostView
        View 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,导致小部件不能显示。

上一篇:全桥LLC谐振变换器概述及MATLAB仿真


下一篇:7-1 玩转二叉树