安卓java分辨率_获取Android设备屏幕分辨率

1.Android 4.3引入的wm工具:

a.获取Android设备屏幕分辨率: adb shell wm size

b.获取android设备屏幕密度: adb shell wm density

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public class Wm extendsBaseCommand {

...public voidonShowUsage(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() throwsException {

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() throwsException {

String size=nextArg();intw, h;if (size == null) {

Point initialSize= newPoint();

Point baseSize= newPoint();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() throwsException {

String densityStr=nextArg();intdensity;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) {

}

}

...

View Code

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View Code@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;

}

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View Code/**

* Gets all currently valid logical displays of the specified category.

*

* 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.

*

*

* @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 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.应用显示区域不包括系统点缀,它可能比真实显示区域小因为系统减掉了点缀元素的空间如导航栏(隐藏/显示导航栏得到的高度不同)

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View CodeDisplayMetrics 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;

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View Code/**

* Gets display metrics that describe the size and density of this display.

*

* The size is adjusted based on the current rotation of the display.

*

* 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.

*

*

* @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.

*

* The size is adjusted based on the current rotation of the display.

*

* 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).

*

*

* @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.");

}

}

}

}

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View Code/**

* 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 CREATOR = new Creator() {

@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)时

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png

View CodeDisplay 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) {

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值