当前位置:   article > 正文

Android 11 系统修改第三方应用的DPI_android 设置某个应用的dpi

android 设置某个应用的dpi

【问题描述】

使用浏览器访问某些网页布局不正确

【问题分析】

首先,这个网页不允许缩放,无法通过手动修改网页比例解决。

通过adb, wm density修改全局屏幕密度,能够让网页显示正常。

说明这个可以通过修改系统来解决问题,但要只针对第三方浏览器应用,不影响其他应用的显示。

不难得出,解决这个问题的措施是单独修改浏览器的DPI

DisplayMetrics

densityDpi 屏幕密度。 每英寸屏幕中包含的像素数量,密度越大越清晰

density 逻辑密度。 可以理解为dp换算为像素的比例(即1个dp等于几个像素)。标准的屏幕密度为160,它的 密度比例就是1,即1个dp就等于1个像素。如果你手机的densityDpi为320,则它是标准屏幕密度的两倍(320 / 160 = 2),则density = 2,表示1个dp就等于2个像素。举个例子,比如你手机的densityDpi为320,然后你设置了一个控件的宽为60dp,则它显示到屏幕上的实际宽度为120像素,因为density = 2,所以60 * 2px = 120px。

在android系统中,density 和densityDpi 通常是一一对应的,遵循一个基本的计算规则。

densityDpi 是屏幕密度的绝对值,以每英寸像素数(dpi)表示,而density 是相对于标准密度(160dpi)的缩放因子

这个关系可以用以下公式表示:

density = denistyDpi / 160

那么我们只需要针对这个应用修改DisplayMetrics这两个属性,问题应该就迎刃而解。

并且修改密度应该在WindowManager.addView() 之前,否则修改密度就不起作用,而addView是在onResume方法之后,因此我们需要在onResume()前更改应用的DPI

  1. void handleResumeActivity(){
  2. ...
  3. r = performResumeActivity(token, clearHide, reason); // 调用onResume方法
  4. ...
  5. wm.addView(decor, 1); // WindowManager 添加DecorView
  6. ...
  7. }

我们选择修改Activity.java的onCreate() 方法,通过筛选包名的方式修改指定第三方应用的分辨率

【修改对策】

frameworks\base\core\java\android\app\Activity.java

  1. @MainThread
  2. @CallSuper
  3. protected void onCreate(@Nullable Bundle savedInstanceState) {
  4. ...
  5. mRestoredFromBundle = savedInstanceState != null;
  6. mCalled = true;
  7. ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
  8. List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(1);
  9. //solve firefox new version page scaling incorrect start
  10. if (runningTasks != null && !runningTasks.isEmpty()) {
  11. ComponentName topActivity = runningTasks.get(0).topActivity;
  12. String packageName = topActivity.getPackageName();
  13. if ("org.mozilla.firefox".equals(packageName)) {
  14. Resources resources = getResources();
  15. if (resources != null) {
  16. Configuration configuration = resources.getConfiguration();
  17. if (configuration != null) {
  18. DisplayMetrics displayMetrics = new DisplayMetrics();
  19. getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
  20. int densityDpi = displayMetrics.densityDpi;
  21. // change dpi
  22. if (densityDpi != 240) {
  23. configuration.densityDpi = 240;
  24. configuration.density = 1.5f;
  25. //scaledDensity与density应该相同,因此也同步修改
  26. configuration.scaledDensity = 1.5f;
  27. resources.updateConfiguration(configuration,
  28. resources.getDisplayMetrics());
  29. }
  30. }
  31. }
  32. }
  33. }
  34. //solve firefox new version page scaling incorrect end
  35. }

【总结】

对策修改其实就是几行代码,难点在于定位修改的位置。如果对于系统源码不够熟悉,会需要花费相当多的时间进行调试。系统层去修改第三方应用的DPI等资源是一个十分实用的适配无源码的第三方应用的技巧;

在碰到一些视频画面比例不对,或者View被放大/缩小的问题等,都可以尝试通过修改屏幕密度去解决。

修改时,需要注意修改值符合 公式:density = denistyDpi / 160,否则可能会存在显示不正确,触摸错位等问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/836964
推荐阅读
相关标签
  

闽ICP备14008679号