【Kotlin/Android Studio】画面(スクリーン)の横幅を取得する方法!デバイスサイズ

この記事からわかること

  • Android Studio/Kotlin画面(スクリーン)のサイズ取得するには?
  • デバイスサイズを識別する
  • 横幅縦幅
  • APIによるコードの違い
  • pxdpiでの取得
  • SizeResolutionDensityとは?
  • DisplayMetricsクラスWindowMetricsクラスの使い方
  • getSystemServiceメソッドWINDOW_SERVICEWindowManager

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Androidの画面サイズ情報

AndroidやiOSなどのモバイル端末のディスプレイにはサイズを表す単位や言葉(ピクセルやdpi、解像度など)が多く存在します。使用する端末によってサイズや解像度は大きく異なるので小さい端末でUIが大きく崩れてしまうなんてことはよくあります。これを起こさないためにそれぞれの違いをまずははっきりさせておきます。

AndroidではAndroid Studioのエミュレーターを管理しているDevice Managerから機種を追加しようとした際に機種やサイズなどの一覧を確認できます。ここでは「Size」、「Resolution」、「Density」の3つの値が確認できます。

【Kotlin/Android Studio】画面(スクリーン)の横幅を取得する方法!デバイスサイズ

それぞれが表しているのは以下の通りです。詳しくは後述していきます。

インチ:inch

インチとは日本で言うところのセンチメートルやミリメートルなどといった長さを表す指標のことです。「1インチ = 2.54cm」と決められています。

Androidデバイスで「6.0インチ」などと謳われているのはディスプレイの対角線の長さのことです。

ピクセル:pixel

ピクセルとは日本語で言うところの「画素」のことで、デジタル画面や画像などを表示する際の最小表示単位です。ピクセルは色のついた点のようなものでその点がたくさん集まって画面を表示しています。もちろん数が多いほどより綺麗に繊細に色味を表現できることになります。

AndroidではResolution(解像度)として「横方向のピクセル × 縦方向のピクセル」形式で表現されています。

ピクセル密度:Density

Density(デンシティ)とはピクセル密度のことです。ピクセル密度とはディスプレイ上の1インチあたりのピクセル数を示す指標であり、ピクセル密度が高いほど画面がより鮮明になります。

ピクセル密度は「dots per inch(dpi)」(1インチあたりにいくつピクセル(ドット)があるかを示す指標)という単位で表現されることがあります。ピクセル密度は物理サイズ(インチ)とディスプレイの解像度(横方向と縦方向のピクセル数)に基づいて計算可能です。

dpiとppiの違い

ピクセルに関連した解像度を表す言葉に「pixels per inch(ppi)」という単位もあります。ppiとの違いは使用される機械から見た場合の呼び方の違いであり、「1インチあたりにいくつピクセル(ドット)があるかを示す指標」と言う意味合いでは同義になります。

Androidではピクセル密度をdpiを使って表現しているようです。ちなみにAndroidアプリ開発ではピクセルでの指定はできるだけ非推奨となっています。これは同じピクセルサイズ(解像度)のデバイスがあってもピクセル密度が異なる場合、ディスプレイ表示に差が生まれてしまうからです。

また画像を格納する際もピクセル密度を意識する必要があります。

Androidでコードから取得できるデバイス情報

Androidではコードからアプリを実行しているデバイスの画面サイズなどの情報を取得することが可能になっています。API30以降からWindowMetricsクラスというのが追加されたのでAPI30以降と以前ではAPIレベルによってコードが少し異なります。

使用するクラス

また今回はデモとして「Pixel 3a」の情報(以下)を取得していきます。

API30以上:WindowMetricsクラス

公式リファレンス:WindowMetricsクラス

API30以上でコードからデバイスの画面情報を取得するにはWindowMetricsクラスを使用します。WindowMetricsクラスgetSystemServiceメソッドの引数にWINDOW_SERVICEを渡してWindowManagerクラスを取得し、取得したWindowManagerからcurrentWindowMetrics(getCurrentWindowMetrics)を使用して取得します。

val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val windowMetrics = windowManager.currentWindowMetrics

解像度を取得する

解像度を取得したい場合はまずWindowMetricsクラスのbounds(getBounds)を取得します。boundsは日本語で「境界」の意味です。

取得したboundswidthメソッドとheightメソッドからデバイスのpx単位の大きさを取得できます。

val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val windowMetrics = windowManager.currentWindowMetrics
val bounds = windowMetrics.bounds
var screenWidth = bounds.width()
val screenHeight = bounds.height()

print(screenWidth.toString())  // 1080
print(screenHeight.toString()) // 2220

ピクセル密度:Density(dpi)を取得する

ピクセル密度:Densityを取得するためにはまずresources.displayMetrics.densityから論理密度を取得します。これはt密度独立ピクセル単位のスケーリング係数として計算された値であり、160dpiの画面で密度値が1になります。今回は440dpiなので440 / 160 = 2.75となります。

val density = resources.displayMetrics.density
print(density) // 2.75

dpiで取得するには取得した論理密度をデバイスの大きさから割ればdpiでの大きさを取得できます。

val bounds = windowManager.currentWindowMetrics.bounds
val density = resources.displayMetrics.density
var screenWidthDpi = bounds.width()/density
var screenHeightDpi = bounds.Height()/density

print(screenWidthDpi.toString())  // 392.72726
print(screenHeightDpi.toString()) // 807.2727

API29以下:DisplayMetrics

公式リファレンス:DisplayMetrics

API29以下ではAPI1から追加されているDisplayMetricsクラスのみを使用します。

DisplayMetricsクラスのみでデバイスの画面サイズを取得するにはgetSystemServiceメソッドの引数にWINDOW_SERVICEを渡してWindowManagerクラスを取得する流れは変わりません。次にDisplayMetricsをインスタンス化してwindowManagergetMetricsメソッドを使用してセットします。

val windowManager = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics) // ちなみにここが非推奨になっている?
val screenWidth = displayMetrics.widthPixels
val screenHeight = displayMetrics.heightPixels

print(screenWidth.toString())  // 1080
print(screenHeight.toString()) // 2154

あとはwidthPixelsheightPixelsメソッドからデバイスのpx単位の大きさを取得できます。高さのみ微妙に誤差が生じていました。

ピクセル密度:Density(dpi)を取得する

ピクセル密度:Density(dpi)を取得するのは簡単でxdpiプロパティまたはydpiプロパティを使用します。やはり先ほどと少し誤差が生まれる(こちらのが端数のない数値?)ようです。

screenWidthDpi = displayMetrics.xdpi 
screenHeightDpi = displayMetrics.ydpi

print(screenWidthDpi.toString())  // 440 
print(screenHeightDpi.toString()) // 440

WindowManager

公式リファレンス:WindowManager

WindowManagerクラスはウィンドウ(画面上の表示領域)の管理と操作を担当するシステムサービスです。

おまけ:APIでコードを分岐させる

今まではActivityに記述するコードでしたがFragment用のコードも載せておきます。といっても違いはContextの取得方法だけですが。またついでにAPIレベルを識別してコードを分岐させるようにsてあります。

おすすめ記事:【Kotlin/Android Studio】コードからAPI(OS)レベルを取得して分岐する方法!Build.VERSION.SDK_INT

val context:Context = requireContext()
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
var screenWidth = 0f
// Android10 (29) と Android11以降 (30)で分岐
if(Build.VERSION.SDK_INT <= 29){
    val displayMetrics = DisplayMetrics()
    windowManager.defaultDisplay.getMetrics(displayMetrics) 
    screenWidth = displayMetrics.widthPixels
}else if(Build.VERSION.SDK_INT >= 30){
    val bounds = windowManager.currentWindowMetrics.bounds
    screenWidth = bounds.width
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index