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,导致小部件不能显示。

相关推荐
2501_9151063212 小时前
iOS 性能优化这件事,结合多工具分析运行期性能问题
android·ios·性能优化·小程序·uni-app·cocoa·iphone
千里马学框架12 小时前
如何使用豆包手机的READ_FRAME_BUFFER权限截图密码画面
android·智能手机·framework·安卓framework开发·权限·截图·secure
游戏开发爱好者812 小时前
App Store 上架流程,结合多工具协作
android·ios·小程序·https·uni-app·iphone·webview
阿道夫小狮子12 小时前
android 音频抢占问题
android·音视频
撩得Android一次心动13 小时前
Android 四大组件——Service(服务)【基础篇1】
android·服务·四大组件
峥嵘life13 小时前
Android16 EDLA 认证测试BTS过程介绍
android·java·linux
茶憶14 小时前
UniApp 安卓端实现文件的生成,写入,获取文件大小以及压缩功能
android·javascript·vue.js·uni-app
2501_9159214314 小时前
uni-app 的 iOS 打包与上架流程,多工具协作
android·ios·小程序·uni-app·cocoa·iphone·webview
Lei活在当下21 小时前
【Perfetto从入门到精通】4.使用 heapprofd 工具采样追踪 Java/Native 内存分配
android·性能优化·架构
alexhilton21 小时前
学会在Jetpack Compose中加载Lottie动画资源
android·kotlin·android jetpack