Ответ 1
К сожалению, до сих пор нет api для получения этой информации от AppWidget-Host.
Вы можете получать текущую информацию о размере событий изменения размера (Android 4.1+) и только с пусковых установок, которые поддерживают это (например, Sony XPeria Launcher не работает, а также некоторые сторонние пусковые установки).
Я следил за этим потоком stackoverflow и Документацией разработчика Android:
Определите размер сетки в окнах виджетов рабочего стола
Вот мой код, чтобы определить размер виджета, взятый из 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, это было не вариант.
Получение уведомлений о изменениях ориентации для перерисовки виджета (ов) - это еще одна тема.
Важно. Если вы разрешаете пользователю иметь несколько виджетов, вы должны сделать это вычисление для каждого из них на основе их идентификатора!