如何在Android Honeycomb中获取屏幕分辨率?

12

我想在Android Honeycomb上获取屏幕的真实分辨率。

这是我的代码:

Display display = getWindowManager().getDefaultDisplay();
int w = display.getWidth();
int h = display.getHeight();

我的设备是Asus Transformer TF101,尺寸为1280x800。

但是上面的代码使得w = 1280,h = 752(我想要的是800而不是752)。

我知道h < 800是因为状态栏被减去了。

有没有办法获取屏幕的真实高度?

非常感谢!


2
@alexanderblom 这对我来说不容易解释。但我真的需要获取Honeycomb的完整高度或状态栏。谢谢! - Levanphong7887
10个回答

15

从Andorid 3.2开始,系统状态栏的高度不再包含在DisplayMetrics的高度中,您需要使用未公开的API(Display.getRawWidth()和Display.getRawHeight())来获取物理屏幕宽度或高度。

以下是示例,展示如何获取物理屏幕宽度或高度。

Method mGetRawW = Display.class.getMethod("getRawWidth");
Method mGetRawH = Display.class.getMethod("getRawHeight");
int nW = (Integer)mGetRawW.invoke(dp);
int nH = (Integer)mGetRawH.invoke(dp);

更新: 对于API 13-16,您必须使用上面的代码获取真实的宽度/高度。 对于API 17+,您现在可以使用新的公共API,Display.getRealSize()。


12

下面是一些小技巧和假设,假设屏幕装饰物在顶部/底部,而不是左侧/右侧:

Display d = getWindowManager().getDefaultDisplay();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
int h = d.getWidth();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
int w = d.getWidth();

1
很不幸,例如在Kindle Fire上,你的假设完全是错误的。 - Lukas Hanacek

5

我手上有一台Xoom,并使用getWindowManager().getDefaultDisplay()来检索尺寸,它返回全屏大小的1280 x 800。我想知道如何在API版本3.0之前获取除导航栏之外的分辨率。


4
您得到的答案正确推断是因为状态栏。您只需要在窗口显示启动之前摆脱状态栏。然后,您可以在设置活动的内容视图之前重置状态栏。
这样做的原因是摆脱状态栏会影响您的视图绘制,除非您动态处理所有测量、布局和绘制。如果在运行时中间这样做,将导致状态栏消失,如果您想要它再次出现,则会导致用户感到困惑。
隐藏StatusBar的方法:
在onCreate() 中:
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
//Add the flag to the Window Attributes
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
//Disassociate Display from the Activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

现在您的默认显示应该正常工作。
仍然在您的onCreate()方法中:
Display display = getWindowManager().getDefaultDisplay();
int w = display.getWidth();
int h = display.getHeight();

在设置内容之前

同样,在您的onCreate()方法中:

final WindowManager.LayoutParams attrs = getWindow().getAttributes();
//Show the statubar
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
// Reassociate.
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

最后:

setContentView(r.layout.myView);

前面的代码段几乎可以在任何地方使用。我考虑到你的用户体验,当然你可以随意放置它们。这些是从我的一个项目中提取的功能段落。我也在一些主屏幕启动器中看到了类似的技术。注意:根据Android版本的不同,您可能需要在onWindowAttached()中执行状态栏操作。如果您这样做,请确保仍然调用super.onWindowAttached()。
另一种技术: 当然,如果您想要这样做,您可以在清单文件中以这种方式设置活动的属性。
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

这个例子在运行Android 4.4的Nexus 4上似乎无法正常工作。显示尺寸不包括通知栏。 - user153275
这篇文章的核心是一种方法,可以摆脱通知栏并进行测量。然而,这个例子是在 Android 4.4 之前制作的。Android 4.4 不允许您移除通知栏吗? - Fuzzical Logic

4

使用 DisplayMetrics 结构,描述有关显示屏的一般信息,例如其大小、密度和字体缩放。

获取显示屏高度的代码如下:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Log.d("log", "OOO " + metrics.heightPixels);

它应该返回显示器的绝对高度,以像素为单位。


1
谢谢,但是metrics.heightPixels = 752,与display.getHeight()相同。 - Levanphong7887
4
在Honeycomb系统中,这不能报告真实的物理屏幕尺寸。 - Pointer Null

0
在问题状态栏的高度?中,解释了如何获取状态栏的高度。有了statusBarHeight值,您可以执行以下操作:
Display display = getWindowManager().getDefaultDisplay();
int h = display.getHeight() + statusBarHeight;

0

或许你可以添加状态栏的高度。 状态栏的高度?

   Rect rectgle= new Rect();
   Window window= getWindow();
   window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
   int StatusBarHeight= rectgle.top;
   int contentViewTop= `enter code here`
      window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
   int TitleBarHeight= contentViewTop - StatusBarHeight;

   Log.i("*** Jorgesys :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight);

0
一个用于获取API11及以上级别屏幕尺寸的函数;还包括更高级别API的方法(更改函数以使用所选API、其函数调用和返回对象类型):
public int getScreenOrientation()
{
    int nOrientation = Configuration.ORIENTATION_UNDEFINED;

    try
    {
        DisplayMetrics displayMetrics = null;
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if(windowManager != null)
        {
            Display defaultDisplay = windowManager.getDefaultDisplay();
            if(defaultDisplay != null)
            {
                defaultDisplay.getMetrics(displayMetrics);//API11
                //defaultDisplay.getRectSize(rectGet);//API13
                //defaultDisplay.getSize(pointGet);//API13
                //defaultDisplay.getCurrentSizeRange(pointGet,pointGet);//API16
                //defaultDisplay.getRealSize(pointGet);//API17
                //defaultDisplay.getRealMetrics(displayMetrics);//API17
                if((displayMetrics.widthPixels == displayMetrics.heightPixels) || (displayMetrics.widthPixels < displayMetrics.heightPixels))
                {
                    nOrientation = Configuration.ORIENTATION_PORTRAIT;
                }
                else
                {
                    nOrientation = Configuration.ORIENTATION_LANDSCAPE;
                }
            }
        }
    }
    catch(Exception e)
    {
        showMessage(false,"Error","[getScreenOrientation]: " + e.toString());
    }

    return nOrientation;
}

注意:Configuration.ORIENTATION_SQUARE已经被弃用,因此它被替换为默认的ORIENTATION_PORTRAIT。

0

这是另一种可行的测量屏幕尺寸的解决方案(API 11+):

public static ABDimension calculateScreenDimensions(Activity activityGet)
{
    ABDimension abdReturn = new ABDimension();

    try
    {
        Rect rectGet = new Rect();
        Window winGet = null;
        DisplayMetrics displayMetrics = new DisplayMetrics();
        int nStatusBarHeight = 0;
        int nContentViewTop = 0;
        int nTitleBarHeight = 0;
        int nScreenHeight = 0;

        if((activityGet != null) && (rectGet != null) && (displayMetrics != null))
        {
            winGet = activityGet.getWindow();
            if(winGet != null)
            {
                winGet.getDecorView().getWindowVisibleDisplayFrame(rectGet);
                nStatusBarHeight = rectGet.top;
                nContentViewTop = winGet.findViewById(Window.ID_ANDROID_CONTENT).getTop();
                nTitleBarHeight = nContentViewTop - nStatusBarHeight;

                activityGet.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
                int screenHeight = displayMetrics.heightPixels;
                abdReturn.nWidth = displayMetrics.widthPixels;
                abdReturn.nHeight = screenHeight - (nTitleBarHeight + nStatusBarHeight);
            }
        }
    }
    catch(Exception e)
    {
        appContext.showMessage(false,"Error","[calculateScreenDimensions]: "+e.toString());
    }

    return abdReturn;
}

ABDimension类包含六个整数,标记为nWidth、nHeight、nMarginLeft、nMarginTop、nMarginRight和nMarginBottom。此版本考虑了常见的Android装饰组件,如TitleBar/StatusBar。


0
你可以扩展一个布局,这将成为你的顶级布局(它将被设置为填充父宽度和高度),并覆盖 onSizeChange(int width, int height, int oldwidth, int oldheight) 方法。宽度和高度是您显示屏的实际宽度和高度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接