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

相关推荐
Kapaseker13 分钟前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
黄林晴40 分钟前
Android17 为什么重写 MessageQueue
android
阿巴斯甜21 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android