Android11.0 修改系统默认显示大小

这篇具有很好参考价值的文章主要介绍了Android11.0 修改系统默认显示大小。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系统设置中的显示大小调整的就是屏幕密度,调整的越小,屏幕显示的内容就越多。
在系统中都会有定义一个默认的屏幕密度

设置中显示大小相关内容

  • 源码:/packages/apps/Settings/res/xml/display_settings.xml
 <Preference
      android:key="font_size"
      android:title="@string/title_font_size"
      android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
      settings:controller="com.android.settings.display.FontSizePreferenceController" />
      
 <!-- 显示大小设置-->
 <com.android.settings.display.ScreenZoomPreference
      android:key="display_settings_screen_zoom"
      android:title="@string/screen_zoom_title"
      android:fragment="com.android.settings.display.ScreenZoomSettings"/>

  • 源码:/packages/apps/Settings/src/com/android/settings/display/ScreenZoomSettings.java
 @Override
 public void onCreate(@Nullable Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
		
     final DisplayDensityUtils density = new DisplayDensityUtils(getContext());

     final int initialIndex = density.getCurrentIndex();
     if (initialIndex < 0) {
         // Failed to obtain default density, which means we failed to
         // connect to the window manager service. Just use the current
         // density and don't let the user change anything.
         final int densityDpi = getResources().getDisplayMetrics().densityDpi;
         mValues = new int[]{densityDpi};
         mEntries = new String[]{getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
         mInitialIndex = 0;
         mDefaultDensity = densityDpi;
     } else {
         mValues = density.getValues();
         mEntries = density.getEntries();
         mInitialIndex = initialIndex;
         mDefaultDensity = density.getDefaultDensity();
     }

     getActivity().setTitle(R.string.screen_zoom_title);
 }
 
 @Override
 protected Configuration createConfig(Configuration origConfig, int index) {
     // Populate the sample layouts.
     final Configuration config = new Configuration(origConfig);
     config.densityDpi = mValues[index];
     return config;
 }

 /**
  * Persists the selected density and sends a configuration change.
  */
 @Override
 protected void commit() {
     final int densityDpi = mValues[mCurrentIndex];
     if (densityDpi == mDefaultDensity) {
         DisplayDensityConfiguration.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
     } else {
         DisplayDensityConfiguration.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, densityDpi);
     }
 }

密度缩放等级描述"小,默认,大,较大,最大" mEntries和mValues 这些配置是从DisplayDensityUtils 中获取
设置显示大小后调用DisplayDensityConfiguration.setForcedDisplayDensity方法去配置

获取显示大小等级描述

  • 源码:/frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
/**
 * Utility methods for working with display density.
 */
 public class DisplayDensityUtils {
    private static final String LOG_TAG = "DisplayDensityUtils";

    /** Minimum increment between density scales. */
    private static final float MIN_SCALE_INTERVAL = 0.09f;

    /** Minimum density scale. This is available on all devices. */
    private static final float MIN_SCALE = 0.85f;

    /** Maximum density scale. The actual scale used depends on the device. */
    private static final float MAX_SCALE = 1.50f;

    /** Summary used for "default" scale. */
    public static final int SUMMARY_DEFAULT = R.string.screen_zoom_summary_default;

    /** Summary used for "custom" scale. */
    private static final int SUMMARY_CUSTOM = R.string.screen_zoom_summary_custom;
    
	/**
     * Summaries for scales smaller than "default" in order of smallest to
     * largest.
     */
     private static final int[] SUMMARIES_SMALLER = new int[] {
             R.string.screen_zoom_summary_small
     };

    /**
     * Summaries for scales larger than "default" in order of smallest to
     * largest.
     */
     private static final int[] SUMMARIES_LARGER = new int[] {
            R.string.screen_zoom_summary_large,
            R.string.screen_zoom_summary_very_large,
            R.string.screen_zoom_summary_extremely_large,
    };
    
    /**
     * Minimum allowed screen dimension, corresponds to resource qualifiers
     * "small" or "sw320dp". This value must be at least the minimum screen
     * size required by the CDD so that we meet developer expectations.
     */
     private static final int MIN_DIMENSION_DP = 320;

     private final String[] mEntries;
     private final int[] mValues;

     private final int mDefaultDensity;
     private final int mCurrentIndex;

     public DisplayDensityUtils(Context context) {
        // 获取默认的屏幕密度 ro.sf.lcd_density 
        final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity(
                Display.DEFAULT_DISPLAY);
        if (defaultDensity <= 0) {
            mEntries = null;
            mValues = null;
            mDefaultDensity = 0;
            mCurrentIndex = -1;
            return;
        }
        final Resources res = context.getResources();
        final DisplayMetrics metrics = new DisplayMetrics();
        context.getDisplayNoVerify().getRealMetrics(metrics);
        // 当前屏幕使用的密度值
        final int currentDensity = metrics.densityDpi;
        int currentDensityIndex = -1;

        // Compute number of "larger" and "smaller" scales for this display.
        final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
        // DisplayMetrics.DENSITY_MEDIUM = 160
        // MIN_DIMENSION_DP = 320
        final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
        // 屏幕密度最大的缩放是1.5
        final float maxScale = Math.min(MAX_SCALE, maxDensity / (float) defaultDensity);
        // 屏幕密度最小缩放0.85
        final float minScale = MIN_SCALE;
        // 0~3
        final int numLarger = (int) MathUtils.constrain((maxScale - 1) / MIN_SCALE_INTERVAL,
                0, SUMMARIES_LARGER.length);
        // 0~1
        final int numSmaller = (int) MathUtils.constrain((1 - minScale) / MIN_SCALE_INTERVAL,
                0, SUMMARIES_SMALLER.length);
        // {小,默认,大,较大,最大}
        // entries的内容根据numLarger和numSmaller的值来填充
        String[] entries = new String[1 + numSmaller + numLarger];
        int[] values = new int[entries.length];
        int curIndex = 0;
        
        if (numSmaller > 0) {
            final float interval = (1 - minScale) / numSmaller;
            for (int i = numSmaller - 1; i >= 0; i--) {
                // Round down to a multiple of 2 by truncating the low bit.
                final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1;
                if (currentDensity == density) {
                    currentDensityIndex = curIndex;
                }
                entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
                values[curIndex] = density;
                curIndex++;
            }
        }
        // 如果numSmaller为0,entries{默认,..}
        if (currentDensity == defaultDensity) {
            currentDensityIndex = curIndex;
        }
        values[curIndex] = defaultDensity;
        entries[curIndex] = res.getString(SUMMARY_DEFAULT);
        curIndex++;

        if (numLarger > 0) {
            final float interval = (maxScale - 1) / numLarger;
            for (int i = 0; i < numLarger; i++) {
                // Round down to a multiple of 2 by truncating the low bit.
                final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1;
                if (currentDensity == density) {
                    currentDensityIndex = curIndex;
                }
                values[curIndex] = density;
                entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
                curIndex++;
            }
        }
        
        final int displayIndex;
        if (currentDensityIndex >= 0) {
            displayIndex = currentDensityIndex;
        } else {
            // We don't understand the current density. Must have been set by
            // someone else. Make room for another entry...
            int newLength = values.length + 1;
            values = Arrays.copyOf(values, newLength);
            values[curIndex] = currentDensity;

            entries = Arrays.copyOf(entries, newLength);
            entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);

            displayIndex = curIndex;
        }

        mDefaultDensity = defaultDensity;
        mCurrentIndex = displayIndex;
        mEntries = entries;
        mValues = values;
    }

    public String[] getEntries() {
        return mEntries;
    }

    public int[] getValues() {
        return mValues;
    }

首先读取ro.sf.lcd_density获得默认的屏幕密度值,然后通过metrics.densityDpi得到当前使用的屏幕密度值,根据屏幕宽高计算得到密度最大缩放值maxScale(最大为1.5);在通过计算得到numLarger和numSmaller的值然后对entries和values填充内容,得到我们看到的等级描述"小,默认,大,较大,最大"。

修改显示大小重新计算显示配置并保存值

  • 源码:/frameworks/base/packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
 public static void setForcedDisplayDensity(final int displayId, final int density) {
     final int userId = UserHandle.myUserId();
     AsyncTask.execute(
             () -> {
                 try {
                     final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                     wm.setForcedDisplayDensityForUser(displayId, density, userId);
                 } catch (RemoteException exc) {
                     Log.w(LOG_TAG, "Unable to save forced display density setting");
                 }
             });
 }
  • 源码:/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
 @Override
 public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
     if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
             != PackageManager.PERMISSION_GRANTED) {
         throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
     }

     final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
             Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
             null);
     final long ident = Binder.clearCallingIdentity();
     try {
         synchronized (mGlobalLock) {
             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
             if (displayContent != null) {
                 displayContent.setForcedDensity(density, targetUserId);
             }
         }
     } finally {
         Binder.restoreCallingIdentity(ident);
     }
 }
  • 源码:/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
 void setForcedDensity(int density, int userId) {
     final boolean updateCurrent = userId == UserHandle.USER_CURRENT;
     if (mWmService.mCurrentUserId == userId || updateCurrent) {
     	  // 重新赋值
         mBaseDisplayDensity = density;
         // 根据设置的值,重新计算显示配置
         reconfigureDisplayLocked();
     }
     
     if (updateCurrent) {
            // We are applying existing settings so no need to save it again.
         return;
     }

     if (density == mInitialDisplayDensity) {
         density = 0;
     }
     
     mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId);
 }
  • 源码:/frameworks/base/services/core/java/com/android/server/wm/DisplayWindowSettings.java
 void setForcedDensity(DisplayContent displayContent, int density, int userId) {
     if (displayContent.isDefaultDisplay) {
         final String densityString = density == 0 ? "" : Integer.toString(density);
         Settings.Secure.putStringForUser(mService.mContext.getContentResolver(),
                 Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId);
         return;
     }

     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
     final Entry entry = getOrCreateEntry(displayInfo);
     entry.mForcedDensity = density;
     writeSettingsIfNeeded(entry, displayInfo);
 }

根据设置的屏幕密度值重新计算显示配置,最后修改Settings.Secure.DISPLAY_DENSITY_FORCED的值

修改默认显示大小

  • 源码:/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
 private void loadSecureSettings(SQLiteDatabase db) {
     SQLiteStatement stmt = null;
     try {
         stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                 + " VALUES(?,?);");
         ...
         loadStringSetting(stmt, Settings.Secure.DISPLAY_DENSITY_FORCED,
                    R.string.def_display_density_forced);               
  • 源码:/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
 <string name="def_display_density_forced">204</string>

这种修改方式是不改变默认的屏幕密度值ro.sf.lcd_density=240,在此基础上修改屏幕显示的密度。
修改之后使用adb命令查看

C:\Users\dell>adb shell wm density
Physical density: 240
Override density: 204

C:\Users\dell>

开机获取强制显示密度(如果有设置)

  • 源码:/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
 public void displayReady() {
     synchronized (mGlobalLock) {
         if (mMaxUiWidth > 0) {
             mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
         }
         applyForcedPropertiesForDefaultDisplay();
         mAnimator.ready();
         mDisplayReady = true;
        ...
 }
 
 /** The global settings only apply to default display. */
 private boolean applyForcedPropertiesForDefaultDisplay() {
     boolean changed = false;
     final DisplayContent displayContent = getDefaultDisplayContentLocked();
     ...
     // Display density.
     final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId);
     if (density != 0 && density != displayContent.mBaseDisplayDensity) {
         displayContent.mBaseDisplayDensity = density;
         changed = true;
     }
     ...
 }
 
 /**
  * @param userId the ID of the user
  * @return the forced display density for the specified user, if set, or
  *         {@code 0} if not set
  */
 private int getForcedDisplayDensityForUserLocked(int userId) {
     String densityStr = Settings.Secure.getStringForUser(mContext.getContentResolver(),
             Settings.Secure.DISPLAY_DENSITY_FORCED, userId);
     if (densityStr == null || densityStr.length() == 0) {
         // String DENSITY_OVERRIDE = "ro.config.density_override";
         densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
     }
     if (densityStr != null && densityStr.length() > 0) {
         try {
             return Integer.parseInt(densityStr);
         } catch (NumberFormatException ex) {
         }
     }
     return 0;
 }

在WindowManagerService启动之后,调用getForcedDisplayDensityForUserLocked方法获取强制设置的屏幕显示密度,如果有强制设置,将获取到的值赋给mBaseDisplayDensity,系统将以Settings.Secure.DISPLAY_DENSITY_FORCED的值这个密度显示。文章来源地址https://www.toymoban.com/news/detail-491768.html

到了这里,关于Android11.0 修改系统默认显示大小的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android11.0 launcher修改为单层

    OS: RK3568 Android11.0 现在的产品基本都是按照手机样式去做,所以需要把系统默认的Launcher样式,去掉抽屉改为单层显示,也就是把所有的app添加到workspace中。 以下修改是在设备横屏模式下进行 。 1.添加一个宏开关控制Launcher单双层显示 源码: /packages/apps/Launcher3/src/com/android/

    2024年02月08日
    浏览(59)
  • Android 11.0 Camera2 拍照功能默认选前摄像头

     在11.0的系统rom产品开发中,对于app调用系统api来打开摄像头拍照的功能也是常有的功能,而拍照一般是默认打开后置摄像头拍照的,由于 客户的产品特殊要求,需要打开前置摄像头拍照功能,所以需要了解拍照功能的流程,然后修改默认前置摄像头打开拍照功能就可以了

    2024年02月07日
    浏览(53)
  • Android 11.0 systemui锁屏页面时钟显示样式的定制功能实现

      在11.0的系统ROM定制化开发中,在进行systemui的相关开发中,当开机完成后在锁屏页面就会显示时间日期的功能,由于 开发产品的需求要求时间显示周几上午下午接下来就需要对锁屏显示时间日期的相关布局进行分析,然后实现相关功能 效果图如图: SystemUI作为整个系统的基

    2024年02月04日
    浏览(85)
  • Android 11.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

    在11.0的系统rom定制化开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 MtpService负责启动MtpServer和加载存储设备的信

    2024年01月17日
    浏览(79)
  • Android 11.0 系统开机自启动第三方app

      在11.0的系统rom定制化开发中,由于有些第三方app,需要在接收到开机广播后,启动app,但是在10.0以后第三方app就接收不到开机广播了 只有系统app才可以接收到开机广播了,所以在app内通过接收开机广播自启动就没法实现了 这就需要在系统中添加监听开机完成广播的功能,

    2024年02月16日
    浏览(88)
  • Android11.0系统中实现静默安装并启动App以及静默卸载

    本文描述Android11中通过修改系统PackageInstaller应用支持静默安装App,并启动安装的App。 PackageInstaller是系统中专门负责app安装的App,静默安装逻辑添加到此应用中,应用所在路径 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/ 添加SilenceInstallManager,路径为 /frameworks

    2024年02月03日
    浏览(69)
  • Android11.0 生成系统签名.jks文件并对Apk进行签名

    V2签名 对应用手动进行系统签名,需要platform.pk8,platform.x509.pem,signapk.jar这三个文件,应用的AndroidManifest.xml中需要添加 android:sharedUserId=“android.uid.system” ,然后输入以下命令就可得到签名后的apk文件: 如果你的应用 targetSdkVersion=30 ,在7.0以上的设备上安装不成功,会报以

    2024年02月07日
    浏览(56)
  • Android 11.0 系统限制上网系统之iptables用IOemNetd实现创建子链功能的实现

    在11.0的系统rom定制化开发中,对于限制系统上网功能中,需要在system中netd网络这块的产品开发中,会要求设置屏蔽ip地址之内的功能, liunx中iptables命令也是比较重要的,接下来就来在IOemNetd这块实现创建子链的相关功能 在android原生系统中,iptables是在网络过滤包模块非常重

    2024年02月13日
    浏览(98)
  • Android 11.0 系统限制上网系统之iptables用IOemNetd实现删除子链功能的实现

    在11.0的系统rom定制化开发中,对于限制系统上网功能中,在system中netd网络这块的产品开发中,会要求设置屏蔽ip地址之内的功能, liunx中iptables命令也是比较重要的,接下来就来在IOemNetd这块实现删除创建子链的相关功能 在android原生系统中,iptables是在网络过滤包模块非常重

    2024年02月16日
    浏览(50)
  • Android11.0 系统限制上网系统之iptables用IOemNetd实现app上网黑名单的实现

    在11.0的系统rom定制化开发中,对于系统限制网络的使用,在system中netd网络这块的产品需要中,会要求设置屏蔽某个app上网的功能, liunx中iptables命令也是比较重要的,接下来就来在IOemNetd这块实现app上网黑名单的的相关功能,就是在 系统中只能不允许某个app上网,就是除了这

    2024年02月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包