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

两种方式:

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

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

直接贴代码:

java 复制代码
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,导致小部件不能显示。

相关推荐
踢球的打工仔10 小时前
PHP面向对象(7)
android·开发语言·php
安卓理事人11 小时前
安卓socket
android
安卓理事人16 小时前
安卓LinkedBlockingQueue消息队列
android
万能的小裴同学18 小时前
Android M3U8视频播放器
android·音视频
q***577418 小时前
MySql的慢查询(慢日志)
android·mysql·adb
JavaNoober18 小时前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
城东米粉儿19 小时前
关于ObjectAnimator
android
zhangphil20 小时前
Android渲染线程Render Thread的RenderNode与DisplayList,引用Bitmap及Open GL纹理上传GPU
android
火柴就是我21 小时前
从头写一个自己的app
android·前端·flutter
lichong9511 天前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端