29

This question is related to Android App: how to read Font Size under Settings? I read the answer of CommonsWare which points to use Settings.System.FONT_SCALE. So I wrote this few lines:

float scale = -66.6f;
try {
    scale = android.provider.Settings.System.getFloat(getContentResolver(),
                                    android.provider.Settings.System.FONT_SCALE);
} catch(SettingNotFoundException e) {
    Log.e(getClass().getSimpleName(), "Error: ", e);
}
Toast.makeText(this, "scale=" + scale, Toast.LENGTH_LONG).show();

My problem is that I always get the SettingNotFoundException I'm using an Android 4.2.2 device. By the way I that code is in an onCreate callback of an Activity.

I also googled for that problem and found about 3 sites which uses the same code. Is some special permission required? I tried also the permission android.permission.WRITE_SETTINGS without success.

rekire
  • 47,260
  • 30
  • 167
  • 264
  • hmm, I am not sure that you need to read this. Doesn't the system do the scaling for you as long as you use sp units ?? – Teovald May 14 '13 at 14:09
  • Well sure but I have some graphical bugs which I need to fix with that scale factor. – rekire May 14 '13 at 14:22

5 Answers5

60

I just found in the source code of Settings.System this function:

/** @hide */
public static void getConfigurationForUser(ContentResolver cr,
                                       Configuration outConfig, int userHandle) {
    outConfig.fontScale = Settings.System.getFloatForUser(
        cr, FONT_SCALE, outConfig.fontScale, userHandle);
    if (outConfig.fontScale < 0) {
        outConfig.fontScale = 1;
    }
}

There is however the FONT_SCALE in usage so I checked for that Configuration class where the documentation points to getResources().getConfiguration(). So I counld fix my code by using:

float scale = getResources().getConfiguration().fontScale;

Since my question was about to calculate the correct font size in pixel here is the way I use it nowerdays in Kotlin:

val Number.dpInPx: Int
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, toFloat(), Resources.getSystem().displayMetrics).toInt()

val Number.spInPx: Int
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP, toFloat(), Resources.getSystem().displayMetrics).toInt()

The usage is:

val textSize = 42.spInPx
val padding = 8.dpInPx
rekire
  • 47,260
  • 30
  • 167
  • 264
6

You can set system font according to font scale.

Example: For huge font scale is 2.0 then you can set as follow.

Configuration config = new Configuration();
config.fontScale = 2.0f;
getResources().getConfiguration().setTo(config);
Hardik Bambhania
  • 1,732
  • 15
  • 25
2

Add "float def" param to the end of the

public static float getFloat(ContentResolver cr, String name, float def)

Example:

scale = android.provider.Settings.System.getFloat(getActivity().getContentResolver(),
                                    android.provider.Settings.System.FONT_SCALE, 1f);
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
Andrej
  • 29
  • 1
0

2023 answer:

This is how I get fontScale using Kotlin:

val fontScale = resources.configuration.fontScale
Caio Mar
  • 2,344
  • 5
  • 31
  • 37
  • Technical not wrong, but the real intent was to get the real pixel dimensions, therefore my `dpInPx` and `spInPx` Kotlin extensions might be more helpful – rekire Jun 11 '23 at 20:19
-2

You could probably use getResources().getDisplayMetrics().scaledDensity - http://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity

FunkTheMonk
  • 10,908
  • 1
  • 31
  • 37