Изменить размер системного дисплея программно Android N

Предыстория: Android N поставляется с функцией изменения системы Display Size в настройках в дополнение к ранее существовавшей функции изменения Font Size.

Изменить размер экрана:

введите здесь описание изображения

Источник изображения: pcmag.com

Вопрос:

Если приложение имеет разрешение android.permission.WRITE_SETTINGS на изменение настроек, существуют способы программно изменить размер системного шрифта, как указано в Как программно изменить настройки шрифта Устройства: стиль шрифта и размер шрифта?. Однако я не смог найти способ программно изменить размер экрана. Является ли это возможным?

Что я пробовал?

Я проверил возможные варианты в списке Settings.System удобные функции для программного изменения настроек.

Обновление:

Я открыл запрос функции для того же здесь: https://code.google.com/p/android/issues/detail?id=214124 . Если вы считаете, что это будет полезно, поставьте звездочку.


person Shobhit Puri    schedule 23.06.2016    source источник


Ответы (3)


Просто поделитесь моим подходом к решению этого требования. Я добиваюсь этой функции, используя грязный метод отражения Java, хотя он не так элегантен.

Основные файлы исходного кода ссылки:

И выполните следующие шаги, после чего вы сможете получить требуемый контроль:

  1. Прочтите ZoomScreenSettings.java onCreate() и commit(). Они демонстрируют, как правильно получить и установить значение плотности в фреймворке.
  2. Прочитайте DisplayDensityUtils.java. Он показывает, как использовать WindowManagerService для управления плотностью системы. Поскольку мы не можем получить экземпляр DisplayDensityUtils через отражение, нам нужно понять, какие методы WindowManagerService используются.
  3. Используйте отражение, чтобы получить экземпляр WindowManagerService, и напишите в своем проекте класс, подобный DisplayDensityUtils.
// Where wm is short for window manager
val wmGlobalClz = Class.forName("android.view.WindowManagerGlobal")
val getWmServiceMethod = wmGlobalClz.getDeclaredMethod("getWindowManagerService")
val wmService = getWmServiceMethod.invoke(wmGlobalClz)

val wmInterfaceClz = Class.forName("android.view.IWindowManager")

// Now, we already have the ability to do many things we want.
// For instance, to get the default density value.
val getInitialDisplayDensityMethod = wmInterfaceClz.getDeclaredMethod(
        "getInitialDisplayDensity", 
        Integer.TYPE
)
val defaultDensity = getInitialDisplayDensityMethod.invoke(
        wmService,
        Display.DEFAULT_DISPLAY
) as Int

  1. Установите или получите значение плотности с помощью вашего DisplayDensityUtils-подобного класса. Стоит только упомянуть, что если вы хотите передать значение индекса (например, 2 для большого размера экрана), пожалуйста, передайте его массиву mValues вашего DisplayDensityUtils-подобного класса, чтобы получить фактическое значение плотности, которое является правильным для передачи. к каркасу. Получение индекса плотности тока также использует ту же концепцию.
person jxsun    schedule 14.02.2020
comment
Для этого требуется разрешение WRITE_SECURE_SETTINGS, и его может предоставить только adb: C - person Pablo Cegarra; 20.06.2021

В манифесте под приложением: android:configChanges="density"

В действии/приложении:

public void adjustDisplayScale(Configuration configuration) {
    if (configuration != null) {
        Log.d("TAG", "adjustDisplayScale: " + configuration.densityDpi);
        if(configuration.densityDpi >= 485) //for 6 inch device OR for 538 ppi
            configuration.densityDpi = 500; //decrease "display size" by ~30
        else if(configuration.densityDpi >= 300) //for 5.5 inch device OR for 432 ppi
            configuration.densityDpi = 400; //decrease "display size" by ~30
        else if(configuration.densityDpi >= 100) //for 4 inch device OR for 233 ppi
            configuration.densityDpi = 200; //decrease "display size" by ~30
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);
        metrics.scaledDensity = configuration.densityDpi * metrics.density;
        this.getResources().updateConfiguration(configuration, metrics);
    }
}

Назовите его сразу после super.onCreate(..):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    adjustDisplayScale( getResources().getConfiguration());

Это установит размер дисплея между настройками «Меньший» и «Маленький» для «Размер дисплея», отменяя любые настройки размера дисплея, установленные пользователем. Он самонастраивается правильно для 4-дюймовых, 5,5-дюймовых, 6-дюймовых устройств и т. д., но я уверен, что есть лучший способ, чем использование этих операторов if.

person FEAR X    schedule 22.07.2018

При ссылке на Settings.System есть [putConfiguration(ContentResolver cr, Configuration config)]( https://developer.android.com/reference/android/provider/Settings.System.html#putConfiguration(android.content.ContentResolver, android.content.res.Configuration)) Использование этого метода:

Удобная функция для записи пакета настроек, связанных с конфигурацией, из объекта Configuration.

В разделе Конфигурация.

Сюда входят как параметры конфигурации, указанные пользователем (список языков и масштабирование), так и конфигурации устройства (например, режимы ввода, размер экрана и ориентация экрана).

Установите конфигурацию со значениями SCREENLAYOUT_SIZE_MASK для размера экрана. Это:

Биты SCREENLAYOUT_SIZE_MASK определяют общий размер экрана. Это может быть один из SCREENLAYOUT_SIZE_SMALL, SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_LARGE или SCREENLAYOUT_SIZE_XLARGE.

Я надеюсь, что это поможет вам.

person pRaNaY    schedule 24.06.2016
comment
@alanv Спасибо, что изучили это. Не похоже, что это работает. Не могли бы вы указать, что Проект Android с открытым исходным кодом — средство отслеживания проблем это правильное место, чтобы открыть запрос функции для того же или нам нужно запросить его где-то еще? Спасибо pRaNay за попытку помочь. К сожалению, похоже, это не работает. - person Shobhit Puri; 26.06.2016