I need to record certain metrics for the usage of my app based on font and display size. How can I retrieve the display size under Settings -> Accessibility section programmatically? Font Scale is straight-forward, but there seems to be no way of retrieving the display size.
float fontScale = getResources().getConfiguration().fontScale;
The Android API does not expose this scale factor chosen by the user. However, a similar scale can be obtained by dividing the density DPI (which is scaled based on the user's setting) and DENSITY_DEVICE_STABLE, which gives the required result.
final DisplayMetrics metrics = getResources().getDisplayMetrics();
final int currentDeviceDensity = metrics.densityDpi;
float displayDensityScaleFactor = (float) currentDeviceDensity / DENSITY_DEVICE_STABLE;
So in my case I actually needed to check fontScale and density combined and for that it seems that using val deviceDensity = LocalDensity.current.density - (DENSITY_DEVICE_STABLE / DENSITY_DEFAULT) is better since it provides more range than densityDpi / DENSITY_DEVICE_STABLE.
| Display size | DPI approach | Density approach (mine) |
|---|---|---|
| 1st | 0.85 | -0.025 |
| 2nd | 1.0 | 0.5 |
| 3rd | 1.09 | 0.83 |
| 4th | 1.19 | 1.16 |
| 5th | 1.29 | 1.5 |
Density approach numbers can be easily combined with fontScale. For example in my case I had to check if fontScale per density is higher than 200%. For which I made a function (Compose) to get the scale:
/**
* Gets font scale combined with screen density to check how large is the text compared to default device settings.
* Default device density is divided by default density and by this number current density of the screen is reduced to
*
* Note: Preview cannot load proper [DENSITY_DEVICE_STABLE] value since it is loaded from HW configuration but density
* from LocalDensity is loaded properly thus they cannot be combined. That is why for previous only fontScale is
* returned.
*
* @return font scale for the screen density
*/
@Composable
fun getScreenDensityFontScale(): Float {
val fontScale = LocalDensity.current.fontScale
val isComposePreview = LocalInspectionMode.current
return if (isComposePreview) {
fontScale
} else {
val deviceDensity = LocalDensity.current.density - (DENSITY_DEVICE_STABLE / DENSITY_DEFAULT)
fontScale + deviceDensity
}
}
And I'm checking getScreenDensityFontScale() > 2.0f. For Pixel 7 Pro (emulator) 200% or more font scale can be reached when:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With