Изменение размера дисплея системы программно 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, хотя он не так уж элегантен.
Основные справочные файлы исходного кода:
- ScreenZoomSettings.java (https://github.com/aosp-mirror/platform_packages_apps_settings/blob/master/src/com/android/settings/display/ScreenZoomSettings.java)
- DisplayDensityUtils.java (http://androidxref.com/9.0.0_r3/xref/frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java)
- WindowManagerGlobal.java (http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/WindowManagerGlobal.java)
И выполните следующие шаги, чтобы получить требуемый контроль:
- Читать
ZoomScreenSettings
onCreate() и commit().java. Они демонстрируют, как правильно получить и установить значение плотности в каркас. - Читать
DisplayDensityUtils
.Джава. Он показывает, как использоватьWindowManagerService
для контроля плотности системы. Потому что мы не можем получить экземплярDisplayDensityUtils
через отражение нам нужно понять, какиеWindowManagerService
методы используются. - Используйте отражение, чтобы получить
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
- Установите или получите значение плотности с помощью
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.
Я надеюсь, что это поможет вам.