Получить размер моего виджета рабочего стола

Я просто хочу знать, насколько велик мой текущий виджет. Я нашел массу вопросов, чтобы установить минимальный размер, но я не хочу его устанавливать. Вместо этого я хочу показать эту информацию, которая просто вписывается в виджет.

Если виджет слишком мал, мне нужно скрыть некоторые вещи, но мне нужно знать размер для этого. Я прочитал исходный код некоторых классов, таких как AppWidgetProvider, даже документация. Есть всегда ссылки на минимальный или максимальный размер, но не текущий размер.

Укажите мне правильный ресурс.

Ответ 1

К сожалению, до сих пор нет api для получения этой информации от AppWidget-Host.

Вы можете получать текущую информацию о размере событий изменения размера (Android 4.1+) и только с пусковых установок, которые поддерживают это (например, Sony XPeria Launcher не работает, а также некоторые сторонние пусковые установки).

Я следил за этим потоком stackoverflow и Документацией разработчика Android:

Определите размер сетки в окнах виджетов рабочего стола

https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html#onAppWidgetOptionsChanged%28android.content.Context,%20android.appwidget.AppWidgetManager,%20int,%20android.os.Bundle%29

Вот мой код, чтобы определить размер виджета, взятый из Picture Calendar 2014 (Play Store):

        /* Get Device and Widget orientation. 
           This is done by adding a boolean value to 
           a port resource directory like values-port/bools.xml */

        mIsPortraitOrientation = getResources().getBoolean(R.bool.isPort);

        // Get min dimensions from provider info
        AppWidgetProviderInfo providerInfo = AppWidgetManager.getInstance(
            getApplicationContext()).getAppWidgetInfo(appWidgetId);

        // Since min and max is usually the same, just take min
        mWidgetLandWidth = providerInfo.minWidth;
        mWidgetPortHeight = providerInfo.minHeight;
        mWidgetPortWidth = providerInfo.minWidth;
        mWidgetLandHeight = providerInfo.minHeight;

        // Get current dimensions (in DIP, scaled by DisplayMetrics) of this
        // Widget, if API Level allows to
        mAppWidgetOptions = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            mAppWidgetOptions = getAppWidgetoptions(mAppWidgetManager,
                    appWidgetId);

        if (mAppWidgetOptions != null
                && mAppWidgetOptions
                        .getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH) > 0) {
            if (D.DEBUG_SERVICE)
                Log.d(TAG,
                        "appWidgetOptions not null, getting widget sizes...");
            // Reduce width by a margin of 8dp (automatically added by
            // Android, can vary with third party launchers)

            /* Actually Min and Max is a bit irritating, 
               because it depends on the homescreen orientation
               whether Min or Max should be used: */

            mWidgetPortWidth = mAppWidgetOptions
                    .getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
            mWidgetLandWidth = mAppWidgetOptions
                    .getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
            mWidgetLandHeight = mAppWidgetOptions
                    .getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
            mWidgetPortHeight = mAppWidgetOptions
                    .getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);

            // Get the value of OPTION_APPWIDGET_HOST_CATEGORY
            int category = mAppWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);

            // If the value is WIDGET_CATEGORY_KEYGUARD, it a lockscreen
            // widget (dumped with Android-L preview :-( ).
            mIsKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;

        } else {
            if (D.DEBUG_SERVICE)
                Log.d(TAG,
                        "No AppWidgetOptions for this widget, using minimal dimensions from provider info!");
            // For some reason I had to set this again here, may be obsolete
            mWidgetLandWidth = providerInfo.minWidth;
            mWidgetPortHeight = providerInfo.minHeight;
            mWidgetPortWidth = providerInfo.minWidth;
            mWidgetLandHeight = providerInfo.minHeight;
        }

        if (D.DEBUG_SERVICE)
            Log.d(TAG, "Dimensions of the Widget in DIP: portWidth =  "
                    + mWidgetPortWidth + ", landWidth = " + mWidgetLandWidth
                    + "; landHeight = " + mWidgetLandHeight
                    + ", portHeight = " + mWidgetPortHeight);

        // If device is in port oriantation, use port sizes
        mWidgetWidthPerOrientation = mWidgetPortWidth;
        mWidgetHeightPerOrientation = mWidgetPortHeight;

        if (!mIsPortraitOrientation)
        {
            // Not Portrait, so use landscape sizes
            mWidgetWidthPerOrientation = mWidgetLandWidth;
            mWidgetHeightPerOrientation = mWidgetLandHeight;
        }

В Android 4.1+ теперь у вас текущий размер виджета в DIP для текущей ориентации устройства. Чтобы узнать, сколько ячеек сетевых экранов вашего экрана широко и высоко, вы должны разделить это на размер ячейки. Значение по умолчанию - 74dip, но это может зависеть от использования разных устройств или пусковых установок. Пользовательские пусковые установки, которые позволяют изменять сетку, - это боль в заднице для разработчиков Widget.

В Android < 4.1 нет способа получить текущий размер виджета. Поэтому лучше настройте свой уровень API на JellyBean, чтобы избежать неприятностей. Должно быть хорошо сейчас... два года назад, когда я начал с моего приложения Widget, это было не вариант.

Получение уведомлений о изменениях ориентации для перерисовки виджета (ов) - это еще одна тема.

Важно. Если вы разрешаете пользователю иметь несколько виджетов, вы должны сделать это вычисление для каждого из них на основе их идентификатора!