【问题标题】:Launch a widget from an application从应用程序启动小部件
【发布时间】:2020-09-30 06:30:31
【问题描述】:

在您的应用程序中,使用此代码,我可以获得设备上安装的所有小部件的提供者列表:

    AppWidgetManager manager = AppWidgetManager.getInstance(this);
    List <ComponentName> cn = new ArrayList<>();
    List<AppWidgetProviderInfo> infoList = manager.getInstalledProviders();
    for (AppWidgetProviderInfo info : infoList) {
            cn.add(info.provider);
    }

如果我想启动其中一个小部件,有没有办法做到这一点? (我想我可能需要 appWidgetId 但我不知道如何检索它)。

【问题讨论】:

    标签: android android-widget


    【解决方案1】:

    我从我非常旧的代码中复制了这个,所以它可能需要一些润色。它不是开箱即用的,但它包含向您展示如何操作的所有重要步骤。

    1. 首先,您需要显示一个选择器以让用户选择小部件:
        private void createWidget() {
            try {
                awhId = // generate your unique ID
                awh = new AppWidgetHost(ctx, awhId);
                int appWidgetId = awh.allocateAppWidgetId();
                Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
                pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
                pickIntent = widgetAddEmptyData(pickIntent);
                startActivityForResult(pickIntent, ActivityMain.REQUEST_CODE_WIDGET_ADD);
            } catch (Exception e) {
                widgetError(e.getMessage(), e);
            }
        }
    
    
       public Intent widgetAddEmptyData(Intent pickIntent) {
            ArrayList<AppWidgetProviderInfo> customInfo = new ArrayList<AppWidgetProviderInfo>();
            pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
            ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
            pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
            return pickIntent;
        }
    
    1. 您必须正确处理选择器的响应。
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            boolean processed = false;
            if (resultCode == Activity.RESULT_OK) {
                if (requestCode == ActivityMain.REQUEST_CODE_WIDGET_ADD) {
                    widgetConfigure(data);
                    processed = true;
                }
                if (requestCode == ActivityMain.REQUEST_CODE_WIDGET_CONFIGURED) {
                    widgetSave(data);
                    processed = true;
                }
            } else if (resultCode == Activity.RESULT_CANCELED && data != null) {
                int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
                if (appWidgetId != -1) {
                    try {
                        if (awh == null) {
                            awh = new AppWidgetHost(ctx, awhId);
                        }
                        awh.deleteAppWidgetId(appWidgetId);
                    } catch (Exception e) {}
                }
            }
            if (!processed) {
                super.onActivityResult(requestCode, resultCode, data);
            }
        }
    
        private void widgetConfigure(Intent data) {
            try {
                Bundle extras = data.getExtras();
                int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
                AppWidgetProviderInfo appWidgetInfo = wm.getAppWidgetInfo(appWidgetId);
                if (appWidgetInfo.configure != null) {
                    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
                    intent.setComponent(appWidgetInfo.configure);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
                    startActivityForResult(intent, ActivityMain.REQUEST_CODE_WIDGET_CONFIGURED);
                } else {
                    widgetSave(data);
                }
            } catch (Exception e) {
                widgetError(e.getMessage(), e);
            }
        }
    
        private void widgetSave(final Intent data) {
            try {
                Bundle extras = data.getExtras();
                final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
                final AppWidgetProviderInfo appWidgetInfo = wm.getAppWidgetInfo(appWidgetId);
    
                // store information about created widget
                store(MyApps.WIDGET_HOST_ID, awhId);
                store(MyApps.WIDGET_ID, appWidgetId);
                store(MyApps.WIDGET_ICON, appWidgetInfo.icon);
                store(MyApps.WIDGET_PACKAGE, appWidgetInfo.provider.getPackageName());
                store(MyApps.WIDGET_CLASS, appWidgetInfo.provider.getClassName());
        }
    
    1. 创建小部件并存储其数据后,即可托管它。
    AppWidgetManager wm = AppWidgetManager.getInstance(getContext());
    awh = new FaAppWidgetHost(getContext(), myAppItem.getWidgetHostId());
    AppWidgetProviderInfo appWidgetInfo = wm.getAppWidgetInfo(myAppItem.getWidgetId());
    AppWidgetHostView hostView = awh.createView(getContext(), myAppItem.getWidgetId(), appWidgetInfo);
    hostView.setAppWidget(myAppItem.getWidgetId(), appWidgetInfo);
    awh.startListening();
    

    【讨论】:

    • mmm 非常好:) 但是,我不想创建小部件。小部件已经存在并且来自第三方应用程序。比如说airbnb小部件。所以我没有appWidgetId。 (我尝试使用 getAppWidgetIds 来获取它,但我遇到了安全异常)。你知道有没有办法做到这一点?
    • 我们中的一个人不明白:-)。我上面的代码是关于如何在您的应用程序中托管小部件(例如来自 airbnb 和其他应用程序的小部件)。这不是关于创建自定义小部件,而是注册现有小部件的实例,对其进行配置并显示它。您不能只列出 id 并在您的应用中显示一些小部件,因为这些小部件没有被您的应用注册 - 因此是安全异常。
    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多