Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Detecting Between a tablet and mobile

Discussion in 'Android' started by markpollard1, Nov 11, 2015.

  1. markpollard1

    markpollard1

    Joined:
    Apr 1, 2010
    Posts:
    70
    HI,

    Is there a way to detect from a android Tablet and a Mobile phone from code ?
     
  2. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,366
    I use something like this.

    Where 2 assumptions are made.

    1. If the highest dimension in pixels is less then 800, it is not a tablet.
    2. If it is smaller then 6.5 inches it is not a tablet.

    Code (CSharp):
    1.     public static bool IsTablet(){
    2.    
    3.         float ssw;
    4.         if(Screen.width>Screen.height){ssw=Screen.width;}else{ssw=Screen.height;}
    5.        
    6.         if(ssw<800) return false;
    7.        
    8.          if(Application.platform==RuntimePlatform.Android || Application.platform==RuntimePlatform.IPhonePlayer){
    9.              float screenWidth = Screen.width / Screen.dpi;
    10.              float screenHeight = Screen.height / Screen.dpi;
    11.              float size = Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
    12.              if(size >= 6.5f) return true;
    13.          }
    14.        
    15.         return false;
    16.     }
     
  3. markpollard1

    markpollard1

    Joined:
    Apr 1, 2010
    Posts:
    70
    Thanks i will test it now on different tablets and mobiles.
     
  4. miticatechnology

    miticatechnology

    Joined:
    Oct 30, 2014
    Posts:
    14
    Hi, how are you?

    Wouldn't it be enough with the second assumption?

    Thank you
     
  5. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,366
    Well yes.
    But at that time the 1st assumption made more sense.
     
    twicejiggled likes this.
  6. miticatechnology

    miticatechnology

    Joined:
    Oct 30, 2014
    Posts:
    14
    Ok, works great, thank you!
     
  7. austinborden

    austinborden

    Joined:
    Aug 5, 2016
    Posts:
    24
    Through some beta testing on Android I've found there's at least one phone out there that gets reported as a tablet with this code, the OnePlus GM1913. Its screen is 1080x2340 at 380 dpi. To restrict this a bit more, I added an aspect ratio test. I'm not aware of any tablet that has an aspect ratio greater than 2:1. Modify the snippet above like this:

    Code (CSharp):
    1. var aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height)
    2. if (size >= 6.5f && aspectRatio < 2f) return true;
     
  8. wahnishjorge25

    wahnishjorge25

    Joined:
    Jan 24, 2015
    Posts:
    13
    Thanks for that @austinborden, iphone 8 plus not working for me hehe, so I added a iOS if for that.

    I have a enum for the types so for other developers I put ENUMHERE so you can change it to the name you want

    Code (CSharp):
    1. private float DeviceDiagonalSizeInInches()
    2. {
    3.     float screenWidth = Screen.width / Screen.dpi;
    4.     float screenHeight = Screen.height / Screen.dpi;
    5.     float diagonalInches =Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
    6.  
    7.     return diagonalInches;
    8. }
    9.  
    10. public ENUMHERE GetDeviceType()
    11. {
    12. #if UNITY_IOS
    13.     bool deviceIsIpad = UnityEngine.iOS.Device.generation.ToString().Contains("iPad");
    14.             if (deviceIsIpad)
    15.             {
    16.                 return ENUMHERE.Tablet;
    17.             }
    18.  
    19.             bool deviceIsIphone = UnityEngine.iOS.Device.generation.ToString().Contains("iPhone");
    20.             if (deviceIsIphone)
    21.             {
    22.                 return ENUMHERE.Phone;
    23.             }
    24. #endif
    25.          
    26.             float aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height);
    27.             bool isTablet = (DeviceDiagonalSizeInInches() > 6.5f && aspectRatio < 2f);
    28.  
    29.             if (isTablet)
    30.             {
    31.                 return ENUMHERE.Tablet;
    32.             }
    33.             else
    34.             {
    35.                 return ENUMHERE.Phone;
    36.             }
    37.         }
     
  9. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,627
  10. alipaknahad

    alipaknahad

    Joined:
    Dec 22, 2020
    Posts:
    10
    So in the end I made it static and with the enums thanks to @wahnishjorge25 it became something like this:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6.  
    7. public enum ENUM_Device_Type
    8. {
    9.     Tablet,
    10.     Phone
    11. }
    12.  
    13. public static class DeviceTypeChecker
    14. {
    15.     public static bool isTablet;
    16.  
    17.     private static float DeviceDiagonalSizeInInches()
    18.     {
    19.         float screenWidth = Screen.width / Screen.dpi;
    20.         float screenHeight = Screen.height / Screen.dpi;
    21.         float diagonalInches = Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
    22.  
    23.         return diagonalInches;
    24.     }
    25.  
    26.     public static ENUM_Device_Type GetDeviceType()
    27.     {
    28. #if UNITY_IOS
    29.     bool deviceIsIpad = UnityEngine.iOS.Device.generation.ToString().Contains("iPad");
    30.             if (deviceIsIpad)
    31.             {
    32.                 return ENUM_Device_Type.Tablet;
    33.             }
    34.             bool deviceIsIphone = UnityEngine.iOS.Device.generation.ToString().Contains("iPhone");
    35.             if (deviceIsIphone)
    36.             {
    37.                 return ENUM_Device_Type.Phone;
    38.             }
    39. #elif UNITY_ANDROID
    40.  
    41.         float aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height);
    42.         bool isTablet = (DeviceDiagonalSizeInInches() > 6.5f && aspectRatio < 2f);
    43.  
    44.         if (isTablet)
    45.         {
    46.             return ENUM_Device_Type.Tablet;
    47.         }
    48.         else
    49.         {
    50.             return ENUM_Device_Type.Phone;
    51.         }
    52. #endif
    53.     }
    54. }
    and this way you check it :

    Code (CSharp):
    1.             if (DeviceTypeChecker.GetDeviceType() == ENUM_Device_Type.Phone)
    2.             {
    3.              
    4.             }
     
    phong-genix, Dongmany, ATate and 9 others like this.
  11. nick-morhun

    nick-morhun

    Joined:
    May 12, 2015
    Posts:
    47
    Just a minor note that aspectRatio will be of type int. But the check aspectRatio < 2 is still valid.
     
  12. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,627
    I ran into a issue where there are 1920 x 1080 android tablets being detected as a phone.
     
  13. nick-morhun

    nick-morhun

    Joined:
    May 12, 2015
    Posts:
    47
    Which models? What screen size do they have?
     
  14. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,828
    Can you try this script?

    Code (CSharp):
    1. const int SCREENLAYOUT_SIZE_MASK = 0x0000000f;
    2. const int SCREENLAYOUT_SIZE_LARGE = 0x00000003;
    3. private static AndroidJavaObject s_context;
    4.  
    5. private static AndroidJavaObject GetUnityActivity()
    6.         {
    7.             if (s_context == null)
    8.             {
    9.                 AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    10.                 s_context = jc.GetStatic<AndroidJavaObject>("currentActivity");
    11.             }
    12.             return s_context;
    13.         }
    14.  
    15.  
    16. public static boolean IsTablet()
    17. {
    18.     AndroidJavaObject context = GetUnityActivity();
    19.     int screenLayout = context.Call<AndroidJavaObject>("getResources").Call<int>("getConfiguration");
    20.     return ((screenLayout & SCREENLAYOUT_SIZE_MASK) >= SCREENLAYOUT_SIZE_LARGE);
    21. }
     
    Last edited: Mar 15, 2023
  15. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,595

    s_context is undefined when first used.
     
  16. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,828
    Thanks for the note. I just fixed it!
     
  17. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    67
    Kind of surprising unity doesn't have some built in function for this, I am dealing with the same problem, it is easy to check ipad vs iphone but android tablet is difficult. Im confused why the aspect ration value threshold is 2, why wouldn't it be lower?
    Aren't there going to be instances when this doesn't work? Why not just check the screen diagnal, I am probably missing something.
     
  18. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    67
    Wouldnt it be better so use this info?
     

    Attached Files:

  19. marcozakaria

    marcozakaria

    Joined:
    Sep 17, 2017
    Posts:
    22
    Code (CSharp):
    1. 08-29 14:28:30.949 20228 20268 E Unity   : AndroidJavaException: java.lang.NoSuchFieldError: no "Landroid/app/Activity;" field "currentActivity" in class "Lcom/unity3d/player/UnityPlayer;" or its superclasses
    2. 08-29 14:28:30.949 20228 20268 E Unity   : java.lang.NoSuchFieldError: no "Landroid/app/Activity;" field "currentActivity" in class "Lcom/unity3d/player/UnityPlayer;" or its superclasses
    3. 08-29 14:28:30.949 20228 20268 E Unity   :      at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
    4. 08-29 14:28:30.949 20228 20268 E Unity   :      at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
    5. 08-29 14:28:30.949 20228 20268 E Unity   :      at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
    6. 08-29 14:28:30.949 20228 20268 E Unity   :      at android.os.Handler.dispatchMessage(Handler.java:102)
    7. 08-29 14:28:30.949 20228 20268 E Unity   :      at android.os.Looper.loopOnce(Looper.java:210)
    8. 08-29 14:28:30.949 20228 20268 E Unity   :      at android.os.Looper.loop(Looper.java:299)
    9. 08-29 14:28:30.949 20228 20268 E Unity   :      at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
    10. 08-29 14:28:30.949 20228 20268 E Unity   :   at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000000000000000000000000000>:0
    11. 08-29 14:28:30.949 20228 20268 E Unity   :   at UnityEngine.AndroidJNISafe.GetFieldID (System.IntPtr clazz, System.String name, System.String sig) [0x00000] in <00000000000000000000000000000000>:0
    Hello @Voxel-Busters when i run code it gives this error on device do you know why ?
    Unity 2021.3.7 , my device is on android 12