Please test this Scaling/DPI function(s)

Monkey Targets Forums/Android/Please test this Scaling/DPI function(s)

Supertino(Posted 2013) [#1]
continuing from http://www.monkeycoder.co.nz/Community/posts.php?topic=4958

I put this together as I needed approximate values (mm and inches converted to pixels) to size buttons and other elements independent of screen size,dpi and resolution.

I wont go into why Android does not support or return these values nativley just to say it doesn't... well it can but 90% of devices will return incorrect values. You can read the original thread to get a fuller story.

This demo *should* draw a 1 Inch and a 10mm square on any Android device, best have a ruler or tape to measure. Depending on the device and because of the way these are calculated based on a bucket DPI value (not the actual DPI value of the device) there will be a variance of a mm or two on the 1 Inch square. It will also guess the form factor of your device.

If you guys could let me know how you get on with your devices that would be handy. The emulator is useless for this test, it needs real devices.

save as "dpi.java"
class DPIStuff {
	public static int GetAndroid_Dpi() {
		DisplayMetrics metrics = new DisplayMetrics();
		BBAndroidGame._androidGame._activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		int dpi= metrics.densityDpi;
		return dpi;
	}
	
	public static float GetAndroid_LogicalDpi() {
		DisplayMetrics metrics = new DisplayMetrics();
		BBAndroidGame._androidGame._activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		float ldpi= metrics.density;
		return ldpi;
	}
	
	public static int GetAndroid_heightPixels() {
		DisplayMetrics metrics = new DisplayMetrics();
		BBAndroidGame._androidGame._activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		int height= metrics.heightPixels ;
		return height;
	}
	
	public static int GetAndroid_widthPixels() {
		DisplayMetrics metrics = new DisplayMetrics();
		BBAndroidGame._androidGame._activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		int width= metrics.widthPixels ;
		return width;
	}
}


save this as "androiddpi.monkey"

Import "dpi.java"

Extern
	#If TARGET="android"
		Function GetAndroid_DPI:Float() = "DPIStuff.GetAndroid_Dpi"
		Function GetAndroid_DPI_Scale_Value:Float() = "DPIStuff.GetAndroid_LogicalDpi"
		Function GetAndroid_Height_Pixels:Int() = "DPIStuff.GetAndroid_heightPixels"
		Function GetAndroid_Width_Pixels:Int() = "DPIStuff.GetAndroid_widthPixels"
	#Endif
Public

' Return the bucket density value - 120,160,213,240,320,480
Function GetAndroid_Bucket_DPI:Int()
	Return (160 * GetAndroid_DPI_Scale_Value)
End Function

' Return the bucket density type
Function GetAndroid_Bucket_Name:String()
	Select GetAndroid_Bucket_DPI
		Case 120; Return "ldpi"
		Case 160; Return "mdpi"
		Case 213; Return "tvdpi"
		Case 240; Return "hdpi"
		Case 320; Return "xhdpi"
		Case 480; Return "xxhdpi"
	End Select
End Function

' Return the 'density independent pixel' size
' e.g, on the base 160 1px is 1.0 on a 240 1px is 1.5
Function GetAndroid_dp_Unit:Float()
	Return (1.0 * GetAndroid_DPI_Scale_Value)
End Function

' Converts a mm value in a px value
Function GetAndroid_mm_To_px:Float(mm:Float)
	Local Inch_To_mm:Float = 25.4
	Local One_mm:Float = (GetAndroid_Bucket_DPI / Inch_To_mm)
	Return Ceil(One_mm * mm)
End Function

' Converts pixel value into mm value
Function GetAndroid_px_To_mm:Float(px:Float)
	Return Ceil(px / GetAndroid_mm_To_px(1.0))
End Function

' Calculate the approximate height of the screen in Inches
' Expect an up to 10% over/under
Function GetAndroid_Screen_Width_Inches:Float()
	Local Inch_To_mm:Float = 25.4
	Return (GetAndroid_px_To_mm(GetAndroid_Width_Pixels) / Inch_To_mm)
End Function

' Calcuate the approximate width of the screen in Inches
' Expect an up to 10% over/under
Function GetAndroid_Screen_Height_Inches:Float()
	Local Inch_To_mm:Float = 25.4
	Return (GetAndroid_px_To_mm(GetAndroid_Height_Pixels) / Inch_To_mm)
End Function

' Calculate the Approximate Diagonal of the screen to return a device form factor
' Expect an up to 10% over/under
Function GetAndroid_Device_Type:String()
	Local w:Float = (GetAndroid_Screen_Width_Inches * GetAndroid_Screen_Width_Inches)
	Local h:Float = (GetAndroid_Screen_Height_Inches * GetAndroid_Screen_Height_Inches)
	Local Diagonal:Float = Sqrt(w + h) + 0.75 ' add 0.75 for rounding up, seems to be a sweet spot
	If Diagonal < 5.0
		Return "Phone"
	ElseIf Diagonal < 7.0
		Return "Phablet"
	ElseIf Diagonal < 8.0
		Return "7' Tablet"
	ElseIf Diagonal < 10.0
		Return "8' Tablet"
	Else
		Return "10' Tablet"
	End If		
End Function


save this as what ever (main.monkey)
Import mojo
Import monkey
Import androiddpi

Function Main(); New project; End
Class project Extends App

	' ----------------------------------------------------------- OnCreate -
	Method OnCreate(); SetUpdateRate 30; End Method
	
	' ----------------------------------------------------------- OnUpdate -
	Method OnUpdate(); End Method

	' ----------------------------------------------------------- OnRender -
	Method OnRender()
		Cls(155, 155, 155)
		
		' values returned from the google API
		DrawText "Android DPI                   : " + GetAndroid_DPI, 10, 10
		DrawText "Android DPI Scale             : " + GetAndroid_DPI_Scale_Value, 10, 22
		DrawText "Android Width Px              : " + GetAndroid_Width_Pixels, 10, 34
		DrawText "Android Height Px             : " + GetAndroid_Height_Pixels, 10, 46
		
		' my values
		DrawText "Android DPI Bucket            : " + GetAndroid_Bucket_DPI + " (" + GetAndroid_Bucket_Name + ")", 10, 58
		DrawText "Android dp pixel size         : " + GetAndroid_dp_Unit, 10, 70
		DrawText "Android 1 mm is               : " + GetAndroid_mm_To_px(1) + " pixels", 10, 82
		DrawText "Android 1 inch is             : " + GetAndroid_mm_To_px(25.4) + " pixels", 10, 94
		DrawText "Approx screen width Inches    : " + GetAndroid_Screen_Width_Inches, 10, 106
		DrawText "Approx screen height Inches   : " + GetAndroid_Screen_Height_Inches, 10, 118
		DrawText "Device form factor (Probably) : " + GetAndroid_Device_Type, 10, 130
		
		' 1 inch square
		DrawRect 10, 156, GetAndroid_mm_To_px(25.4), GetAndroid_mm_To_px(25.4)
		DrawText "1 inch sq", 20, 166
		
		' 10mm square
		DrawRect 10, 166 + GetAndroid_mm_To_px(25.4), GetAndroid_mm_To_px(10), GetAndroid_mm_To_px(10)
		DrawText "10 mm sq", 20, 176 + GetAndroid_mm_To_px(25.4)
		
	End Method
	
End Class



Midimaster(Posted 2013) [#2]
Allow me you offer a ready to install apk of this test here:

http://www.midimaster.de/temp/TestDpi.apk



I did a little change: Adding a 'Quit' functionality:

before:
Method OnUpdate(); End Method


after:
Method OnUpdate()
	If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""
End Method


Result of my test:
The big square is 22mm on my Samsung GT-S5300


Supertino(Posted 2013) [#3]
22mm not too bad for a phone as low spec as the GT-S5300.

For reference here are my results for the 1 Inch square (rounded up)

Nexus 7 = 27mm
S3 Mini = 25mm


Fred(Posted 2013) [#4]
Great!, Thanks both of you, I just got a GS4 and can't read my debug DrawText anymore ! :)

*Galaxy S4 GT-I9505
big square: 27.5 mm
small: 11 mm
*Galaxy Note 10.1 GT-N8010
big: 27 mm
small: 10.5 mm


Xaron(Posted 2013) [#5]
Sony Xperia S
Big: 24mm
Small: 9.5mm


Supertino(Posted 2013) [#6]
ah good to see it more or less works.


Panda(Posted 2013) [#7]
HTC One
Big and small both spot on.

Useful code, cheers!


Grey Alien(Posted 2014) [#8]
Just wanna bump this to check that no one has found any problems with it since?

I just want to check DPI and resolution to guess if it's a tablet or phone (I'll choose some size where I say over that is a tablet).

Then I can alter the button size/layout for phone/tablet interfaces.

Thx!


Midimaster(Posted 2014) [#9]
I use these java functions to guess the size and the resolution of the device in my score-trainer app and never heard about any problems from users....


Grey Alien(Posted 2014) [#10]
OK great thx. How many users to you have?


Midimaster(Posted 2014) [#11]
roundabout 30.000


Grey Alien(Posted 2014) [#12]
OK great, sounds like a good test then!


Grey Alien(Posted 2014) [#13]
@Therevills Have you added this to diddy btw?


Supertino(Posted 2014) [#14]
I have had a few new devices since I posted this, here are my values

MotoG
Big = 25mm
Small = 10mm
Reports as Phone

Galaxy Tab 3 8"
Big = 27mm
Small = 11mm
Reports as 7" Tablet

Galaxy S4 mini
Big = 22mm
Small = 9mm
Reports as Phablet

Dimensions of the squares are rather good but the form factor guessing is off and might need some tweeking.


Sensei(Posted 2014) [#15]
This is fantastic stuff guys!