Detect 7 inch and 10 inch tablet programmatically

AndroidAndroid LayoutScreen

Android Problem Overview


Is there a way to programmatically find whether the device the app is installed on is a 7 inch tablet or a 10 inch tablet?

Android Solutions


Solution 1 - Android

You can use the DisplayMetrics to get a whole bunch of information about the screen that your app is running on.

First, we create a DisplayMetrics metrics object:

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

From this, we can get the information required to size the display:

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

This will return the absolute value of the width and the height in pixels, so 1280x720 for the Galaxy SIII, the Galaxy Nexus etc.

This isn't usually helpful on its own, as when we're working on Android devices, we usually prefer to work in density independent pixels, dip.

You get the density of the screen using metrics again, in the form of a scale factor for the device, which is based on the Android Design Resources for mdpi, hdpi etc. DPI scales

float scaleFactor = metrics.density;

From this result, we can calculate the amount of density independent pixels there are for a certain height or width.

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

The result you get from this will help you decide what type of screen you are working with in conjunction with the Android Configuration examples, which give you the relative dp for each screen size:

> - 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc). > - 480dp: a tweener tablet like the Streak (480x800 mdpi). > - 600dp: a 7” tablet (600x1024 mdpi). > - 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).

Using the above information, we know that if the smallest-width of the device is greater than 600dp, the device is a 7" tablet, if it's greater than 720dp, the device is a 10" tablet.

We can work out the smallest width using the min function of Math class, passing in the heightDp and the widthDp to return the smallestWidth.

float smallestWidth = Math.min(widthDp, heightDp);

if (smallestWidth > 720) {
    //Device is a 10" tablet
} 
else if (smallestWidth > 600) {
    //Device is a 7" tablet
}

However, this doesn't always give you an exact match, especially when working with obscure tablets that might be misrepresenting their density as hdpi when it isn't, or that might only be 800 x 480 pixels yet still be on a 7" screen.

Further to these methods, if you ever need to know the exact dimensions of a device in inches, you can work that out too, using the metrics method for how many pixels there are per inch of the screen.

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

You can use the knowledge of how many pixels are in each inch of device and the amount of pixels in total to work out how many inches the device is.

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

This will return the height and width of the device in inches. This again isn't always that helpful for determining what type of device it is, as the advertised size of a device is the diagonal, all we have is the height and the width.

However, we also know that given the height of a triangle and the width, we can use the Pythagorean theorem to work out the length of the hypotenuse (In this case, the size of the screen diagonal).

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

From this, we can work out whether the device is a tablet or not:

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

And that's how you calculate what kind of device you're working with.

Solution 2 - Android

There's nothing that says 7" or 10" AFAIK. There are roughly two ways do get screen dimensions that the system uses when decoding bitmaps and whatnot. They're both found in the application's Resources object found in the Context.

The first is the Configuration object which can be obtained by getContext().getResources().getConfiguration(). In it you have:

Configuration#densityDpi - The target screen density being rendered to, corresponding to density resource qualifier.

Configuration#screenHeightDp - The current height of the available screen space, in dp units, corresponding to screen height resource qualifier.

Configuration#screenWidthDp - The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.

Configuration#smallestScreenWidthDp - The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

With that, you can pretty much use the screen guidelines to figure out if your device is pulling from the respective specialized resource folders (hdpi, xhdpi, large, xlarge, etc.).

Remember, these are some of the buckets:

  • xlarge screens are at least 960dp x 720dp

  • large screens are at least 640dp x 480dp

  • normal screens are at least 470dp x 320dp

  • small screens are at least 426dp x 320dp

  • 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).

  • 480dp: a tweener tablet like the Streak (480x800 mdpi).

  • 600dp: a 7” tablet (600x1024 mdpi).

  • 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).

More info

The second is the DisplayMetrics object obtained by getContext().getResources().getDisplayMetrics(). In that you have:

DisplayMetrics#density - The logical density of the display.

DisplayMetrics#densityDpi - The screen density expressed as dots-per-inch.

DisplayMetrics#heightPixels - The absolute height of the display in pixels.

DisplayMetrics#widthPixels - The absolute width of the display in pixels.

DisplayMetrics#xdpi - The exact physical pixels per inch of the screen in the X dimension.

DisplayMetrics#ydpi - The exact physical pixels per inch of the screen in the Y dimension.

This is handy if you need exact pixel count of the screen rather than density. However, it is important to note that this is all the screen's pixels. Not just the ones available to you.

Solution 3 - Android

place this method in onResume() and can check.

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;

	}

generally tablets starts after 6 inch size.

Solution 4 - Android

The above doesn't always work when switching portrait vs. landscape.

If you are targeting API level 13+, it is easy as described above -- use Configuration.smallestScreenWidthDp, then test accordingly:

resources.getConfiguration().smallestScreenWidthDp

Otherwise, if you can afford this, use the following method which is a very accurate approach to detect 600dp (like 6") vs. 720dp (like 10") by letting the system tell you:

  1. Add to layout-sw600dp and layout-sw720dp (and if applicable its landscape) an invisible view with proper ID, for example:

For 720, on layout-sw720dp:

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

For 600, on layout-sw600dp:

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

2) Then on the code, for example, the Activity, test accordingly:

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

Solution 5 - Android

Great information, just what I was looking for! However, after trying this out I found that when using the metrics mentioned here the Nexus 7 (2012 model) reports having dimensions 1280x736. I also have a Motorola Xoom running Jelly Bean and it incorrectly reports a resolution of 1280x752. I stumbled upon this post here that confirms this. Basically, in ICS/JB the calculations using the metrics mentioned above appear to exclude the dimensions of the Navigation Bar. Some more research led me to Frank Nguyen's answer here that uses different methods that will give you the raw (or real) pixel dimensions of the screen. My initial testing has shown that the following code from Frank correclty reports the dimensions on the Nexus 7 (2012 model runnin JB) and my Motorola Xoom running JB:

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

Solution 6 - Android

I have two android device with same resolution

Device1 -> resolution 480x800 diagonal screen size -> 4.7 inches

Device2 -> resolution 480x800 diagonal screen size -> 4.0 inches

It gives both device diagonal screen size -> 5.8

the solution to your problem is..

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

see details here..

Solution 7 - Android

They way that Android specifies screen sizes is through four generalized sizes: small, normal, large and xlarge.

While the Android documentation states that the size groups are deprecated

> ... these size groups are deprecated in favor of a new technique for managing screen sizes based on the > available screen width. If you're developing for Android 3.2 and > greater, see [Declaring Tablet Layouts for Android 3.2]( hdpi (high) ~240dpi) for more > information.

Generally the size qualifier large specifies a 7" tablet. And a size qualifier of xlarge specifies a 10" tablet:

enter image description here

The nice thing about triggering on the the size qualifier, is that you can guarantee that your assets and code are in agreement on which asset to use or code path to activate.

To retrieve the size qualifier in code make the following calls:

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

Solution 8 - Android

You can use the below method to get the screen size in inches, based on that simply you can check which tablet or phone the device is.

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

Solution 9 - Android

I was storing a value in values folder that gives me screen is 7 inch or 10 inc but we can do it for any device using values folder.

like create different-2 values folder for different-2 devices. But this thing depends upon the requirement.

Solution 10 - Android

You'll have to make a little bit of computation using data given by the DisplayMetrics class.

You have heightPixel and widthPixels ( the screen resolution in pixels)

You need the diagonal since the 'inch screen size' always describe the diagonal length. You can get the screen diagonal in pixel (using pythagore)

diagonalPixel = √(heightPixel² + widthPixels² )

then you can convert the pixel value to inches thanks to the densityDPI value :

inchDiag = diagonalPixel / densityDPI.

I hope I didn't make mistakes here, be aware that the values you get from the DisplayMetrics class are given by the constructor, it appears (in very rare cases) that they are not well set according to the physical material...

This will give you the physical screen size but its probably not the better way to manage multiple layouts. More on this topics

Solution 11 - Android

Another way:

  • Create 2 more folders: values-large + values-xlarge

  • Put: <string name="screentype">LARGE</string> in values-large folder (strings.xml)

  • Put: <string name="screentype">XLARGE</string> in values-xlarge folder (strings.xml)

  • In code:

    String mType = getString(R.string.screentype);

    if (mType != null && mType.equals("LARGE") {

    // from 4~7 inches

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

    // from 7~10 inches

    }

Solution 12 - Android

Voila!  This is all you will need to distinguish tablets from phones

1. Helper function to get screen width:

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

2. Function to figure out if a device is a tablet

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

3. Finally, if you are looking to perform different operations for different device sizes:

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

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

Solution 13 - Android

Here some useful kotlin extensions:

    
    fun DisplayMetrics.isTablet(): Boolean {
        return getScreenWidth() >= 600
    }
    
    fun DisplayMetrics.is7InchTablet(): Boolean {
        return getScreenWidth() >= 600 && getScreenWidth() < 720
    }
    
    fun DisplayMetrics.is10InchTablet(): Boolean {
        return getScreenWidth() >= 720
    }
    
    fun DisplayMetrics.getScreenWidth(): Float {
        return widthPixels.coerceAtMost(heightPixels) / density
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRookieView Question on Stackoverflow
Solution 1 - AndroidSean O'TooleView Answer on Stackoverflow
Solution 2 - AndroidDeeVView Answer on Stackoverflow
Solution 3 - AndroidPiyushMishraView Answer on Stackoverflow
Solution 4 - AndroidCEOView Answer on Stackoverflow
Solution 5 - AndroidJasonView Answer on Stackoverflow
Solution 6 - AndroidZar E AhmerView Answer on Stackoverflow
Solution 7 - AndroidJadeView Answer on Stackoverflow
Solution 8 - AndroidAshish RajvanshiView Answer on Stackoverflow
Solution 9 - Androidsharma_kunalView Answer on Stackoverflow
Solution 10 - AndroidGuianView Answer on Stackoverflow
Solution 11 - AndroidFrank NguyenView Answer on Stackoverflow
Solution 12 - AndroidSagarView Answer on Stackoverflow
Solution 13 - AndroidDanimateView Answer on Stackoverflow