Променете системния размер на дисплея програмно 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. Прочетете onCreate() и commit() на ZoomScreenSettings.java. Те демонстрират как правилно да получите и зададете стойността на плътността в рамката.
  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)) метод Използването на този метод е:

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

В Конфигурация

Това включва както зададени от потребителя опции за конфигурация (списък с локали и мащабиране), така и конфигурации на устройства (като режими на въвеждане, размер на екрана и ориентация на екрана >).

Задайте конфигурация с 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