Изменение размера дисплея системы программно 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. Если вы считаете, что это будет полезно, пожалуйста, отметьте это.

Заранее спасибо за помощь!

2 ответа

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

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

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

  1. Читать ZoomScreenSettingsonCreate() и commit().java. Они демонстрируют, как правильно получить и установить значение плотности в каркас.
  2. Читать DisplayDensityUtils.Джава. Он показывает, как использовать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 для большого размера дисплея), подайте его на свойDisplayDensityUtils-подобный класс mValuesмассив, чтобы получить фактическое значение плотности, которое необходимо передать каркасу. Получение индекса плотности тока также применимо к той же концепции.

В декларации, под заявкой: 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.

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

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

В конфигурации

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

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

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

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

Другие вопросы по тегам