정상에서 IT를 외치다

[Android, Device Height] Android P 이후 디바이스 높이 가져오기 본문

안드로이드

[Android, Device Height] Android P 이후 디바이스 높이 가져오기

Black-Jin 2019. 9. 3. 19:15
반응형

안녕하세요. 블랙진입니다.


Android 9(Pie, API 레벨 28) 이후 나온 스마트폰에서 높이 값을 가져오는 코드에 대한 필자가 겪은 이슈 내용을 포스팅 하고자 합니다. 먼저 그동안 디바이스의 높이를 가져올 때 어떤 코드를 사용해 가져오셨나요? 아마 제 포스팅에 있는 방법과 같이 아래 코드를 사용해 높이 값을 가져왔을 겁니다.



Device Width, Height


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

int deviceWidth = displayMetrics.widthPixels;
int deviceHeight = displayMetrics.heightPixels;


여기서 getMetrics() 사용해 디바이스의 높이값을 가져왔을 경우 status bar의 높이까지 포함된 값이 리턴됩니다. (만일 소프트 네비게이션 바가 있다면 이 값은 포함되지 않습니다.) 이를 그림으로 좀 더 자세히 보겠습니다.



안드로이드 스튜디오에서 Nexus 6P 예물레이터의 모습입니다. 해상도는 1440 x 2560 이므로 가로와 세로는 각각 1440px, 2560px 이 됩니다. 여기서 getMetrics()를 이용해 높이값을 가져오면 하단 소프트 네비게이션 바의 크기를 제외한 2392px 즉 status bar의 높이가 포함된 값이 리턴됩니다.



하지만 Anroid P 이상부터는 동작이 조금 다르게 됩니다!




안드로이드 스튜디오에서 Pixel 3 XL 에물레이터의 모습입니다. 해상도는 1440 x 2960으로 getMetrics()를 사용해 높이값을 가져오면 status bar의 높이가 포함되지 않은 값이 리턴됩니다. 필자의 생각으로는 안드로이드 P 이상 부터는 display cutouts가 추가되면서 값이 다르게 받아와 지는 것 같습니다. 특히 status Bar에 카메라가 달린 폰에서만 위와 같이 적용되는 것을 확인했습니다.


우리는 디바이스의 높이값을 가져와 화면 비율에 맞게 UI를 처리해야 되는 작업을 해야될 때가 있습니다. 그런데! device height 값이 안드로이드 기종에 따라 다르게 오다니 어떻게 해야 될까요??



getRealMetrics() 를 사용하자!


디바이스의 실재 해상도를 가져올 수 있는 함수인 getRealMetrics()를 사용하면 문제를 해결할 수 있습니다.


DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);

int realDeviceWidth = displayMetrics.widthPixels;
int realDeviceHeight = displayMetrics.heightPixels;


인터넷에서 디바이스 높이를 검색하면 getMetrics()를 사용해 가져오는 코드가 많습니다. 하지만 Android P에 대응하여 높이값을 가져오기 위해서는 getRealMetrics()를 사용해야 정확하게 처리할 수 있습니다.



 정리


getMetrics() : status bar에 카메라가 달린 폰과 아닌 폰에서 가져오는 높이 값이 다르다.


getRealMetrics() : status bar에 카메라가 달린 폰과 아닌 폰 상관없이 디바이스의 실재 해상도 값을 리턴합니다. 이 값에서 상태바와 소프트 네이게이션 바의 높이를 필요에 따라 빼서 사용하면 되겠습니다.




참고 코드


상태바와 소프트 네비게이션 바 높이를 가져올 수 있는 코드


status bar height


int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) statusBarHeight = getResources().getDimensionPixelSize(resourceId);


navigation bar height


int bottomBarHeight = 0;
int resourceIdBottom = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceIdBottom > 0) bottomBarHeight = getResources().getDimensionPixelSize(resourceIdBottom);


여기서 네비게이션 바는 하드웨어 바와 소프트웨어 바를 사용하는 두 기기를 분리해서 작업해 주시는게 좋습니다. 실제 디바이스의 높이랑 보여지는 화면의 높이에서 하드웨어 바를 사용하는 디바이스 화면에서는 네이게이션바를 제외시켜 줘야 겠죠?



Show Navigation Bar Bool


int id = getResources().getIdentifier("config_showNavigationBar", "bool", "android");
boolean useSoftNavigation = getResources().getBoolean(id);


소프트웨어 네비게이션 바를 사용한다면 true 리턴하고 반대면 false 리턴합니다.

반응형
Comments