AI2 Component  (Version nb184)
ScreenDensityUtil.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2015 Google, All Rights reserved
3 // Copyright 2011-2020 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.runtime.util;
8 
9 import android.content.Context;
10 import android.graphics.Point;
11 import android.util.DisplayMetrics;
12 import android.util.Log;
13 import android.view.Display;
14 import android.view.WindowManager;
15 
16 import java.lang.reflect.InvocationTargetException;
17 import java.lang.reflect.Method;
18 
23 public final class ScreenDensityUtil {
24 
25  private static final String LOG_TAG = "ScreenDensityUtil";
26 
27  // Much of this compatibility scaling code/constant is taken
28  // from the Android source code.
29  public static final int DEFAULT_NORMAL_SHORT_DIMENSION = 320;
30  public static final float MAXIMUM_ASPECT_RATIO = (854f/480f);
31 
32 
33  private ScreenDensityUtil() {
34  }
35 
43  public static float computeCompatibleScaling(Context context) {
44  DisplayMetrics dm = context.getResources().getDisplayMetrics();
45 
46  Point rawDims = new Point();
47  getRawScreenDim(context, rawDims);
48 
49  int width = rawDims.x;
50  int height = rawDims.y;
51 
52  int shortSize, longSize;
53  if (width < height) {
54  shortSize = width;
55  longSize = height;
56  } else {
57  shortSize = height;
58  longSize = width;
59  }
60  int newShortSize = (int)(DEFAULT_NORMAL_SHORT_DIMENSION * dm.density + 0.5f);
61  float aspect = ((float)longSize) / shortSize;
62  if (aspect > MAXIMUM_ASPECT_RATIO) {
63  aspect = MAXIMUM_ASPECT_RATIO;
64  }
65  int newLongSize = (int)(newShortSize * aspect + 0.5f);
66  int newWidth, newHeight;
67  if (width < height) {
68  newWidth = newShortSize;
69  newHeight = newLongSize;
70  } else {
71  newWidth = newLongSize;
72  newHeight = newShortSize;
73  }
74 
75  float sw = width/(float)newWidth;
76  float sh = height/(float)newHeight;
77 
78  return Math.max(1, Math.min(Math.min(sw, sh), MAXIMUM_ASPECT_RATIO));
79  }
80 
88  private static void getRawScreenDim(Context context, Point outSize) {
89 
90  final DisplayMetrics metrics = new DisplayMetrics();
91  final WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
92  Display display = wm.getDefaultDisplay();
93 
94  int sdkLevel = SdkLevel.getLevel();
95  if (sdkLevel >= SdkLevel.LEVEL_NOUGAT) {
96  // Needed for multi-window support
97  display.getMetrics(metrics);
98  outSize.x = metrics.widthPixels;
99  outSize.y = metrics.heightPixels;
100  } else if (sdkLevel >= SdkLevel.LEVEL_JELLYBEAN_MR1) {
101  // On API level 17, a public method was added to get the actual sizes
102  JellybeanUtil.getRealSize(display, outSize);
103  } else if ( sdkLevel > SdkLevel.LEVEL_GINGERBREAD_MR1){
104  // Before API level 17, the realsize method did not exist
105  // We use reflection instead to access some hidden methods
106  // Does not work for 3.x, will just error
107  try {
108  Method getRawH = Display.class.getMethod("getRawHeight");
109  Method getRawW = Display.class.getMethod("getRawWidth");
110  try {
111  outSize.x = (Integer) getRawW.invoke(display);
112  outSize.y = (Integer) getRawH.invoke(display);
113  } catch (IllegalArgumentException e) {
114  Log.e(LOG_TAG, "Error reading raw screen size", e);
115  } catch (IllegalAccessException e) {
116  Log.e(LOG_TAG, "Error reading raw screen size", e);
117  } catch (InvocationTargetException e) {
118  Log.e(LOG_TAG, "Error reading raw screen size", e);
119  }
120  } catch (NoSuchMethodException e) {
121  Log.e(LOG_TAG, "Error reading raw screen size", e);
122  }
123  } else {
124  // The raw height and width functions were added after verison 10
125  // Before that, the methods actually returned the raw values
126  outSize.x = display.getWidth();
127  outSize.y = display.getHeight();
128  }
129 
130  }
131 }
com.google.appinventor.components.runtime.util.SdkLevel.LEVEL_NOUGAT
static final int LEVEL_NOUGAT
Definition: SdkLevel.java:37
com.google.appinventor.components.runtime.util.ScreenDensityUtil.DEFAULT_NORMAL_SHORT_DIMENSION
static final int DEFAULT_NORMAL_SHORT_DIMENSION
Definition: ScreenDensityUtil.java:29
com.google.appinventor.components.runtime.util.SdkLevel
Definition: SdkLevel.java:19
com.google.appinventor.components.runtime.util.SdkLevel.LEVEL_JELLYBEAN_MR1
static final int LEVEL_JELLYBEAN_MR1
Definition: SdkLevel.java:32
com.google.appinventor.components.runtime.util.SdkLevel.getLevel
static int getLevel()
Definition: SdkLevel.java:45
com.google.appinventor.components.runtime.util.ScreenDensityUtil.MAXIMUM_ASPECT_RATIO
static final float MAXIMUM_ASPECT_RATIO
Definition: ScreenDensityUtil.java:30
com.google.appinventor.components.runtime.util.ScreenDensityUtil.computeCompatibleScaling
static float computeCompatibleScaling(Context context)
Definition: ScreenDensityUtil.java:43
com.google.appinventor.components.runtime.util.ScreenDensityUtil
Definition: ScreenDensityUtil.java:23