获取我的主屏幕小部件的大小

问题描述:

我只想知道我当前的小部件有多大.我发现了很多问题来设置最小大小,但是我不想设置它.取而代之的是,我想显示那些仅适用于小部件的信息.

I just want to know how big my current widget is. I found tons of questions to set the minimum size, but I don't want to set it. Instead I want to show that informations which simply fit on the widget.

如果小部件太小,我需要隐藏一些东西,但是我需要知道它的大小.我阅读了诸如AppWidgetProvider之类的某些类的源代码,甚至是文档.总是有关于最小或最大尺寸的参考,而没有当前尺寸的参考.

If the widget is too small I need to hide some things, but I need to know the size for that. I read the source code of some classes like the AppWidgetProvider, even the documentation. There are allways just references about the minimum or maximum size, but never the current size.

请指向正确的资源.

不幸的是,仍然没有api可以从The AppWidget-Host获取此信息.

Unfortunately there still is no api to acquire this info from The AppWidget-Host.

您只能获得有关调整大小事件的当前大小信息(Android 4.1+),并且只能从支持此功能的启动器中获取(例如,Sony XPeria Launcher以及某些第三方启动器).

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).

我关注了这个stackoverflow线程和Android开发者文档:

I followed this stackoverflow thread and the Android Developer Documentation:

确定主屏幕的appwidgets空间网格大小

这是我确定小部件尺寸的代码,取自Picture Calendar 2014(Play商店):

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;
        }

在Android 4.1+上,您现在具有DIP中小部件的当前大小以用于当前设备方向.要知道您的窗口小部件有多少个主屏幕网格单元,您必须将其除以单元尺寸.默认值为74dip,但这可能会因使用不同的设备或启动器而有所不同.允许更改网格的自定义启动器对于Widget开发人员来说是一个痛苦的事情.

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.

在Android上< 4.1无法获得当前小部件的大小.因此,最好将您的API级别设置为JellyBean以避免麻烦.现在应该可以...两年前,当我开始使用我的Widget App时,这是不可行的.

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.

重要:如果您允许用户拥有自己的多个小部件,则必须根据他们的ID对每个人进行此计算!

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!