获取Android设备屏幕分辨率
1.Android 4.3引入的wm工具:
a.获取Android设备屏幕分辨率: adb shell wm size
b.获取android设备屏幕密度: adb shell wm density
public class Wm extends BaseCommand {
...
public void onShowUsage(PrintStream out) {
out.println(
"usage: wm [subcommand] [options]\n" +
" wm size [reset|WxH]\n" +
" wm density [reset|DENSITY]\n" +
" wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
"\n" +
"wm size: return or override display size.\n" +
"\n" +
"wm density: override display density.\n" +
"\n" +
"wm overscan: set overscan area for display.\n"
);
} public void onRun() throws Exception {
mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
Context.WINDOW_SERVICE));
if (mWm == null) {
System.err.println(NO_SYSTEM_ERROR_CODE);
throw new AndroidException("Can't connect to window manager; is the system running?");
} String op = nextArgRequired(); if (op.equals("size")) {
runDisplaySize();
} else if (op.equals("density")) {
runDisplayDensity();
} else if (op.equals("overscan")) {
runDisplayOverscan();
} else {
showError("Error: unknown command '" + op + "'");
return;
}
} private void runDisplaySize() throws Exception {
String size = nextArg();
int w, h;
if (size == null) {
Point initialSize = new Point();
Point baseSize = new Point();
try {
mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);
mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);
System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);
if (!initialSize.equals(baseSize)) {
System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);
}
} catch (RemoteException e) {
}
return;
} else if ("reset".equals(size)) {
w = h = -1;
} else {
int div = size.indexOf('x');
if (div <= 0 || div >= (size.length()-1)) {
System.err.println("Error: bad size " + size);
return;
}
String wstr = size.substring(0, div);
String hstr = size.substring(div+1);
try {
w = Integer.parseInt(wstr);
h = Integer.parseInt(hstr);
} catch (NumberFormatException e) {
System.err.println("Error: bad number " + e);
return;
}
} try {
if (w >= 0 && h >= 0) {
// TODO(multidisplay): For now Configuration only applies to main screen.
mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
} else {
mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
}
} catch (RemoteException e) {
}
} private void runDisplayDensity() throws Exception {
String densityStr = nextArg();
int density;
if (densityStr == null) {
try {
int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
System.out.println("Physical density: " + initialDensity);
if (initialDensity != baseDensity) {
System.out.println("Override density: " + baseDensity);
}
} catch (RemoteException e) {
}
return;
} else if ("reset".equals(densityStr)) {
density = -1;
} else {
try {
density = Integer.parseInt(densityStr);
} catch (NumberFormatException e) {
System.err.println("Error: bad number " + e);
return;
}
if (density < 72) {
System.err.println("Error: density must be >= 72");
return;
}
} try {
if (density > 0) {
// TODO(multidisplay): For now Configuration only applies to main screen.
mWm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density);
} else {
mWm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
}
} catch (RemoteException e) {
}
}
...


@Override
public void getInitialDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
synchronized(displayContent.mDisplaySizeLock) {
size.x = displayContent.mInitialDisplayWidth;
size.y = displayContent.mInitialDisplayHeight;
}
}
}
} @Override
public void getBaseDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
synchronized(displayContent.mDisplaySizeLock) {
size.x = displayContent.mBaseDisplayWidth;
size.y = displayContent.mBaseDisplayHeight;
}
}
}
} @Override
public int getInitialDisplayDensity(int displayId) {
synchronized (mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
synchronized(displayContent.mDisplaySizeLock) {
return displayContent.mInitialDisplayDensity;
}
}
}
return -1;
} @Override
public int getBaseDisplayDensity(int displayId) {
synchronized (mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
synchronized(displayContent.mDisplaySizeLock) {
return displayContent.mBaseDisplayDensity;
}
}
}
return -1;
} @Override
public void setForcedDisplaySize(int displayId, int width, int height) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Must hold permission " +
android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
if (displayId != Display.DEFAULT_DISPLAY) {
throw new IllegalArgumentException("Can only set the default display");
}
synchronized(mWindowMap) {
// Set some sort of reasonable bounds on the size of the display that we
// will try to emulate.
final int MIN_WIDTH = 200;
final int MIN_HEIGHT = 200;
final int MAX_SCALE = 2;
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
width = Math.min(Math.max(width, MIN_WIDTH),
displayContent.mInitialDisplayWidth * MAX_SCALE);
height = Math.min(Math.max(height, MIN_HEIGHT),
displayContent.mInitialDisplayHeight * MAX_SCALE);
setForcedDisplaySizeLocked(displayContent, width, height);
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
}
}
} @Override
public void setForcedDisplayDensity(int displayId, int density) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Must hold permission " +
android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
if (displayId != Display.DEFAULT_DISPLAY) {
throw new IllegalArgumentException("Can only set the default display");
}
synchronized(mWindowMap) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
setForcedDisplayDensityLocked(displayContent, density);
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
}
}
} // displayContent must not be null
private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
Slog.i(TAG, "Using new display density: " + density); synchronized(displayContent.mDisplaySizeLock) {
displayContent.mBaseDisplayDensity = density;
}
reconfigureDisplayLocked(displayContent);
} private DisplayContent newDisplayContentLocked(final Display display) {
DisplayContent displayContent = new DisplayContent(display);
mDisplayContents.put(display.getDisplayId(), displayContent);
final Rect rect = new Rect();
DisplayInfo info = displayContent.getDisplayInfo();
mDisplaySettings.getOverscanLocked(info.name, rect);
info.overscanLeft = rect.left;
info.overscanTop = rect.top;
info.overscanRight = rect.right;
info.overscanBottom = rect.bottom;
mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
rect.right, rect.bottom);
mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
rect.right, rect.bottom);
return displayContent;
} /**
* Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
* there is a Display for the displayId.
* @param displayId The display the caller is interested in.
* @return The DisplayContent associated with displayId or null if there is no Display for it.
*/
public DisplayContent getDisplayContentLocked(final int displayId) {
DisplayContent displayContent = mDisplayContents.get(displayId);
if (displayContent == null) {
final Display display = mDisplayManager.getDisplay(displayId);
if (display != null) {
displayContent = newDisplayContentLocked(display);
}
}
return displayContent;
}


/**
* Gets all currently valid logical displays of the specified category.
* <p>
* When there are multiple displays in a category the returned displays are sorted
* of preference. For example, if the requested category is
* {@link #DISPLAY_CATEGORY_PRESENTATION} and there are multiple presentation displays
* then the displays are sorted so that the first display in the returned array
* is the most preferred presentation display. The application may simply
* use the first display or allow the user to choose.
* </p>
*
* @param category The requested display category or null to return all displays.
* @return An array containing all displays sorted by order of preference.
*
* @see #DISPLAY_CATEGORY_PRESENTATION
*/
public Display[] getDisplays(String category) {
final int[] displayIds = mGlobal.getDisplayIds();
synchronized (mLock) {
try {
if (category == null) {
addMatchingDisplaysLocked(mTempDisplays, displayIds, -1);
} else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI);
addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
}
return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
} finally {
mTempDisplays.clear();
}
}
} private void addMatchingDisplaysLocked(
ArrayList<Display> displays, int[] displayIds, int matchType) {
for (int i = 0; i < displayIds.length; i++) {
Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
if (display != null
&& (matchType < 0 || display.getType() == matchType)) {
displays.add(display);
}
}
}
2.显示区域分为应用显示区域和真实显示区域。
a.应用显示区域不包括系统点缀,它可能比真实显示区域小因为系统减掉了点缀元素的空间如导航栏(隐藏/显示导航栏得到的高度不同)


DisplayMetrics metrics = new DisplayMetrics();
Display displaymetrics = getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = displaymetrics.widthPixels;
int height = displaymetrics.heightPixels;
float density = displaymetrics.density;
int densityDpi = displaymetrics.densityDpi;


/**
* Gets display metrics that describe the size and density of this display.
* <p>
* The size is adjusted based on the current rotation of the display.
* </p><p>
* The size returned by this method does not necessarily represent the
* actual raw size (native resolution) of the display. The returned size may
* be adjusted to exclude certain system decor elements that are always visible.
* It may also be scaled to provide compatibility with older applications that
* were originally designed for smaller displays.
* </p>
*
* @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
*/
public void getMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo);
}
} /**
* Gets display metrics based on the real size of this display.
* <p>
* The size is adjusted based on the current rotation of the display.
* </p><p>
* The real size may be smaller than the physical size of the screen when the
* window manager is emulating a smaller display (using adb shell am display-size).
* </p>
*
* @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
*/
public void getRealMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getLogicalMetrics(outMetrics, null);
}
} private void updateDisplayInfoLocked() {
// Note: The display manager caches display info objects on our behalf.
DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
if (newInfo == null) {
// Preserve the old mDisplayInfo after the display is removed.
if (mIsValid) {
mIsValid = false;
if (DEBUG) {
Log.d(TAG, "Logical display " + mDisplayId + " was removed.");
}
}
} else {
// Use the new display info. (It might be the same object if nothing changed.)
mDisplayInfo = newInfo;
if (!mIsValid) {
mIsValid = true;
if (DEBUG) {
Log.d(TAG, "Logical display " + mDisplayId + " was recreated.");
}
}
}
}


/**
* Describes the characteristics of a particular logical display.
* @hide
*/
public final class DisplayInfo implements Parcelable {
... /**
* The width of the portion of the display that is available to applications, in pixels.
* Represents the size of the display minus any system decorations.
*/
public int appWidth; /**
* The height of the portion of the display that is available to applications, in pixels.
* Represents the size of the display minus any system decorations.
*/
public int appHeight;
...
/**
* The logical width of the display, in pixels.
* Represents the usable size of the display which may be smaller than the
* physical size when the system is emulating a smaller display.
*/
public int logicalWidth; /**
* The logical height of the display, in pixels.
* Represents the usable size of the display which may be smaller than the
* physical size when the system is emulating a smaller display.
*/
public int logicalHeight;
...
public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
@Override
public DisplayInfo createFromParcel(Parcel source) {
return new DisplayInfo(source);
} @Override
public DisplayInfo[] newArray(int size) {
return new DisplayInfo[size];
}
};
...
private DisplayInfo(Parcel source) {
readFromParcel(source);
}
...
public void readFromParcel(Parcel source) {
layerStack = source.readInt();
flags = source.readInt();
type = source.readInt();
address = source.readString();
name = source.readString();
appWidth = source.readInt();
appHeight = source.readInt();
smallestNominalAppWidth = source.readInt();
smallestNominalAppHeight = source.readInt();
largestNominalAppWidth = source.readInt();
largestNominalAppHeight = source.readInt();
logicalWidth = source.readInt();
logicalHeight = source.readInt();
overscanLeft = source.readInt();
overscanTop = source.readInt();
overscanRight = source.readInt();
overscanBottom = source.readInt();
rotation = source.readInt();
refreshRate = source.readFloat();
logicalDensityDpi = source.readInt();
physicalXDpi = source.readFloat();
physicalYDpi = source.readFloat();
} public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
} public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
} private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
int width, int height) {
outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; outMetrics.density = outMetrics.noncompatDensity =
logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; if (cih != null) {
CompatibilityInfo ci = cih.getIfNeeded();
if (ci != null) {
ci.applyToDisplayMetrics(outMetrics);
}
}
}
b.真实显示区域包括系统点缀,但它有可能比物理显示小当窗口管理器模拟更小显示(如使用adb shell am display-size)时


Display d = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = d.getMetrics(new DisplayMetrics()); int ver = Build.VERSION.SDK_INT;
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
if (Build.VERSION.SDK_INT = 13)
try {
widthPixels = (Integer) Display.class.getMethod("getRealWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRealHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
//Point realSize = new Point();
//Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
//widthPixels = realSize.x;
//heightPixels = realSize.y;
DisplayMetrics realMetrics = d.getRealMetrics(new DisplayMetrics());
widthPixels = realMetrics.widthPixels;
heightPixels = realMetrics.heightPixels;
} catch (Exception ignored) {
}
获取Android设备屏幕分辨率的更多相关文章
- 【Android 应用开发】分析各种Android设备屏幕分辨率与适配 - 使用大量真实安卓设备采集真实数据统计
.主要是为了总结一下 对这些概念有个直观的认识; . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/198 ...
- 分析各种Android设备屏幕分辨率与适配 - 使用大量真实安卓设备采集真实数据统计
一. 数据采集 源码GitHub地址 : -- SSH : git@github.com:han1202012/DisplayTest.git; -- HTTP : https://github.co ...
- Android 开发 获取Android设备的屏幕高宽
获得屏幕的宽度和高度有很多种方法: //1.通过WindowManager获取 DisplayMetrics dm = new DisplayMetrics(); heigth = dm.height ...
- 获取Android 手机屏幕宽度和高度以及获取Android手机序列号
1.获取Android 手机屏幕宽度 1 DisplayMetrics dm = new DisplayMetrics(); 2 this.getWindowManager().getDefaultD ...
- 获取Android设备WIFI的MAC地址 “MAC地址”
需要指出的是:wifi状态和wifi AP状态是互斥的状态:也就是一旦发现WIFI AP打开,WIFI是不能被打开的. 获取Android设备的WIFI MAC地址,首先需要将设备中的WIFI个人热点 ...
- Unity3D Android手机屏幕分辨率问题
Android手机屏幕分辨率五花八门,导致开发时不好把握,还好各个引擎对这个屏幕分辨率问题都有较好的处理方式:unity3D 也为我们提供了一个不错的解决方案. 在Unity3D 进行 android ...
- iOS设备屏幕分辨率分布
iOS设备屏幕分辨率比较单一,960*640是iPhone4和4s的分辨率,占比67.4%;1024*768是iPad1和iPad2的分辨率,占比22.5%;480*320是iPhone3和3gs的分 ...
- 获取Android设备的方向,Sensor和SensorManager实现手机旋转角度
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1009/425.html 带有g-sensor的Android设备上可通过API ...
- ios各个型号设备屏幕分辨率总结
https://blog.csdn.net/amyloverice/article/details/79389357 iPhone: iPhone 1G 320x480 iPhone 3G 3 ...
随机推荐
- js--小结⑦---格式转换
- C# 二叉查找树实现
BuildTree 代码1次CODE完,没有BUG. 在画图地方debug了很多次.第一次画这种图. 一开始用treeview显示,但发现不是很好看出树结构,于是自己动手画了出来. using Sys ...
- eclipse中更改默认编码格式
更改过程如下: (1)window->preferences->general->content Types, 选中java class file修改default encoding ...
- CSS布局模型思考
flow模型:默认布局模型,元素从左向右.从上到下依次排列,块状元素独占一行.Position属性对应值static. float模型:主要效果是让本来独占一行的块状元素变成内联-块状元素,并到一排显 ...
- hdoj 2602(背包)
Problem D Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Sub ...
- cocos2dx 实现华丽丽的滚动层.
前言 好久没写博客了. 前几周策划要求实现一个比较多功能的滚动层控件. 这个艰巨的任务就这样自然而然的落在了我这小身板上. 当然了, 只要我出手, 难度再高的需求也变得不堪一击. 哈哈哈哈 示例图 该 ...
- Why your Games are Unfinished, and What To Do About It (转)
So, you've got a new game idea, and it's going to change what everyone knows about the genre! Great! ...
- HDU 1996
Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上, ...
- TC2.0中怎样调用汇编程序
转载于: TC2.0中怎样调用汇编程序 一.概述 TC是美国BORLAND 公司在IBM PC机上开发的一个高效.优化的C编译程序,它自带高效的全屏幕编辑程序,在集成开发环境下可支持编辑.编译.连接调 ...
- ASP.NET MVC轻教程 Step By Step 3 ——使用ViewBag
在上一节我们创建了与Index动作方法对应的Index视图,那么Index动作方法该如何向Index视图传送数据呢?其中一个方法是使用ViewBag(视图包).让我们试试看. 在Index动作方法中添 ...