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

Roo*_*kie 90 android screen android-layout

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

Sea*_*ole 230

您可以使用它DisplayMetrics来获取有关运行应用程序的屏幕的大量信息.

首先,我们创建一个DisplayMetrics指标对象:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Run Code Online (Sandbox Code Playgroud)

从这里,我们可以获得尺寸显示所需的信息:

int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
Run Code Online (Sandbox Code Playgroud)

这将返回宽度和高度的绝对值(以像素为单位),因此Galaxy SIII,Galaxy Nexus等为1280x720.

这通常不会有帮助,因为当我们在Android设备上工作时,我们通常更喜欢使用密度无关的像素,dip.

你得到了density使用屏幕metrics再次,在一个比例系数的装置,它是基于表单的Android设计资源mdpi,hdpi等等. DPI可以扩展

float scaleFactor = metrics.density;
Run Code Online (Sandbox Code Playgroud)

从这个结果,我们可以计算出一定高度或宽度的密度独立像素的数量.

float widthDp = widthPixels / scaleFactor
float heightDp = heightPixels / scaleFactor
Run Code Online (Sandbox Code Playgroud)

您从中获得的结果将帮助您确定与Android配置示例一起使用的屏幕类型,这些示例为您提供每个屏幕大小的相对dp:

  • 320dp:典型的手机屏幕(240x320 ldpi,320x480 mdpi,480x800 hdpi等).
  • 480dp:像Streak(480x800 mdpi)这样的tweener平板电脑.
  • 600dp:7"平板电脑(600x1024 mdpi).
  • 720dp:10英寸平板电脑(720x1280 mdpi,800x1280 mdpi等).

使用上述信息,我们知道如果设备的最小宽度大于600dp,设备是7"平板电脑,如果它大于720dp,设备是10"平板电脑.

我们可以使用类的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
}
Run Code Online (Sandbox Code Playgroud)

但是,这并不总能给你一个完全匹配,特别是当使用模糊的平板电脑时可能会将其密度误认为hdpi,或者可能只有800 x 480像素但仍然在7英寸屏幕上.

除了这些方法之外,如果您需要知道设备的确切尺寸(以英寸为单位),您也可以使用该metrics方法计算每英寸屏幕的像素数.

float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;
Run Code Online (Sandbox Code Playgroud)

您可以使用每英寸设备中有多少像素的知识以及总计的像素数量来计算出设备的英寸数.

float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;
Run Code Online (Sandbox Code Playgroud)

这将以英寸为单位返回设备的高度和宽度.这对于确定它是什么类型的设备并不总是有用的,因为设备的广告尺寸是对角线,我们所拥有的只是高度和宽度.

但是,我们也知道,考虑到三角形的高度和宽度,我们可以使用毕达哥拉斯定理来计算斜边的长度(在这种情况下,屏幕对角线的大小).

//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));
Run Code Online (Sandbox Code Playgroud)

由此,我们可以确定设备是否是平板电脑:

if (diagonalInches >= 10) {
    //Device is a 10" tablet
} 
else if (diagonalInches >= 7) {
    //Device is a 7" tablet
}
Run Code Online (Sandbox Code Playgroud)

这就是你如何计算你正在使用的设备类型.

  • 最后,我从[DeeV的答案](http://stackoverflow.com/a/15133770/56285)中找到了`resources.getConfiguration().smallestScreenWidthDp`,这是唯一一种在纵向和横向上都给出相同值的方法**在我的Nexus 7(600dp)上.它在API级别13中添加. (20认同)
  • 不要使用xdpi或ydpi.这些是可选的,将由制造商设置,而不是计算.它们通常是未使用的或不准确的. (8认同)
  • 精彩提示肖恩.我以前用px检查平板电脑,但在某些情况下有问题(Galaxy 3,4,Note,与Nexus 7相同或更高).现在我也可以查看英寸.以下是许多流行设备屏幕规格的列表:http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density (3认同)
  • 逻辑`if(smallestWidth> 600){/*7"*/}否则if(smallestWidth> 720){/*10"*/}`有缺陷:10"平板电脑被识别为7".我冒昧地解决了这个问题. (3认同)
  • 使用您的方法获取dpi的宽度我会根据方向得到不同的结果.例如,对于Nexus 7:PORTRAIT:smallestWidth = 600.9; LANDSCAPE:smallestWidth = 552.8; 这是什么原因? (2认同)
  • 同意,这个答案是有缺陷的,并且随着轮换的变化会产生不良结果.resources.getConfiguration().smallestScreenWidthDp是要走的路. (2认同)

Dee*_*eeV 32

没有任何说法7"10"AFAIK.在解码位图和诸如此类的东西时,系统使用的屏幕尺寸大致有两种方式.它们都可以在应用程序的Resources对象中找到Context.

第一个是Configuration可以通过获得的对象getContext().getResources().getConfiguration().你有:

Configuration#densityDpi - 呈现的目标屏幕密度,对应于密度资源限定符.

Configuration#screenHeightDp - 可用屏幕空间的当前高度,以dp为单位,对应于屏幕高度资源限定符.

Configuration#screenWidthDp - 可用屏幕空间的当前宽度,以dp为单位,对应于屏幕宽度资源限定符.

Configuration#smallestScreenWidthDp - 应用程序在正常操作中将看到的最小屏幕大小,对应于最小屏幕宽度资源限定符.

就这样,你几乎可以使用屏幕准则搞清楚,如果你的设备是从各自的专业资源文件夹拉(hdpi,xhdpi,large,xlarge,等).

请记住,这些是一些桶:

  • xlarge屏幕至少为960dp x 720dp
  • 大屏幕至少640dp x 480dp
  • 正常屏幕至少为470dp x 320dp
  • 小屏幕至少为426dp x 320dp

  • 320dp:典型的手机屏幕(240x320 ldpi,320x480 mdpi,480x800 hdpi等).

  • 480dp:像Streak(480x800 mdpi)这样的tweener平板电脑.
  • 600dp:7"平板电脑(600x1024 mdpi).
  • 720dp:10英寸平板电脑(720x1280 mdpi,800x1280 mdpi等).

更多信息

第二个是通过DisplayMetrics获得的对象getContext().getResources().getDisplayMetrics().你有:

DisplayMetrics#density - 显示器的逻辑密度.

DisplayMetrics#densityDpi - 屏幕密度以每英寸点数表示.

DisplayMetrics#heightPixels - 显示的绝对高度(以像素为单位).

DisplayMetrics#widthPixels - 显示的绝对宽度(以像素为单位).

DisplayMetrics#xdpi - X维度中每英寸屏幕的精确物理像素数.

DisplayMetrics#ydpi - Y维度中每英寸屏幕的精确物理像素数.

如果您需要精确的屏幕像素数而不是密度,这很方便.但是,重要的是要注意这是屏幕的所有像素.不只是你可以使用的.

  • +1,我用'smallestScreenWidthDp`得到了最好的结果.与其他解决方案不同,它在我的Nexus 7(600dp)*上提供相同的值,无论方向*.作为奖励,它也是最简单的代码! (4认同)

Piy*_*hra 13

将此方法放在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;

    }
Run Code Online (Sandbox Code Playgroud)

通常片剂在6英寸大小后开始.


小智 8

切换纵向与横向时,上述操作并不总是有效.

如果您的目标是API级别13+,则如上所述很简单 - 使用Configuration.smallestScreenWidthDp,然后相应地进行测试:

resources.getConfiguration().smallestScreenWidthDp
Run Code Online (Sandbox Code Playgroud)

否则,如果您能负担得起,请使用以下方法,这是一种非常准确的方法,通过让系统告诉您检测600dp(如6")与720dp(如10"):

1)添加到layout-sw600dp和layout-sw720dp(如果适用,其风景)一个具有正确ID的不可见视图,例如:

对于720,在layout-sw720dp上:

<View android:id="@+id/sw720" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
Run Code Online (Sandbox Code Playgroud)

对于600,在layout-sw600dp上:

<View android:id="@+id/sw600" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 你不需要创建一个单独的布局,我相信你可以根据大小,通过拥有不同的值文件夹,如values-sw600dp等,有一个单独的strings.xml.有一个字符串定义<string name ='screensize' sw600dp文件夹中的> 600dp </ string>等.它甚至不必是字符串,它可以在ints.xml或dimens.xml中. (4认同)

Jas*_*son 7

很棒的信息,正是我所寻找的!但是,在尝试了这一点之后,我发现当使用此处提到的指标时,Nexus 7(2012模型)报告的尺寸为1280x736.我还有一台运行Jelly Bean的摩托罗拉Xoom,它错误地报告了1280x752的分辨率.我偶然发现了这个帖子这里是证实了这一点.基本上,在ICS/JB中,使用上述指标的计算似乎排除了导航栏的尺寸.还有一些研究让我看到了 Frank Nguyen的答案,它使用了不同的方法来提供屏幕的原始(或实际)像素尺寸.我的初步测试显示,来自Frank correclty的以下代码报告了Nexus 7(2012型号runnin JB)和运行JB的Motorola 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();
}
Run Code Online (Sandbox Code Playgroud)