Unfortunately there still is no api to acquire this info from The AppWidget-Host.
You only get a current size info on resize events (Android 4.1+) and only from launchers which support this (Sony XPeria Launcher for example does not, as well as some third party launchers).
I followed this stackoverflow thread and the Android Developer Documentation:
Determine the homescreen's appwidgets space grid size
https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html#onAppWidgetOptionsChanged%28android.content.Context,%20android.appwidget.AppWidgetManager,%20int,%20android.os.Bundle%29
Here is my code to determine the widget size, taken from 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's 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;
}
On Android 4.1+ you now have the current size of the Widget in DIP for the current device orientation. To know how many homescreen grid cells your widget is wide and high, you have to divide this by cell size. Default is 74dip, but this may vary by using different devices or launchers. Custom Launchers which allow to change the grid are a pain in the ass for Widget developers.
On Android < 4.1 there is no way to get the current widget size. So better set your API level to JellyBean to avoid trouble. Should be ok now... two years ago when I started with my Widget App that was not an option.
Getting notified on orientation changes to redraw the widget(s) is another topic.
Important: If you allow the user to have multiple Widgets of yours, you have to do this calculation for everyone of them, based on their Id!