我想了解一种设备的信息,看看它是智能手机还是平板电脑。我该怎么做呢?

我想显示不同的网页资源基于设备的类型:

String s="Debug-infos:";
s += "\n OS Version: " + System.getProperty("os.version") + "(" +    android.os.Build.VERSION.INCREMENTAL + ")";
s += "\n OS API Level: " + android.os.Build.VERSION.SDK;
s += "\n Device: " + android.os.Build.DEVICE;
s += "\n Model (and Product): " + android.os.Build.MODEL + " ("+ android.os.Build.PRODUCT + ")";

然而,这似乎对我的情况毫无用处。


这个解决方案现在对我很有效:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;

if (SharedCode.width > 1023 || SharedCode.height > 1023){
   //code for big screen (like tablet)
}else{
   //code for small screen (like smartphone)
}

这个主题在Android Training中有讨论:

使用最小宽度限定符

如果你阅读了整个主题,他们解释了如何在特定的值文件(如res/values-sw600dp/attrs.xml)中设置布尔值:

<resources>
    <bool name="isTablet">true</bool>
</resources>

因为sw600dp限定符只对android3.2以上的平台有效。如果你想确保这个方法适用于所有平台(3.2之前),在res/values-xlarge文件夹中创建相同的文件:

<resources>
    <bool name="isTablet">true</bool>
</resources>

然后,在“标准”值文件(如res/values/attrs.xml)中,将布尔值设置为false:

<resources>
    <bool name="isTablet">false</bool>
</resources>

然后在你的活动中,你可以得到这个值,并检查你是否在平板电脑大小的设备上运行:

boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
    // do something
} else {
    // do something else
}

我的假设是,当你定义“移动/手机”时,你想知道你是否可以在设备上打电话,而不能在被定义为“平板电脑”的设备上打电话。验证方法如下。如果你想了解传感器、屏幕尺寸等方面的信息,那么这就是一个不同的问题了。

此外,虽然使用屏幕分辨率或资源管理大vs大,但在过去可能是一种有效的方法,现在新的“移动”设备具有如此大的屏幕和高分辨率,它们模糊了这条界限,而如果你真的想知道电话通话与无电话通话功能,下面的方法是“最好的”。

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

我使用的解决方案是定义两个布局。例如,将布局文件夹设置为 layout-sw600dp 我用它来为我的平板电脑用户提供一个菜单按钮,并为手机用户隐藏这个按钮。这样,我(还)不必为我现有的应用程序实现动作栏……

更多细节请看这篇文章。


由于平板电脑通常比智能手机大,而且低分辨率平板电脑的像素可能与高分辨率智能手机相同,解决这个问题的一种方法是计算设备的物理尺寸(而不是分辨率):

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

    float yInches= metrics.heightPixels/metrics.ydpi;
    float xInches= metrics.widthPixels/metrics.xdpi;

   if (yInches> smallestTabletSize|| xInches > smallestTabletSize)
    {
                  //We are on a 
    }

I like Ol_v_er's solution and it's simplicity however, I've found that it's not always that simple, what with new devices and displays constantly coming out, and I want to be a little more "granular" in trying to figure out the actual screen size. One other solution that I found here by John uses a String resource, instead of a boolean, to specify the tablet size. So, instead of just putting true in a /res/values-sw600dp/screen.xml file (assuming this is where your layouts are for small tablets) you would put:

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

参考如下,然后根据结果做你需要做的事情:

String screenType = getResources().getString(R.string.screen_type);
if (screenType.equals("7-inch-tablet")) {
    // do something
} else {
    // do something else
}

Sean O'Toole对检测7英寸和10英寸平板电脑的回答也是我一直在寻找的。如果这里的答案不允许你像你想的那样具体,你可能会想要检查一下。他很好地解释了如何计算不同的度量标准,以弄清楚你实际在处理什么。

更新

在查看谷歌I/O 2013应用程序源代码时,我看到了他们用来识别设备是否是平板电脑的以下内容,所以我想我应该添加它。以上内容让你对它有了更多的“控制”,但如果你只是想知道它是否是平板电脑,下面的步骤相当简单:

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

回复:上面关于如何区分电话和非电话的正题:据我所知,只有电话有15位IMEI(国际移动站设备标识),所以下面的代码将明确区分电话和非电话:

    TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    String deviceInfo = "";
    deviceInfo += manager.getDeviceId(); // the IMEI
    Log.d(TAG, "IMEI or unique ID is " + deviceInfo);

    if (manager.getDeviceId() == null) {
        Log.d(TAG, "This device is NOT a phone");
    } else {
        Log.d(TAG, "This device is a phone.");
    }

我发现在一个Nook模拟器getPhoneType()返回phoneType的“GSM”出于某种原因,所以它似乎检查手机类型是不可靠的。同样,对于处于飞行模式的手机,getNetworkType()将返回0。事实上,飞行模式也会导致getLine1Number()和getSim*方法返回null。但即使在飞行模式下,手机的IMEI仍然存在。


我发现最好的选择和侵入性较小,是在xml中设置一个标记参数,如

电话XML布局

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="phone"/>

Tablet XML布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="tablet">

    ...

</RelativeLayout>

然后在你的活动类中调用这个

View viewPager = findViewById(R.id.pager);
Log.d(getClass().getSimpleName(), String.valueOf(viewPager.getTag()));

希望这对你有用。


我认为平板电脑至少要有6.5英寸的屏幕。这是如何计算它,基于诺尔夫的答案上面。

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

float yInches= metrics.heightPixels/metrics.ydpi;
float xInches= metrics.widthPixels/metrics.xdpi;
double diagonalInches = Math.sqrt(xInches*xInches + yInches*yInches);
if (diagonalInches>=6.5){
    // 6.5inch device or bigger
}else{
    // smaller device
}

我在我所有的应用程序中都使用了这种方法,并且非常成功:

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