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


93

是否可以通过编程方式找到应用程序安装的设备是7英寸平板电脑还是10英寸平板电脑?


例如:layout-sw600dp查找最小宽度尺寸为600dp。
新秀

我了解这一点,但是您以编程方式寻找什么?
Geobits,

我需要以编程方式获取这些设备..因为有些属性我无法在xml中定义..这些属性是在代码本身中定义的..因此,如果我简单地放置代码,它将应用于所有设备..但是我不要那个..
新秀

@Raghav您是否尝试过使用显示矩阵来获取屏幕的大小,然后可以进行比较。虽然它不是一种干净的方法,但是您可以使用。
PiyushMishra

你可以让你的屏幕尺寸,并从那里工作了... stackoverflow.com/questions/1016896/...
拉吉

Answers:


234

您可以使用DisplayMetrics获取有关运行您的应用程序的屏幕的全部信息。

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

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

由此,我们可以获得调整显示器尺寸所需的信息:

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

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

通常,这本身并没有帮助,因为当我们在Android设备上工作时,我们通常更喜欢使用密度无关的像素(dip)。

你得到了density使用屏幕metrics再次,在设备,它是基于比例因子的形式Android设计资源mdpihdpi等等。 DPI秤

float scaleFactor = metrics.density;

根据此结果,我们可以计算出一定高度或宽度下密度独立像素的数量。

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

从中获得的结果将帮助您结合使用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”。

我们可以使用class 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
}

但是,这并不总是能为您提供完全匹配的结果,尤其是在使用晦涩的平板电脑时,可能会错误地将其密度错误表示为hdpi,或者可能只有800 x 480像素而仍在7英寸的屏幕上。

除了这些方法之外,如果您需要了解设备的确切尺寸(以英寸为单位),也可以使用该metrics方法计算每英寸屏幕上的像素数,从而得出结果。

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

您可以使用有关设备每英寸多少个像素以及像素总数的知识来得出设备多少英寸。

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

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

但是,我们也知道给定三角形的高度和宽度,我们可以使用勾股定理确定斜边的长度(在这种情况下,为屏幕对角线的大小)。

//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));

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

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

这就是您计算要使用哪种设备的方式。


3
极好的提示肖恩。我曾经用px来检查平板电脑,但是在某些情况下会出现问题(Galaxy 3、4,注意,px等于或大于Nexus 7)。现在我也可以检查英寸。以下是许多受欢迎的设备屏幕规格的列表:en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes 2013年

8
不要使用xdpi或ydpi。这些是可选的,将由制造商设置,而不是计算得出的。它们通常是未使用的或不准确的。
sturrockad 2013年

2
使用您的方法以dpi为单位获得宽度,我会根据方向得到不同的结果。例如Nexus 7:肖像:smallestWidth = 600.9;景观:minimumWidth = 552.8; 是什么原因呢?
Christopher Masser

3
逻辑if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }有缺陷:10英寸平板电脑被识别为7英寸。我自由地解决了这个问题。
约尼克,

21
最后,我去与resources.getConfiguration().smallestScreenWidthDp来自DeeV的答案是,赋予的唯一方法在纵向和横向相同的值 在我的Nexus 7(宽度为600 dp)。这是在API级别13加入
Jonik

32

没什么可说的7"10"AFAIK。大致有两种方法可以获取系统在解码位图时使用的屏幕尺寸和其他功能。它们都可以在中找到的应用程序Resources对象中找到Context

第一个是Configuration可以通过获取的对象getContext().getResources().getConfiguration()。其中包含:

Configuration#densityDpi -渲染到的目标屏幕密度,对应于密度资源限定符。

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

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

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

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

请记住,以下是其中一些:

  • 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维度上的确切物理像素。

如果您需要屏幕的准确像素数而不是密度,这将很方便。但是,请务必注意,这是屏幕的所有像素。不仅限于您。


4
+1,我得到了最好的结果smallestScreenWidthDp。与其他解决方案不同,无论方向如何,它在Nexus 7(600dp)上都具有相同的值。另外,它也是最简单的代码!
Jonik 2013年

1
我认为这仍然是最好的方法,因为它应该与资源路径上的sw ??? dp表示法相匹配。一致性很重要。
lilbyrdie's 2016年

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;

    }

通常,平板电脑会在6英寸大小后开始。


8

切换人像和风景时,上述方法并不总是有效。

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

resources.getConfiguration().smallestScreenWidthDp

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

1)将带有正确ID的不可见视图添加到layout-sw600dp和layout-sw720dp(如果适用,还包括其风景),例如:

对于720,在layout-sw720dp上:

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

对于600,在layout-sw600dp上:

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

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

4
您不需要创建单独的布局,我相信您可以通过具有不同的value文件夹(例如values-sw600dp等)来基于大小创建单独的strings.xml。具有定义的字符串<string name ='screensize' > sw600dp文件夹中的> 600dp </ string>等。它甚至不必是字符串,可以在ints.xml或dimens.xml中。
ajacian81

7

很棒的信息,正是我想要的!但是,在尝试了此方法后,我发现使用此处提到的指标时,Nexus 7(2012年型号)报告的尺寸为1280x736。我也有一个运行Jelly Bean的Motorola Xoom,它错误地报告了1280x752的分辨率。我在这里偶然发现了证实这一点的帖子。基本上,在ICS / JB中,使用上述指标的计算似乎排除了导航栏的尺寸。更多的研究使我想到了 弗兰克·阮(Frank Nguyen)的答案,答案使用了不同的方法,可以为您提供屏幕的原始(或实际)像素尺寸。我的初步测试表明,Frank correclty的以下代码报告了Nexus 7(2012年型号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();
}

3

我有两个分辨率相同的android设备

Device1->分辨率480x800对角线屏幕尺寸-> 4.7英寸

Device2->分辨率480x800对角线屏幕尺寸-> 4.0英寸

它提供两个设备的对角线屏幕尺寸-> 5.8

解决您的问题的方法是..

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

在这里查看详细信息 ..


2

Android 通过四种通用尺寸来指定屏幕尺寸的方式是:smallnormallargexlarge

虽然Android 文档指出不推荐使用大小组

...不建议使用这些尺寸组,而是采用一种新技术来根据可用的屏幕宽度来管理屏幕尺寸。如果您正在开发Android 3.2及更高版本,请参阅[声明Android 3.2的平板电脑布局](hdpi(高)〜240dpi)以获取更多信息。

通常,size qualifier 大号指定7“平板电脑。xlarge size限定符指定10”平板电脑:

在此处输入图片说明

关于触发大小限定符的好处是,您可以保证您的资产和代码在要使用的资产或要激活的代码路径上达成一致。

要在代码中检索大小限定符,请进行以下调用:

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

2

您可以使用以下方法来获取以英寸为单位的屏幕尺寸,基于此,您只需检查设备是哪台平板电脑或手机即可。

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

2

我将值存储在values文件夹中,该屏幕显示的屏幕为7英寸或10 inc,但我们可以使用values文件夹对任何设备进行此操作。

例如,为不同2设备创建不同2值文件夹。但是这取决于要求。


1

您必须使用DisplayMetrics类提供的数据进行一些计算。

您具有heightPixel和widthPixels(以像素为单位的屏幕分辨率)

您需要对角线,因为“​​英寸屏幕尺寸”总是描述对角线长度。您可以以像素为单位获得屏幕对角线(使用pythagore)

对角线像素=√(高度像素2 +宽度像素2)

那么您可以通过densityDPI值将像素值转换为英寸:

inchDiag =对角像素/密度DPI。

我希望我不会在这里犯错,请注意,您从DisplayMetrics类获取的值是由构造函数提供的,在极少数情况下,根据物理材料,它们的设置似乎不正确...

这将为您提供物理屏幕尺寸,但可能不是管理多种布局的更好方法。有关此主题的更多信息


1

其他方式:

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

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

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

  • 在代码中:

    字符串mType = getString(R.string.screentype);

    如果(mType!= null && mType.equals(“ LARGE”){

    // 4〜7英寸

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

    // 7〜10英寸

    }


1

瞧!to这就是您需要将平板电脑与手机区分开来的全部内容

1. Helper函数获取屏幕宽度:

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

2.判断设备是否为平板电脑的功能

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

3.最后,如果要对不同的设备大小执行不同的操作:

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

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

0

这里是一些有用的kotlin扩展:


    fun DisplayMetrics.isTablet(): Boolean {
        return screenWith() >= 600
    }

    fun DisplayMetrics.is7InchTablet(): Boolean {
        return screenWith() >= 600 && screenWith() < 720
    }

    fun DisplayMetrics.is10InchTablet(): Boolean {
        return screenWith() >= 720
    }

    fun DisplayMetrics.screenWith(): Float {
        return widthPixels.coerceAtMost(heightPixels) / density
    }

这样可行!但是,你应该使用正确的DisplayMetrics,例如ResourcesContextresources.displayMetrics.isTablet() 或者WindowManager其存储在Activityval displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.