I'd like to get the size of the screen of the phones but it keeps giving me wrong values, I already used
WindowManager windowmanager = (WindowManager)
getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Display display = windowmanager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
float deviceWidth = displayMetrics.widthPixels;
float deviceHeight = displayMetrics.ydpi;
I tried this code too :
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
// Note, screenHeightDp isn't reliable
// (it seems to be too small by the height of the status bar),
// but we assume screenWidthDp is reliable.
// Note also, dm.widthPixels,dm.heightPixels aren't reliably pixels
// (they get confused when in screen compatibility mode, it seems),
// but we assume their ratio is correct.
double screenWidthInPixels = (double)config.screenWidthDp *dm.density;
double screenHeightInPixels = screenWidthInPixels * dm.heightPixels / dm.widthPixels;
deviceWidth = (int)(screenWidthInPixels + .5);
deviceHeight = (int)(screenHeightInPixels + .5);
And also that :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Point realSize = new Point();
display.getRealSize(realSize);
deviceWidth= realSize.x;
deviceHeight = realSize.y;
}
But on my Samsung S7 on sdk 7.0 I got 1920x1080 that is wrong because on a S7 on sdk 6.0.1 I got 2560x1440 that is the real value.
I tried a lot of solution but found nothing good.
Thanks
Your code is correct. Just in case if you wondering why you get that values, it is because your phone will automatically set the default resolution size to 1920x1080 after updated to 7.0 (Nougat) to conserve the battery life. One of the new features in Nougat is display scaling option, where you can set your phone (in this case, S7) to 3 available modes (WQHD (2560x1440), FHD (1920x1080), and HD (1280x720)). Try go to Settings -> Display and change the settings to your needs. You can read more here: Galaxy S7 on Nougat defaults to 1080p
use this
getWindowManager().getDefaultDisplay().getHeight();
getWindowManager().getDefaultDisplay().getWidth();
This will work for sure.
try {
display.getRealSize(size);
height = size.y;
width=size.x;
} catch (NoSuchMethodError e) {
height = display.getHeight();
width=display.getWidth();
}
Try this link
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
The method below return a Point that contain display size (x as Width and y as Height):
public static Point checkDisplaySize(Context context) {
Point tempDisplaySize = new Point();
try {
WindowManager manager = (WindowManager) context().getSystemService(Context.WINDOW_SERVICE);
if (manager != null) {
Display display = manager.getDefaultDisplay();
if (display != null) {
display.getSize(tempDisplaySize);
Log.d("tmessages", "display size = " + displaySize.x + " " + displaySize.y);
}
}
} catch (Exception e) {
Log.e("tmessages", e.getMessage(), e);
}
return tempDisplaySize;
}
P.S: This is the Code Telegram uses to get display size.
Related
Hello I want to ask about the most efficient way to adjust layout in all devices mobile and tablets sometimes I can't use wrap_content and layout_weight
I set size in some percentage to the device size in java like this:
ImageView img;
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
img.getLayoutParams().width = width* 7 / 10;
and when rotating screen I use this method to change percentage
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE&& getResources().getBoolean(R.bool.isTablet)) {
width=(int) (width * 0.7);
}
I am asking If this procedure is more efficient than using multi XML files for each screen size / orientation
Actually it depends on the scenario. Sometimes maintaining xml is efficient and easy sometimes dynamic calculation is necessary. You can go through the link https://developer.android.com/guide/practices/screens_support.html . It will give you some ideas. In your above code for width/height calculation sometimes you may not get proper result for some devices. Below is the code that will support all version of android device Resolution(Width, Height) accurately at runtime.
private void calculateDeviceResolution(Activity context) {
Display display = context.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= 17) {
//new pleasant way to get real metrics
DisplayMetrics realMetrics = new DisplayMetrics();
display.getRealMetrics(realMetrics);
realWidth = realMetrics.widthPixels;
realHeight = realMetrics.heightPixels;
} else if (Build.VERSION.SDK_INT >= 14) {
//reflection for this weird in-between time
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
realWidth = (Integer) mGetRawW.invoke(display);
realHeight = (Integer) mGetRawH.invoke(display);
} catch (Exception e) {
//this may not be 100% accurate, but it's all we've got
realWidth = display.getWidth();
realHeight = display.getHeight();
Constants.errorLog("Display Info", "Couldn't use reflection to get the real display metrics.");
}
} else {
//This should be close, as lower API devices should not have window navigation bars
realWidth = display.getWidth();
realHeight = display.getHeight();
}
}
In our application, we need to determine screen width at startup. We have tried to get this width using a few different methods (see list below), but Samsung devices, especially their Galaxy devices, are sometimes giving us incorrect values.
We have a Galaxy s6 with a resolution of 1440 x 2560 pixels. Most of the time the device will report a width of 1440, but occasionally it will give us a width of 1080.
We have tried getting the width the following ways:
1)
getResources().getDisplayMetrics().widthPixels;
2)
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
3)
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getRealSize(size);
But in all cases we see an incorrect width being returned. We see incorrect values reliably when our application is launched for the very first time. Any help would be hugely appreciated.
Have you tried this?
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = metrics.widthPixels;
UPDATE
And a little bit hardcore.
You may find more here.
This is our getDeviceWidth() method for ages and we never had any trouble with it, but i guess it's your second version?! Please verify and comment. (Ensure you call this after your views are created.)
public static int getDeviceWidth(Activity activity) {
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
Otherwise i would try to get the y-position (or width) of an dummy layout which has sets its width to match_parent.
And test your getWidth on start and after app is running (f.e. on button click). Does it return wrong width during run time too?
In my method, I haven't run into any issues before in terms of not locating the right location of something or the exact size of any Android screen.
My method finds the screen size in inches and the screen height and width in pixels and inches
In my app this method is how I check if my app is being used by a tablet:
private void tabletChanges() {
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
int dens = dm.densityDpi;
double wi = (double)width/dm.xdpi;
double hi = (double)height/dm.ydpi;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);
if(screenInches >= 7){
//Do certain things
}
}
How can I calculate the screen size exactly under the consideration of Edge part?
Now, I'm developing custom keyboard and when it becomes visible, its size is calculated programmatically based on screen size.
What function I used calculate the screen size is like following.
public static Point getDimentionalSize(Context context)
{
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int realWidth;
int realHeight;
if (Build.VERSION.SDK_INT >= 17){
//new pleasant way to get real metrics
DisplayMetrics realMetrics = new DisplayMetrics();
display.getRealMetrics(realMetrics);
realWidth = realMetrics.widthPixels;
realHeight = realMetrics.heightPixels;
} else if (Build.VERSION.SDK_INT >= 14) {
//reflection for this weird in-between time
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
realWidth = (Integer) mGetRawW.invoke(display);
realHeight = (Integer) mGetRawH.invoke(display);
} catch (Exception e) {
//this may not be 100% accurate, but it's all we've got
realWidth = display.getWidth();
realHeight = display.getHeight();
Log.e("Display Info", "Couldn't use reflection to get the real display metrics.");
}
} else {
//This should be close, as lower API devices should not have window navigation bars
realWidth = display.getWidth();
realHeight = display.getHeight();
}
return new Point(realWidth, realHeight);
}
This function calculates screen size exactly in terms of pixels.
But when I try it on Samsung Galaxy Note Edge, the resulted screen width composes device's Edge part also.
I'd like to exclude it from screen size. (if portrait, from width, otherwise, from height)
What's the solution?
You can try this
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
For normal uses you can use the DisplayMetrics class and get the "renderable" size, but I want to figure out the actual physical screen size, which includes the virtual buttons height.
On my Galaxy Nexus the reported size no matter what I tried is 1196x720, what can I use to get the physical one which is 1280x720 ? Same goes for Nexus 7, Nexus 4 and Nexus 10 devices.
UPDATE : This is the final code I now use, including the fix :
//Activity A = this;
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) A.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();
int API_LEVEL = android.os.Build.VERSION.SDK_INT;
if (API_LEVEL >= 17)
{
disp.getRealMetrics(displayMetrics);
}
else
{
disp.getMetrics(displayMetrics);
}
int Width = displayMetrics.widthPixels;
int Height = displayMetrics.heightPixels;
You should use Display.getRealSize(Point) From the official docs here
The display area is described in two different ways.
The application display area specifies the part of the display that
may contain an application window, excluding the system decorations.
The application display area may be smaller than the real display area
because the system subtracts the space needed for decor elements such
as the status bar. Use the following methods to query the application
display area: getSize(Point), getRectSize(Rect) and
getMetrics(DisplayMetrics).
The real display area specifies the part
of the display that contains content including the system decorations.
Even so, the real display area may be smaller than the physical size
of the display if the window manager is emulating a smaller display
using (adb shell am display-size). Use the following methods to query
the real display area: getRealSize(Point),
getRealMetrics(DisplayMetrics).
The answer in the similar question seems to have a solution to get the real size of the display when API < 17 https://stackoverflow.com/a/15699681/601298
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// 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;
} catch (Exception ignored) {
}
Is there a way we can test an android device's resolution?
In any test function you can write following code:
Activity ACT = getActivity();
Display display = ACT.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
or if API<13
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Hope this Help : [If u r planning to run same test code for Phone/Tablet]
Configuration mConfig = mContext.getResources().getConfiguration();
// checking for XLarge screen ...U can also check for Large screen similarly
if ((mConfig.screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
Log.i("TABLET MODE");
// Do ur actions for Tablet
}