HI,
Is there a way to detect from a android Tablet and a Mobile phone from code ?
HI,
Is there a way to detect from a android Tablet and a Mobile phone from code ?
I use something like this.
Where 2 assumptions are made.
public static bool IsTablet(){
float ssw;
if(Screen.width>Screen.height){ssw=Screen.width;}else{ssw=Screen.height;}
if(ssw<800) return false;
if(Application.platform==RuntimePlatform.Android || Application.platform==RuntimePlatform.IPhonePlayer){
float screenWidth = Screen.width / Screen.dpi;
float screenHeight = Screen.height / Screen.dpi;
float size = Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
if(size >= 6.5f) return true;
}
return false;
}
Thanks i will test it now on different tablets and mobiles.
Hi, how are you?
Wouldn’t it be enough with the second assumption?
Thank you
Well yes.
But at that time the 1st assumption made more sense.
Ok, works great, thank you!
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:
var aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height)
if (size >= 6.5f && aspectRatio < 2f) return true;
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
private float DeviceDiagonalSizeInInches()
{
float screenWidth = Screen.width / Screen.dpi;
float screenHeight = Screen.height / Screen.dpi;
float diagonalInches =Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
return diagonalInches;
}
public ENUMHERE GetDeviceType()
{
#if UNITY_IOS
bool deviceIsIpad = UnityEngine.iOS.Device.generation.ToString().Contains("iPad");
if (deviceIsIpad)
{
return ENUMHERE.Tablet;
}
bool deviceIsIphone = UnityEngine.iOS.Device.generation.ToString().Contains("iPhone");
if (deviceIsIphone)
{
return ENUMHERE.Phone;
}
#endif
float aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height);
bool isTablet = (DeviceDiagonalSizeInInches() > 6.5f && aspectRatio < 2f);
if (isTablet)
{
return ENUMHERE.Tablet;
}
else
{
return ENUMHERE.Phone;
}
}
Nice work @wahnishjorge25 works perfectly.
So in the end I made it static and with the enums thanks to @wahnishjorge25 it became something like this:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum ENUM_Device_Type
{
Tablet,
Phone
}
public static class DeviceTypeChecker
{
public static bool isTablet;
private static float DeviceDiagonalSizeInInches()
{
float screenWidth = Screen.width / Screen.dpi;
float screenHeight = Screen.height / Screen.dpi;
float diagonalInches = Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
return diagonalInches;
}
public static ENUM_Device_Type GetDeviceType()
{
#if UNITY_IOS
bool deviceIsIpad = UnityEngine.iOS.Device.generation.ToString().Contains("iPad");
if (deviceIsIpad)
{
return ENUM_Device_Type.Tablet;
}
bool deviceIsIphone = UnityEngine.iOS.Device.generation.ToString().Contains("iPhone");
if (deviceIsIphone)
{
return ENUM_Device_Type.Phone;
}
#elif UNITY_ANDROID
float aspectRatio = Mathf.Max(Screen.width, Screen.height) / Mathf.Min(Screen.width, Screen.height);
bool isTablet = (DeviceDiagonalSizeInInches() > 6.5f && aspectRatio < 2f);
if (isTablet)
{
return ENUM_Device_Type.Tablet;
}
else
{
return ENUM_Device_Type.Phone;
}
#endif
}
}
and this way you check it :
if (DeviceTypeChecker.GetDeviceType() == ENUM_Device_Type.Phone)
{
}
Just a minor note that aspectRatio will be of type int. But the check aspectRatio < 2 is still valid.
I ran into a issue where there are 1920 x 1080 android tablets being detected as a phone.
Which models? What screen size do they have?
Can you try this script?
const int SCREENLAYOUT_SIZE_MASK = 0x0000000f;
const int SCREENLAYOUT_SIZE_LARGE = 0x00000003;
private static AndroidJavaObject s_context;
private static AndroidJavaObject GetUnityActivity()
{
if (s_context == null)
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
s_context = jc.GetStatic<AndroidJavaObject>("currentActivity");
}
return s_context;
}
public static boolean IsTablet()
{
AndroidJavaObject context = GetUnityActivity();
int screenLayout = context.Call<AndroidJavaObject>("getResources").Call<int>("getConfiguration");
return ((screenLayout & SCREENLAYOUT_SIZE_MASK) >= SCREENLAYOUT_SIZE_LARGE);
}
s_context is undefined when first used.
Thanks for the note. I just fixed it!
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.
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
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
08-29 14:28:30.949 20228 20268 E Unity : at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
08-29 14:28:30.949 20228 20268 E Unity : at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
08-29 14:28:30.949 20228 20268 E Unity : at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
08-29 14:28:30.949 20228 20268 E Unity : at android.os.Handler.dispatchMessage(Handler.java:102)
08-29 14:28:30.949 20228 20268 E Unity : at android.os.Looper.loopOnce(Looper.java:210)
08-29 14:28:30.949 20228 20268 E Unity : at android.os.Looper.loop(Looper.java:299)
08-29 14:28:30.949 20228 20268 E Unity : at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
08-29 14:28:30.949 20228 20268 E Unity : at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000000000000000000000000000>:0
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