简体   繁体   English

以编程方式检测 7 英寸和 10 英寸平板电脑

[英]Detect 7 inch and 10 inch tablet programmatically

有没有办法以编程方式查找安装应用程序的设备是 7 英寸平板电脑还是 10 英寸平板电脑?

You can use the DisplayMetrics to get a whole bunch of information about the screen that your app is running on.您可以使用DisplayMetrics获取有关您的应用正在运行的屏幕的大量信息。

First, we create a DisplayMetrics metrics object:首先,我们创建一个DisplayMetrics指标对象:

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

From this, we can get the information required to size the display:从中,我们可以获得显示大小所需的信息:

int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;

This will return the absolute value of the width and the height in pixels, so 1280x720 for the Galaxy SIII, the Galaxy Nexus etc.这将返回宽度和高度的绝对值(以像素为单位),因此 Galaxy SIII、Galaxy Nexus 等为 1280x720。

This isn't usually helpful on its own, as when we're working on Android devices, we usually prefer to work in density independent pixels, dip.这本身通常没有帮助,因为当我们在 Android 设备上工作时,我们通常更喜欢在与密度无关的像素中工作,dip。

You get the density of the screen using metrics again, in the form of a scale factor for the device, which is based on the Android Design Resources for mdpi , hdpi etc.您再次使用metrics以设备比例因子的形式获得屏幕density ,该比例因子基于mdpihdpi等的Android 设计资源DPI 比例

float scaleFactor = metrics.density;

From this result, we can calculate the amount of density independent pixels there are for a certain height or width.根据这个结果,我们可以计算出特定高度或宽度的密度无关像素的数量。

float widthDp = widthPixels / scaleFactor
float heightDp = heightPixels / scaleFactor

The result you get from this will help you decide what type of screen you are working with in conjunction with the Android Configuration examples , which give you the relative dp for each screen size:您从中获得的结果将帮助您结合Android 配置示例确定您正在使用的屏幕类型,这些示例为您提供每种屏幕尺寸的相对 dp:

  • 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc). 320dp:典型的手机屏幕(240x320 ldpi、320x480 mdpi、480x800 hdpi 等)。
  • 480dp: a tweener tablet like the Streak (480x800 mdpi). 480dp:像 Streak (480x800 mdpi) 这样的 tweener 平板电脑。
  • 600dp: a 7” tablet (600x1024 mdpi). 600dp:7 英寸平板电脑 (600x1024 mdpi)。
  • 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc). 720dp:10 英寸平板电脑(720x1280 mdpi、800x1280 mdpi 等)。

Using the above information, we know that if the smallest-width of the device is greater than 600dp, the device is a 7" tablet, if it's greater than 720dp, the device is a 10" tablet.由以上信息可知,如果设备的最小宽度大于600dp,则该设备为7"平板电脑,如果大于720dp,则该设备为10"平板电脑。

We can work out the smallest width using the min function of Math class, passing in the heightDp and the widthDp to return the smallestWidth .我们可以用计算出的最小宽度min的函数Math类,传入heightDpwidthDp返回smallestWidth

float smallestWidth = Math.min(widthDp, heightDp);

if (smallestWidth > 720) {
    //Device is a 10" tablet
} 
else if (smallestWidth > 600) {
    //Device is a 7" tablet
}

However, this doesn't always give you an exact match, especially when working with obscure tablets that might be misrepresenting their density as hdpi when it isn't, or that might only be 800 x 480 pixels yet still be on a 7" screen.然而,这并不总是能给你一个精确的匹配,特别是当使用模糊的平板电脑时,这些平板电脑可能会误将其密度表示为 hdpi,或者可能只有 800 x 480 像素但仍然在 7" 屏幕上.

Further to these methods, if you ever need to know the exact dimensions of a device in inches, you can work that out too, using the metrics method for how many pixels there are per inch of the screen.除了这些方法之外,如果您需要知道设备的确切尺寸(以英寸为单位),您也可以使用metrics方法计算出每英寸屏幕有多少像素。

float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;

You can use the knowledge of how many pixels are in each inch of device and the amount of pixels in total to work out how many inches the device is.您可以使用每英寸设备中有多少像素和总像素数的知识来计算设备有多少英寸。

float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;

This will return the height and width of the device in inches.这将以英寸为单位返回设备的高度和宽度。 This again isn't always that helpful for determining what type of device it is, as the advertised size of a device is the diagonal, all we have is the height and the width.这对于确定它是什么类型的设备并不总是那么有帮助,因为设备的广告尺寸是对角线,我们只有高度和宽度。

However, we also know that given the height of a triangle and the width, we can use the Pythagorean theorem to work out the length of the hypotenuse (In this case, the size of the screen diagonal).然而,我们也知道给定三角形的高度和宽度,我们可以使用勾股定理来计算斜边的长度(在这种情况下,屏幕对角线的大小)。

//a² + b² = c²

//The size of the diagonal in inches is equal to the square root of the height in inches squared plus the width in inches squared.
double diagonalInches = Math.sqrt(
    (widthInches * widthInches) 
    + (heightInches * heightInches));

From this, we can work out whether the device is a tablet or not:由此,我们可以确定设备是否为平板电脑:

if (diagonalInches >= 10) {
    //Device is a 10" tablet
} 
else if (diagonalInches >= 7) {
    //Device is a 7" tablet
}

And that's how you calculate what kind of device you're working with.这就是您如何计算您正在使用的设备类型。

There's nothing that says 7" or 10" AFAIK.没有什么可以说7"10" AFAIK。 There are roughly two ways do get screen dimensions that the system uses when decoding bitmaps and whatnot.大致有两种方法可以获取系统在解码位图等时使用的屏幕尺寸。 They're both found in the application's Resources object found in the Context .它们都可以在Context中的应用程序Resources对象中找到。

The first is the Configuration object which can be obtained by getContext().getResources().getConfiguration() .第一个是可以通过getContext().getResources().getConfiguration()获取的Configuration对象。 In it you have:其中你有:

Configuration#densityDpi - The target screen density being rendered to, corresponding to density resource qualifier. Configuration#densityDpi - 渲染到的目标屏幕密度,对应于密度资源限定符。

Configuration#screenHeightDp - The current height of the available screen space, in dp units, corresponding to screen height resource qualifier. Configuration#screenHeightDp - 可用屏幕空间的当前高度,以dp为单位,对应屏幕高度资源限定符。

Configuration#screenWidthDp - The current width of the available screen space, in dp units, corresponding to screen width resource qualifier. Configuration#screenWidthDp - 可用屏幕空间的当前宽度,以dp为单位,对应屏幕宽度资源限定符。

Configuration#smallestScreenWidthDp - The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier. Configuration#smallestScreenWidthDp - 应用程序在正常操作中将看到的最小屏幕尺寸,对应于最小屏幕宽度资源限定符。

With that, you can pretty much use the screen guidelines to figure out if your device is pulling from the respective specialized resource folders ( hdpi , xhdpi , large , xlarge , etc.).有了这个,您几乎可以使用屏幕指南来确定您的设备是否从各自的专用资源文件夹( hdpixhdpilargexlarge等)中xlarge

Remember, these are some of the buckets:请记住,这些是一些桶:

  • xlarge screens are at least 960dp x 720dp xlarge 屏幕至少为 960dp x 720dp
  • large screens are at least 640dp x 480dp大屏幕至少 640dp x 480dp
  • normal screens are at least 470dp x 320dp普通屏幕至少为 470dp x 320dp
  • small screens are at least 426dp x 320dp小屏幕至少为 426dp x 320dp

  • 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc). 320dp:典型的手机屏幕(240x320 ldpi、320x480 mdpi、480x800 hdpi 等)。

  • 480dp: a tweener tablet like the Streak (480x800 mdpi). 480dp:像 Streak (480x800 mdpi) 这样的 tweener 平板电脑。
  • 600dp: a 7” tablet (600x1024 mdpi). 600dp:7 英寸平板电脑 (600x1024 mdpi)。
  • 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc). 720dp:10 英寸平板电脑(720x1280 mdpi、800x1280 mdpi 等)。

More info 更多信息

The second is the DisplayMetrics object obtained by getContext().getResources().getDisplayMetrics() .第二个是通过getContext().getResources().getDisplayMetrics()获取的DisplayMetrics对象。 In that you have:你有:

DisplayMetrics#density - The logical density of the display. DisplayMetrics#density - 显示的逻辑密度。

DisplayMetrics#densityDpi - The screen density expressed as dots-per-inch. DisplayMetrics#densityDpi - 以每英寸点数表示的屏幕密度。

DisplayMetrics#heightPixels - The absolute height of the display in pixels. DisplayMetrics#heightPixels - 显示的绝对高度(以像素为单位)。

DisplayMetrics#widthPixels - The absolute width of the display in pixels. DisplayMetrics#widthPixels - 显示的绝对宽度(以像素为单位)。

DisplayMetrics#xdpi - The exact physical pixels per inch of the screen in the X dimension. DisplayMetrics#xdpi - X 维度中每英寸屏幕的确切物理像素。

DisplayMetrics#ydpi - The exact physical pixels per inch of the screen in the Y dimension. DisplayMetrics#ydpi - Y 维度中每英寸屏幕的确切物理像素。

This is handy if you need exact pixel count of the screen rather than density.如果您需要屏幕的精确像素数而不是密度,这很方便。 However, it is important to note that this is all the screen's pixels.但是,重要的是要注意,这是屏幕的所有像素。 Not just the ones available to you.不仅仅是你可以使用的那些。

place this method in onResume() and can check.将此方法放在 onResume() 中并可以检查。

public double tabletSize() {

     double size = 0;
        try {

            // Compute screen size

            DisplayMetrics dm = context.getResources().getDisplayMetrics();

            float screenWidth  = dm.widthPixels / dm.xdpi;

            float screenHeight = dm.heightPixels / dm.ydpi;

            size = Math.sqrt(Math.pow(screenWidth, 2) +

                                 Math.pow(screenHeight, 2));

        } catch(Throwable t) {

        }

        return size;

    }

generally tablets starts after 6 inch size.通常平板电脑从 6 英寸大小开始。

The above doesn't always work when switching portrait vs. landscape.在切换纵向与横向时,上述内容并不总是有效。

If you are targeting API level 13+, it is easy as described above -- use Configuration.smallestScreenWidthDp, then test accordingly:如果您的目标是 API 级别 13+,则如上所述很简单——使用 Configuration.smallestScreenWidthDp,然后进行相应的测试:

resources.getConfiguration().smallestScreenWidthDp

Otherwise, if you can afford this, use the following method which is a very accurate approach to detect 600dp (like 6") vs. 720dp (like 10") by letting the system tell you:否则,如果您负担得起,请使用以下方法,这是一种非常准确的方法,通过让系统告诉您来检测 600dp(如 6")与 720dp(如 10"):

1) Add to layout-sw600dp and layout-sw720dp (and if applicable its landscape) an invisible view with proper ID, for example: 1) 向 layout-sw600dp 和 layout-sw720dp(如果适用的话,它的横向)添加一个具有适当 ID 的不可见视图,例如:

For 720, on layout-sw720dp:对于 720,在 layout-sw720dp 上:

<View android:id="@+id/sw720" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>

For 600, on layout-sw600dp:对于 600,在 layout-sw600dp 上:

<View android:id="@+id/sw600" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>

2) Then on the code, for example, the Activity, test accordingly: 2)然后在代码上,例如Activity,进行相应的测试:

private void showFragment() {
    View v600 = (View) findViewById(R.id.sw600);
    View v720 = (View) findViewById(R.id.sw720);
    if (v600 != null || v720 !=null)
        albumFrag = AlbumGridViewFragment.newInstance(albumRefresh);
    else
        albumFrag = AlbumListViewFragment.newInstance(albumRefresh);
    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.view_container, albumFrag)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .commit();
}

Great information, just what I was looking for!很好的资料,正是我要找的! However, after trying this out I found that when using the metrics mentioned here the Nexus 7 (2012 model) reports having dimensions 1280x736.但是,在尝试之后,我发现使用此处提到的指标时,Nexus 7(2012 型号)报告的尺寸为 1280x736。 I also have a Motorola Xoom running Jelly Bean and it incorrectly reports a resolution of 1280x752.我还有一台运行 Jelly Bean 的 Motorola Xoom,它错误地报告了 1280x752 的分辨率。 I stumbled upon this post here that confirms this.我在这里偶然发现了这篇文章,证实了这一点。 Basically, in ICS/JB the calculations using the metrics mentioned above appear to exclude the dimensions of the Navigation Bar.基本上,在 ICS/JB 中,使用上述指标的计算似乎不包括导航栏的维度。 Some more research led me to Frank Nguyen's answer here that uses different methods that will give you the raw (or real) pixel dimensions of the screen.更多的研究让我找到了Frank Nguyen 的答案,它使用不同的方法为您提供屏幕的原始(或真实)像素尺寸。 My initial testing has shown that the following code from Frank correclty reports the dimensions on the Nexus 7 (2012 model runnin JB) and my Motorola Xoom running JB:我的初步测试表明,以下来自 Frank correclty 的代码报告了 Nexus 7(运行 JB 的 2012 型号)和运行 JB 的摩托罗拉 Xoom 的尺寸:

int width = 0, height = 0;
final DisplayMetrics metrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
Method mGetRawH = null, mGetRawW = null;

try {
    // For JellyBeans and onward
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
        display.getRealMetrics(metrics);

        width = metrics.widthPixels;
        height = metrics.heightPixels;
    } else {
        mGetRawH = Display.class.getMethod("getRawHeight");
        mGetRawW = Display.class.getMethod("getRawWidth");

        try {
            width = (Integer) mGetRawW.invoke(display);
            height = (Integer) mGetRawH.invoke(display);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
} catch (NoSuchMethodException e3) {
    e3.printStackTrace();
}

I have two android device with same resolution我有两个分辨率相同的安卓设备

Device1 -> resolution 480x800 diagonal screen size -> 4.7 inches设备 1 -> 分辨率 480x800 屏幕对角线尺寸 -> 4.7 英寸

Device2 -> resolution 480x800 diagonal screen size -> 4.0 inches Device2 -> 分辨率 480x800 屏幕对角线尺寸 -> 4.0 英寸

It gives both device diagonal screen size -> 5.8它给两个设备对角线屏幕尺寸 -> 5.8

the solution to your problem is..您的问题的解决方案是..

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
int dens=dm.densityDpi;
double wi=(double)width/(double)dens;
double hi=(double)height/(double)dens;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);

see details here .. 详情请看这里..

They way that Android specifies screen sizes is through four generalized sizes: small , normal , large and xlarge . Android 指定屏幕尺寸的方式是通过四种通用尺寸: smallnormallargexlarge

While the Android documentation states that the size groups are deprecated虽然 Android 文档指出不推荐使用大小组

... these size groups are deprecated in favor of a new technique for managing screen sizes based on the available screen width. ... 这些尺寸组已被弃用,取而代之的是一种基于可用屏幕宽度管理屏幕尺寸的新技术。 If you're developing for Android 3.2 and greater, see [Declaring Tablet Layouts for Android 3.2]( hdpi (high) ~240dpi) for more information.如果您正在为 Android 3.2 及更高版本进行开发,请参阅 [Declaring Tablet Layouts for Android 3.2]( hdpi (high) ~240dpi) 了解更多信息。

Generally the size qualifier large specifies a 7" tablet. And a size qualifier of xlarge specifies a 10" tablet:通常,大小限定符large指定 7" 平板电脑。而xlarge的大小限定符指定 10" 平板电脑:

在此处输入图片说明

The nice thing about triggering on the the size qualifier, is that you can guarantee that your assets and code are in agreement on which asset to use or code path to activate.触发大小限定符的好处是,您可以保证您的资产和代码就使用哪个资产或激活代码路径达成一致。

To retrieve the size qualifier in code make the following calls:要在代码中检索大小限定符,请进行以下调用:

int sizeLarge = SCREENLAYOUT_SIZE_LARGE // For 7" tablet
boolean is7InchTablet = context.getResources().getConfiguration()
    .isLayoutSizeAtLeast(sizeLarge);

int sizeXLarge = SCREENLAYOUT_SIZE_XLARGE // For 10" tablet
boolean is10InchTablet = context.getResources().getConfiguration()
    .isLayoutSizeAtLeast(sizeXLarge);

You can use the below method to get the screen size in inches, based on that simply you can check which tablet or phone the device is.您可以使用以下方法获取以英寸为单位的屏幕尺寸,基于此您可以简单地检查设备是哪款平板电脑或手机。

private static double checkDimension(Context context) {

    WindowManager windowManager = ((Activity)context).getWindowManager();
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    // since SDK_INT = 1;
    int mWidthPixels = displayMetrics.widthPixels;
    int mHeightPixels = displayMetrics.heightPixels;

    // includes window decorations (statusbar bar/menu bar)
    try
    {
        Point realSize = new Point();
        Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
        mWidthPixels = realSize.x;
        mHeightPixels = realSize.y;
    }
    catch (Exception ignored) {}

    DisplayMetrics dm = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(dm);
    double x = Math.pow(mWidthPixels/dm.xdpi,2);
    double y = Math.pow(mHeightPixels/dm.ydpi,2);
    double screenInches = Math.sqrt(x+y);
    Log.d("debug","Screen inches : " + screenInches);
    return screenInches;
}

I was storing a value in values folder that gives me screen is 7 inch or 10 inc but we can do it for any device using values folder.我在values 文件夹中存储了一个值,该使我的屏幕为 7 英寸或 10 英寸,但我们可以使用 values 文件夹为任何设备执行此操作。

like create different-2 values folder for different-2 devices.比如为不同的 2 设备创建不同的 2 值文件夹。 But this thing depends upon the requirement.但这件事取决于要求。

You'll have to make a little bit of computation using data given by the DisplayMetrics class.您必须使用DisplayMetrics类提供的数据进行一些计算。

You have heightPixel and widthPixels ( the screen resolution in pixels)你有 heightPixel 和 widthPixels (以像素为单位的屏幕分辨率)

You need the diagonal since the 'inch screen size' always describe the diagonal length.您需要对角线,因为“​​英寸屏幕尺寸”总是描述对角线长度。 You can get the screen diagonal in pixel (using pythagore)您可以获得以像素为单位的屏幕对角线(使用 pythagore)

diagonalPixel = √(heightPixel² + widthPixels² ) diagonalPixel = √(heightPixel² + widthPixels² )

then you can convert the pixel value to inches thanks to the densityDPI value :然后您可以将像素值转换为英寸,这要归功于 densityDPI 值:

inchDiag = diagonalPixel / densityDPI. inchDiag = 对角像素 / 密度 DPI。

I hope I didn't make mistakes here, be aware that the values you get from the DisplayMetrics class are given by the constructor, it appears (in very rare cases) that they are not well set according to the physical material...我希望我没有在这里犯错,请注意,您从 DisplayMetrics 类中获得的值是由构造函数给出的,看起来(在极少数情况下)它们没有根据物理材料很好地设置......

This will give you the physical screen size but its probably not the better way to manage multiple layouts.这将为您提供物理屏幕大小,但它可能不是管理多个布局的更好方法。 More on this topics 有关此主题的更多信息

Another way:其他方式:

  • Create 2 more folders: values-large + values-xlarge再创建 2 个文件夹:values-large + values-xlarge

  • Put: <string name="screentype">LARGE</string> in values-large folder (strings.xml)将: <string name="screentype">LARGE</string>放在 values-large 文件夹 (strings.xml) 中

  • Put: <string name="screentype">XLARGE</string> in values-xlarge folder (strings.xml)将: <string name="screentype">XLARGE</string>放入 values-xlarge 文件夹 (strings.xml)

  • In code:在代码中:

    String mType = getString(R.string.screentype); String mType = getString(R.string.screentype);

    if (mType != null && mType.equals("LARGE") { if (mType != null && mType.equals("LARGE") {

    // from 4~7 inches // 从 4~7 英寸

    } else if (mType != null && mType.equals("XLARGE") { } else if (mType != null && mType.equals("XLARGE") {

    // from 7~10 inches // 从 7~10 英寸

    } }

Voila!瞧! 😀 This is all you will need to distinguish tablets from phones 😀 这就是区分平板电脑和手机所需的全部内容

1. Helper function to get screen width: 1. 获取屏幕宽度的辅助函数:

private float getScreenWidth() {
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    return Math.min(metrics.widthPixels, metrics.heightPixels) / metrics.density;
}

2. Function to figure out if a device is a tablet 2. 判断设备是否为平板的函数

boolean isTablet() {
    return getScreenWidth() >= 600;
}

3. Finally, if you are looking to perform different operations for different device sizes: 3. 最后,如果您要针对不同的设备尺寸执行不同的操作:

boolean is7InchTablet() {
    return getScreenWidth() >= 600 && getScreenWidth() < 720;
}

boolean is10InchTablet() {
    return getScreenWidth() >= 720;
}

Here some useful kotlin extensions:这里有一些有用的 kotlin 扩展:

    
    fun DisplayMetrics.isTablet(): Boolean {
        return getScreenWidth() >= 600
    }
    
    fun DisplayMetrics.is7InchTablet(): Boolean {
        return getScreenWidth() >= 600 && getScreenWidth() < 720
    }
    
    fun DisplayMetrics.is10InchTablet(): Boolean {
        return getScreenWidth() >= 720
    }
    
    fun DisplayMetrics.getScreenWidth(): Float {
        return widthPixels.coerceAtMost(heightPixels) / density
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM