如何在Android应用程序中创建一个小部件? (使用App Widget Host类?)

时间:2014-02-19 21:19:21

标签: android-widget widget android android-appwidget

我需要创建一个包含多个小部件的应用程序。这些不是桌面小部件。我需要能够与这些小部件进行交互,就好像它们是桌面小部件一样,但是它们需要被封装在更大的应用程序中。 (每个小部件在单击时都有自己的功能和行为。)

这在Android中是否可行?或者我是否需要创建一个应用程序并创建我想表现得像窗口小部件实际上作为视图的每个对象?

实施例。父应用程序适用于汽车。 “在应用程序”小部件的示例是:换油历史(可见的最后三个换油日期列表,点击日期将打开收据扫描等),胎压监测器,单圈速度历史记录(显示最后四圈) ,捏和扩展将显示超过四个)等。

我可以制作这些对象的每个小部件吗?或者他们必须在应用程序内部查看?

编辑:Android开发人员App Widget Host page提到:“AppWidgetHost为应用程序(如主屏幕)提供了与AppWidget服务的交互,这些应用程序希望在其UI中嵌入应用程序小部件。 “
有没有人创建过他们自己的App Widget Host或者直接使用这个类?

2 个答案:

答案 0 :(得分:2)

正常创建appwidget

然后在您的活动中添加此代码 调用selectWidget()打开弹出窗口以选择可用的小部件

//init
mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetHost = new AppWidgetHost(this, R.id.APPWIDGET_HOST_ID);

//select widget
void selectWidget() {
    int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId();
    Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
    pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    addEmptyData(pickIntent);
    startActivityForResult(pickIntent, R.id.REQUEST_PICK_APPWIDGET);
}
void addEmptyData(Intent pickIntent) {
    ArrayList customInfo = new ArrayList();
    pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
    ArrayList customExtras = new ArrayList();
    pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
};

//Configure the widget
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK ) {
        if (requestCode == REQUEST_PICK_APPWIDGET) {
            configureWidget(data);
        }
        else if (requestCode == REQUEST_CREATE_APPWIDGET) {
            createWidget(data);
        }
    }
    else if (resultCode == RESULT_CANCELED && data != null) {
        int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        if (appWidgetId != -1) {
            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
        }
    }
}

private void configureWidget(Intent data) {
    Bundle extras = data.getExtras();
    int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.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, REQUEST_CREATE_APPWIDGET);
    } else {
        createWidget(data);
    }
}

//adding it to you view
public void createWidget(Intent data) {
    Bundle extras = data.getExtras();
    int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
    AppWidgetHostView hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
    hostView.setAppWidget(appWidgetId, appWidgetInfo);
    layout.addView(hostView);
}

//Update widget
@Override
protected void onStart() {
    super.onStart();
    mAppWidgetHost.startListening();
}
@Override
protected void onStop() {
    super.onStop();
    mAppWidgetHost.stopListening();
}

//Now to remove it call this
public void removeWidget(AppWidgetHostView hostView) {
    mAppWidgetHost.deleteAppWidgetId(hostView.getAppWidgetId());
    layout.removeView(hostView);
}

希望这有帮助

答案 1 :(得分:0)

如果您想在应用中嵌入特定小部件,并且知道包名称和类名:

public boolean createWidget(View view, String packageName, String className) {
    // Get the list of installed widgets
    AppWidgetProviderInfo newAppWidgetProviderInfo = null;
    List<AppWidgetProviderInfo> appWidgetInfos;
    appWidgetInfos = mAppWidgetManager.getInstalledProviders();
    boolean widgetIsFound = false;
    for(int j = 0; j < appWidgetInfos.size(); j++)
    {
        if (appWidgetInfos.get(j).provider.getPackageName().equals(packageName) && appWidgetInfos.get(j).provider.getClassName().equals(className))
        {
            // Get the full info of the required widget
            newAppWidgetProviderInfo = appWidgetInfos.get(j);
            widgetIsFound = true;
            break;
        }
    }

    if (!widgetIsFound) {
        return false;
    } else {
        // Create Widget
        int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
        AppWidgetHostView hostView = mAppWidgetHost.createView(getApplicationContext(), appWidgetId, newAppWidgetProviderInfo);
        hostView.setAppWidget(appWidgetId, newAppWidgetProviderInfo);

        // Add it to your layout
        LinearLayout widgetLayout = view.findViewById(R.id.widget_view);
        widgetLayout.addView(hostView);

        // And bind widget IDs to make them actually work
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            boolean allowed = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, newAppWidgetProviderInfo.provider);

            if (!allowed) {
                // Request permission - https://stackoverflow.com/a/44351320/1816603
                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, newAppWidgetProviderInfo.provider);
                final int REQUEST_BIND_WIDGET = 1987;
                startActivityForResult(intent, REQUEST_BIND_WIDGET);
            }
        }

        return true;
    }
}