301

我想获取有关设备的信息,以查看它是智能手机还是平板电脑。我该怎么做?

我想根据设备类型显示来自资源的不同网页:

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)
}
4

9 回答 9

828

Android 培训中讨论了这个主题:

使用最小宽度限定符

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

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

因为 sw600dp 限定符只对 android 3.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
}
于 2012-02-16T09:05:47.090 回答
97

我认为平板电脑至少有 6.5 英寸的屏幕。这是根据上面 Nolf 的回答计算它的方法。

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
}
于 2014-07-11T15:15:32.290 回答
40

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

此外,虽然使用屏幕分辨率或资源管理 large vs xlarge,在过去可能是一种有效的方法,新的“移动”设备现在配备了如此大的屏幕和高分辨率,以至于如果你真的希望的话,它们会模糊这条线要了解电话与没有电话功能,以下是“最好的”。

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
            return "Tablet";
        }else{
            return "Mobile";
        }
于 2012-06-14T21:35:30.583 回答
32

我喜欢 Ol_v_er 的解决方案,它很简单,但是,我发现它并不总是那么简单,新设备和显示器不断出现,我想更“细化”地试图找出实际的屏幕尺寸. 我在这里由 John 找到的另一种解决方案使用字符串资源而不是布尔值来指定平板电脑的大小。因此,不要只将 true 放入 /res/values-sw600dp/screen.xml 文件(假设这是您的小型平板电脑的布局),您可以:

<?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 英寸平板电脑的答案也是我一直在寻找的。如果这里的答案不允许您像您希望的那样具体,您可能想检查一下。他很好地解释了如何计算不同的指标来弄清楚你实际处理的是什么。

更新

在查看 Google I/O 2013 应用程序源代码时,我遇到了他们用来识别设备是否是平板电脑的以下内容,所以我想我会添加它。以上为您提供了更多“控制”,但如果您只想知道它是否是平板电脑,以下内容非常简单:

public static boolean isTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout
            & Configuration.SCREENLAYOUT_SIZE_MASK)
            >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
于 2013-08-22T18:17:26.257 回答
11

我在我的所有应用程序中都使用了这种方法,并且它成功地工作:

public static boolean isTablet(Context ctx){    
    return (ctx.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}
于 2014-09-24T23:11:25.077 回答
7

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

    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 
    }
于 2013-05-03T06:25:30.690 回答
5

我发现的最好的选择和更少的干扰,是在你的 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"/>

平板电脑 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()));

希望它对你有用。

于 2014-05-06T00:33:21.320 回答
1

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

有关更多详细信息,请参阅此帖子

于 2013-02-08T07:41:02.053 回答
1

回复:上面关于如何区分电话和非电话的切线:据我所知,只有电话有 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() 出于某种原因返回“GSM”的 phoneType,因此检查电话类型似乎是不可靠的。同样,getNetworkType() 将为处于飞行模式的手机返回 0。事实上,飞行模式也会导致 getLine1Number() 和 getSim* 方法返回 null。但即使在飞行模式下,手机的 IMEI 仍然存在。

于 2014-03-22T23:45:28.287 回答