平板电脑或手机 - Android

时间:2011-04-29 13:00:03

标签: android tablet

有没有办法检查用户是使用平板电脑还是手机? 我的倾斜功能和我的新平板电脑(变压器)存在问题

29 个答案:

答案 0 :(得分:115)

如前所述,您不想检查设备是平板电脑还是手机,但您想了解设备的功能,

大多数情况下,平板电脑和手机之间的区别在于屏幕大小,这就是您要使用不同布局文件的原因。这些文件存储在res/layout-<qualifiers>目录中。您可以在directoy res/values-<same qualifiers>中为每个布局创建一个XML文件,并将int / bool / string资源放入其中,以区分您使用的布局。

实施例

文件res/values/screen.xml(假设res/layout/包含手机的布局文件)

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">phone</string>
</resources>


文件res/values-sw600dp/screen.xml(假设res/layout-sw600dp/包含Nexus 7等小型平板电脑的布局文件)

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">7-inch-tablet</string>
</resources>


文件res/values-sw720dp/screen.xml(假设res/layout-sw720dp/包含大型平板电脑的布局文件,例如Nexus 10):

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">10-inch-tablet</string>
</resources>


现在可以通过R.string.screen_type常量访问屏幕类型。

答案 1 :(得分:59)

要检测设备是否为平板电脑,请使用以下代码:

public boolean isTablet(Context context) {
    boolean xlarge = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
    boolean large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
    return (xlarge || large);
}

LARGE和XLARGE屏幕尺寸由制造商根据他们将要使用的眼睛的距离来确定(因此是平板电脑的想法)。

更多信息:http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f

答案 2 :(得分:38)

这篇文章给了我很多帮助,

不幸的是,我没有必要的声誉来评估帮助我的所有答案。

我需要确定我的设备是平板电脑还是手机,我能够实现屏幕逻辑。在我的分析中,平板电脑必须从MDPI开始超过7英寸(Xlarge)。

以下是基于此帖子创建的代码。

/**
 * Checks if the device is a tablet or a phone
 * 
 * @param activityContext
 *            The Activity Context.
 * @return Returns true if the device is a Tablet
 */
public static boolean isTabletDevice(Context activityContext) {
    // Verifies if the Generalized Size of the device is XLARGE to be
    // considered a Tablet
    boolean xlarge = ((activityContext.getResources().getConfiguration().screenLayout & 
                        Configuration.SCREENLAYOUT_SIZE_MASK) == 
                        Configuration.SCREENLAYOUT_SIZE_XLARGE);

    // If XLarge, checks if the Generalized Density is at least MDPI
    // (160dpi)
    if (xlarge) {
        DisplayMetrics metrics = new DisplayMetrics();
        Activity activity = (Activity) activityContext;
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        // MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
        // DENSITY_TV=213, DENSITY_XHIGH=320
        if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
                || metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
                || metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
                || metrics.densityDpi == DisplayMetrics.DENSITY_TV
                || metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {

            // Yes, this is a tablet!
            return true;
        }
    }

    // No, this is not a tablet!
    return false;
}

答案 3 :(得分:12)

为什么不计算屏幕对角线的大小并使用它来决定设备是手机还是平板电脑?

private boolean isTablet()
{
    Display display = getWindowManager().getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    int width = displayMetrics.widthPixels / displayMetrics.densityDpi;
    int height = displayMetrics.heightPixels / displayMetrics.densityDpi;

    double screenDiagonal = Math.sqrt( width * width + height * height );
    return (screenDiagonal >= 9.0 );
}

当然,人们可以争论阈值是否应该在9英寸或更小。

答案 4 :(得分:11)

没有区别。你应该定义你认为不同的东西,然后检查一下。星系标签是手机吗?还是平板电脑?为什么?

您应该定义您要查找的具体功能,并为此编写代码。

看来你正在寻找'倾斜'。我认为这跟加速度计一样(是一个字吗?)。您可以使用以下方法检查设备是否支持它,

public class Accel extends Activity implements SensorListener {
...
  SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
  boolean accelSupported = sensorMgr.registerListener(this,
        SENSOR_ACCELEROMETER,
        SENSOR_DELAY_UI);
...
}

(来自http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/。我还没有测试过它)

答案 5 :(得分:10)

我的假设是,当您定义“移动/电话”时,您希望知道您是否可以在设备上拨打电话,但这些电话无法用于定义为“平板电脑”的内容。验证这一点的方法如下。如果你想知道基于传感器,屏幕尺寸等的东西,那么这实际上是一个不同的问题。

此外,虽然使用屏幕分辨率,或资源管理大与xlarge,可能是一个有效的方法在过去新的“移动”设备现在有这么大的屏幕和高分辨率,他们正在模糊这一行,而如果你真的希望知道电话与没有电话呼叫功能,以下是“最好的”。

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
    return "Tablet";
}else{
    return "Mobile";
}

答案 6 :(得分:6)

基于Robert Dale Johnson III和Helton Isac,我提出了这个代码希望这很有用

public static boolean isTablet(Context context) {
    TelephonyManager manager = 
        (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    if (manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
        //Tablet
        return true;
    } else {
        //Mobile
        return false; 
    }
}

public static boolean isTabletDevice(Context activityContext) {
    // Verifies if the Generalized Size of the device is XLARGE to be
    // considered a Tablet
    boolean xlarge = 
         ((activityContext.getResources().getConfiguration().screenLayout & 
           Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);

    // If XLarge, checks if the Generalized Density is at least MDPI (160dpi)
    if (xlarge) {
        DisplayMetrics metrics = new DisplayMetrics();
        Activity activity = (Activity) activityContext;
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        // MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
        // DENSITY_TV=213, DENSITY_XHIGH=320
        if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
                  || metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
                  || metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM   
                  || metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {

             // Yes, this is a tablet!
             return true;
        }
    }

    // No, this is not a tablet!
    return false;
}

所以在你的代码中创建一个像

这样的过滤器
if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
    //Tablet
} else {
    //Phone
}

答案 7 :(得分:3)

此方法是Google推荐的。我在Google官方Android应用iosched

中看到了此代码
public static boolean isTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

答案 8 :(得分:3)

对于那些想要参考Google的代码来决定哪些设备将使用平板电脑用户界面的用户可参考以下内容:

  // SystemUI (status bar) layout policy
        int shortSizeDp = shortSize
                * DisplayMetrics.DENSITY_DEFAULT
                / DisplayMetrics.DENSITY_DEVICE;

        if (shortSizeDp < 600) {
            // 0-599dp: "phone" UI with a separate status & navigation bar
            mHasSystemNavBar = false;
            mNavigationBarCanMove = true;
        } else if (shortSizeDp < 720) {
            // 600-719dp: "phone" UI with modifications for larger screens
            mHasSystemNavBar = false;
            mNavigationBarCanMove = false;
        } else {
            // 720dp: "tablet" UI with a single combined status & navigation bar
            mHasSystemNavBar = true;
            mNavigationBarCanMove = false;
        }
        }

答案 9 :(得分:2)

无需代码

其他答案列出了以编程方式确定设备是手机还是平板电脑的多种方式。但是,如果您阅读documentation,这不是支持各种屏幕尺寸的推荐方法。

相反,为平板电脑或手机声明不同的资源。为此,我为layoutvalues等添加了其他资源文件夹。

  • 对于Android 3.2(API级别13),请添加sw600dp文件夹。这意味着 s 最强 w 宽度至少为600dp,大约相当于手机/平板电脑的差距。但是,您也可以添加其他尺寸。查看this answer以获取有关如何添加其他布局资源文件的示例。

  • 如果您还支持Android 3.2之前的设备,则需要添加largexlarge个文件夹才能支持平板电脑。 (手机通常为smallnormal。)

以下是为不同的屏幕尺寸添加额外的xml文件后您的资源可能需要的图像。

enter image description here

使用此方法时,系统会为您确定所有内容。您不必担心在运行时使用哪个设备。您只需提供适当的资源,让Android完成所有工作。

备注

  • 您可以使用aliases来避免重复相同的资源文件。

Android文档值得一读

答案 10 :(得分:2)

如果您仅定位API级别&gt; = 13,请尝试

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
欢呼: - )

答案 11 :(得分:2)

在Google IOSched 2017应用source code中,使用了以下方法:

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}

答案 12 :(得分:1)

考虑“新”的受保护目录(例如,值为sw600dp)我根据屏幕'宽度DP创建了此方法:

 public static final int TABLET_MIN_DP_WEIGHT = 450;
 protected static boolean isSmartphoneOrTablet(Activity act){
    DisplayMetrics metrics = new DisplayMetrics();
    act.getWindowManager().getDefaultDisplay().getMetrics(metrics);

    int dpi = 0;
    if (metrics.widthPixels < metrics.heightPixels){
        dpi = (int) (metrics.widthPixels / metrics.density);
    }
    else{
        dpi = (int) (metrics.heightPixels / metrics.density);
    }

    if (dpi < TABLET_MIN_DP_WEIGHT)         return true;
    else                                    return false;
}

在此列表中,您可以找到一些流行设备和平板电脑尺寸的DP:

Wdp / Hdp

GALAXY Nexus:360/567
XOOM:1280/752
GALAXY NOTE:400/615
NEXUS 7:961/528
GALAXY TAB(&gt; 7&amp;&amp;&lt; 10):1280/752
GALAXY S3:360/615

Wdp =宽度dp
Hdp =高度dp

答案 13 :(得分:1)

使用此方法,当设备是平板电脑时返回 true

public boolean isTablet(Context context) {  
    return (context.getResources().getConfiguration().screenLayout   
        & Configuration.SCREENLAYOUT_SIZE_MASK)    
        >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

答案 14 :(得分:1)

如果屏幕尺寸检测未在新设备上返回正确的值,请尝试:

/*
 Returns '1' if device is a tablet
 or '0' if device is not a tablet.
 Returns '-1' if an error occured.
 May require READ_EXTERNAL_STORAGE
 permission.
 */
public static int isTablet()
{
    try
    {
        InputStream ism = Runtime.getRuntime().exec("getprop ro.build.characteristics").getInputStream();
        byte[] bts = new byte[1024];
        ism.read(bts);
        ism.close();

        boolean isTablet = new String(bts).toLowerCase().contains("tablet");
        return isTablet ? 1 : 0;
    }
    catch (Throwable t)
    {t.printStackTrace(); return -1;}
}

在Android 4.2.2上测试过(对不起我的英文。)

答案 15 :(得分:0)

public boolean isTablet() {
        int screenLayout = getResources().getConfiguration().screenLayout;
        return (Build.VERSION.SDK_INT >= 11 &&
                (((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) || 
                 ((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE)));
    }

答案 16 :(得分:0)

在手机和平​​板电脑之间画线越来越难了。例如(截至2015年8月)Samsung Mega 6.3设备从sw600dp文件夹中提取资源 - 因此就Android而言,它是平板电脑。

@Vyshnavi的答案适用于我们测试的所有设备,但不适用于Mega 6.3。

上面的

@Helton Isac回答将Mega 6.3作为手机返回 - 但由于设备仍然从sw600dp获取资源,因此可能会导致其他问题 - 例如,如果您使用的是手机的查看器,而不是平板电脑,那么;结束NPE错误。

最后,似乎有太多条件要检查,我们可能只需要接受一些手机实际上是平板电脑:-P

答案 17 :(得分:0)

我知道这不是您问题的直接答案,但此处的其他答案可以很好地了解如何识别屏幕尺寸。你在问题中写道,你在倾斜方面遇到了问题,这也恰好发生在我身上。

如果您在智能手机上运行陀螺仪(或旋转传感器),根据该设备的默认方向,x轴和y轴的定义可能与平板电脑不同(例如,三星GS2是默认纵向,Samsung GT -7310是默认版本,新版Google Nexus 7是默认版权,虽然它是平板电脑!)。

现在,如果你想使用陀螺仪,你最终可能会得到一个适用于智能手机的工作解决方案,但在一些平板电脑上会出现轴混乱,反之亦然。

如果您使用上述解决方案之一,只使用屏幕尺寸然后应用

SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X, 
    SensorManager.AXIS_Y, outputRotationMatrix);

如果屏幕尺寸较大或尺寸较大,则可以翻转轴,这可能适用于90%的情况,但例如在Nexus 7上会产生问题(因为它具有默认的纵向和大屏幕尺寸) )。

通过将示例中的sceenOrientation设置为nosensor,在API演示附带的RotationVectorSample中提供了解决此问题的最简单方法:

<activity
    ...
    android:screenOrientation="nosensor">
...
</activity>

答案 18 :(得分:0)

为什么要使用它?

Use this method which returns true when the device is a tablet

public boolean isTablet(Context context) {  
return (context.getResources().getConfiguration().screenLayout   
    & Configuration.SCREENLAYOUT_SIZE_MASK)    
    >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

我在上面看到了很多方法。Configuration类在下面得到了正确的答案:

    /**
 * Check if the Configuration's current {@link #screenLayout} is at
 * least the given size.
 *
 * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
 * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
 * {@link #SCREENLAYOUT_SIZE_XLARGE}.
 * @return Returns true if the current screen layout size is at least
 * the given size.
 */
public boolean isLayoutSizeAtLeast(int size) {
    int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
    if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
    return cur >= size;
}

随便打电话:

 getResources().getConfiguration().
 isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);

可以吗?

答案 19 :(得分:0)

我只需要在布局文件中检测智能手机/平板电脑,因为我正在使用导航代码。

我首先要做的是创建一个layout-sw600dp目录,但是它无法正常工作,因为它会在横向模式下在我的诺基亚8上激活,但是屏幕高度太小。

因此,我将目录重命名为layout-sw600dp-h400dp,然后得到了预期的效果。 h-xxxdp参数应取决于要在布局上放置多少内容,因此应取决于应用程序。

答案 20 :(得分:0)

下面的方法是计算设备屏幕的对角线长度,以确定设备是手机还是平板电脑。这种方法的唯一关注点是决定设备是平板电脑的天气的阈值是多少。在下面的示例中,我将其设置为7英寸及以上。

public static boolean isTablet(Activity act)
{
    Display display = act.getWindow().getWindowManager().getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    float width = displayMetrics.widthPixels / displayMetrics.xdpi;
    float height = displayMetrics.heightPixels / displayMetrics.ydpi;

    double screenDiagonal = Math.sqrt( width * width + height * height );
    int inch = (int) (screenDiagonal + 0.5);
    Toast.makeText(act, "inch : "+ inch, Toast.LENGTH_LONG).show();
    return (inch >= 7 );
}

答案 21 :(得分:0)

包管理器中的com.sec.feature.multiwindow.tablet仅适用于平板电脑,com.sec.feature.multiwindow.phone特定于手机。

答案 22 :(得分:0)

这是我使用的方法:

public static boolean isTablet(Context ctx){    
    return = (ctx.getResources().getConfiguration().screenLayout 
    & Configuration.SCREENLAYOUT_SIZE_MASK) 
    >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

使用:

<强>配置。SCREENLAYOUT_SIZE_MASK

<强>配置。SCREENLAYOUT_SIZE_LARGE

这是推荐的方法!

答案 23 :(得分:-1)

我推荐android库'咖啡因'那里包含手机或平板电脑,10英寸〜!

非常容易使用。

图书馆在这里。

https://github.com/ShakeJ/Android-Caffeine-library

并使用

DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);

答案 24 :(得分:-1)

我认为平板电脑的最大和最大宽度为600像素,高度为1.5 所以需要知道屏幕密度和dp中的高度/宽度,
检索值:

DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth(); 
int height = display.getHeight(); 
float density = metrics.density;  
if((width/density>=600 && height/density>=600))
 isTablette = true;
else
 isTablette = false;

答案 25 :(得分:-1)

对我来说,手机和平板电脑之间的区别不在于设备尺寸和/或像素密度,这会随技术和品味而变化,而是与屏幕比率有关。如果我正在显示一个文本屏幕,我需要知道,例如,是否需要15条长线(手机)和20条短线(平板电脑)。对于我的游戏,我使用以下内容估算我的软件将要处理的矩形:

    Rect surfaceRect = getHolder().getSurfaceFrame();
    screenWidth = surfaceRect.width();
    screenHeight = surfaceRect.height();
    screenWidthF = (float) screenWidth;
    screenHeightF = (float) screenHeight;
    widthheightratio = screenWidthF/screenHeightF;
    if(widthheightratio>=1.5) {
        isTablet=false;
    }else {
        isTablet=true;
    }

答案 26 :(得分:-1)

E.g。在手机和平​​板电脑之间有一个重要的区别(至少对我的程序而言)。它是设备的默认方向。手机有纵向,平板电脑 - 风景。并分别确定设备的方法:

private static boolean isLandscapeDefault(Display display) {
    Log.d(TAG, "isTablet()");
    final int width = display.getWidth();
    final int height = display.getHeight();

    switch (display.getOrientation()) {
    case 0: case 2:
        if(width > height) return true;
        break;
    case 1: case 3:
        if(width < height) return true;
        break;
    }
    return false;
}

EDITED: 与Dan Hulme讨论之后改变了方法的名称。

答案 27 :(得分:-1)

请查看以下代码。

private boolean isTabletDevice() {
  if (android.os.Build.VERSION.SDK_INT >= 11) { // honeycomb
    // test screen size, use reflection because isLayoutSizeAtLeast is
    // only available since 11
    Configuration con = getResources().getConfiguration();
    try {
      Method mIsLayoutSizeAtLeast = con.getClass().getMethod(
      "isLayoutSizeAtLeast", int.class);
      boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con,
      0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
      return r;
    } catch (Exception x) {
      x.printStackTrace();
      return false;
    }
  }
  return false;
}

答案 28 :(得分:-3)

我认为这是最诚实的方式。这将检查正在使用的屏幕尺寸:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

祝你好运!