17

One of the device screen properties that Android lets an app query is it's aspect ratio. In the examples that I have seen this property seems to have only two values - long and notlong.

I am trying to reverse engineer the logic being used by Android to classify a device as having one of the two aspect ratios.

To get some official data to work with, I referred to the values provided by the device definitions included in the AVD Manager tool in Android Studio, and combined that with my own calculations: Devices included in AVD Manager

The column "Published Ratio" shows the value extracted from the AVD Manager. Based on these results, I am failing to understand how Nexus 5 and 6 are considered notlong while Galaxy S4 and Galaxy Nexus are considered long.

Ethen Hunt
  • 579
  • 2
  • 4
  • 13
  • the publish ratio result come from which algorithm? If it yours, can you show it? – Sruit A.Suk Feb 16 '15 at 22:20
  • The Published Ratio came from the AVD manager. It is part of the Google provided Android Studio and also part of the Android SDK. – Ethen Hunt Feb 16 '15 at 22:56
  • Here is how to launch AVD Manager - https://db.tt/shvjNGcb and here is how to find out the aspect ratio of an existing device - https://db.tt/74U5kQEh – Ethen Hunt Feb 16 '15 at 22:59

5 Answers5

21
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
float ratio = ((float)metrics.heightPixels / (float)metrics.widthPixels);
Ashish
  • 6,791
  • 3
  • 26
  • 48
VikasGoyal
  • 3,308
  • 1
  • 22
  • 42
5

To find ration in (16:9) you need to find the GCD and then divide both numbers by that.

int gcd(int p, int q) {
    if (q == 0) return p;
    else return gcd(q, p % q);
}

void ratio(int a, int b) {
   final int gcd = gcd(a,b);
   if(a > b) {
       showAnswer(a/gcd, b/gcd);
   } else {
       showAnswer(b/gcd, a/gcd);
   }
}

void showAnswer(int a, int b) {
   System.out.println(a + " " + b);
}

After this just call ratio(1920,1080);

SachinVsSachin
  • 6,401
  • 3
  • 33
  • 39
Patel Pinkal
  • 8,984
  • 4
  • 28
  • 50
  • This does not work every time. I have tried it with some other values but there it Returns a wrong ratio – user12346352 Aug 06 '18 at 08:03
  • @user12346352 May I know which dimension you have checked and what output you get? – Patel Pinkal Aug 06 '18 at 09:56
  • I have tried it with 4619x3464 and also some others with 16:9 aspect Radio but it doesn't work for every one. I think because the gcd is 1 sometimes and than it Returns the wrong result – user12346352 Aug 06 '18 at 11:34
  • @user12346352 4619x3464 this is not an screen size. I have an answer to get the ratio from valid screen display size, As mention in question. This method cannot give a ratio for invalid sizes. – Patel Pinkal Aug 06 '18 at 12:31
  • Oh sry I haven't seen that sry for wasting your time :) – user12346352 Aug 06 '18 at 12:37
  • @PatelPinkal What is the difference between this answer and the others? – HB. Jul 10 '19 at 06:21
  • @HB. Please read my answer again you will find it is done using GCD – Patel Pinkal Jul 10 '19 at 09:21
  • @PatelPinkal So as long as I provided valid screen dimensions, this will provide me with the correct aspect ratio? I tested with a device that I know is 16:9 and I got 16:9 back. – HB. Jul 10 '19 at 09:37
  • Unfortunately this does not work properly for newest generations of devices, e.g IphoneX – Chestera Dec 20 '20 at 09:46
  • @Chestera `How to calculate Android screen aspect ratio` I've been using this for a few months on different Android devices and it's working perfectly. – HB. Oct 26 '21 at 15:39
3

I think i am very much late for this answer but still for the people who want to know, the answer is:

if(screen_width > screen_height) 
{
    aspectRatio = screen_width / screen_height;
} 
else 
{
    aspectRatio = screen_height / screen_width;
}
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
Ashwani
  • 1,294
  • 1
  • 11
  • 24
1

This is an old question, but none of the proposed answers was getting me quite the right ratio. After trying this out, I was able to get the right aspect ratio (e.g., Pixel 3a is 18.5/9 = 2.0555):

Kotlin:

val aspectRatio = window.decorView.height.toFloat() / window.decorView.width.toFloat()

Java:

float aspectRatio = ((float) getWindow().getDecorView().getHeight()) / 
    ((float) getWindow().getDecorView().getWidth())
ConcernedHobbit
  • 764
  • 1
  • 8
  • 17
0

...property seems to have only two values - long and notlong. I am trying to reverse engineer the logic being used by Android to classify a device as having one of the two aspect ratios.

For the record, there's no need to reverse engineer, just see https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/content/res/Configuration.java

        // Is this a long screen?
        if (((longSizeDp*3)/5) >= (shortSizeDp-1)) {
            // Anything wider than WVGA (5:3) is considering to be long.
            screenLayoutLong = true;
        } else {
            screenLayoutLong = false;
        }

So basically Android takes screen sizes in DP and the result is:

  • long - screen with aspect ratio > 1.667 (5:3) - i.e. > WVGA
  • notlong - screen with aspect ratio <= 1.667 (5:3) - i.e. <= WVGA

Example - Nexus 4 - 384 x 640 dp (5:3):
long edge in dp: 640
short edge in dp: 384

Maths:
640 * 3 / 5 = 384
384 >= (384 - 1) -> false -> notlong

dominik
  • 2,404
  • 2
  • 29
  • 33