how to get fullscreeen height on S9 and similar? - android

My current android code to retrieve the screen height in pixels is this:
Resources.getSystem().getDisplayMetrics().heightPixels
However when the app is running in full screen mode on Samsung S9 (and probably on similar devices) the returned height is the same as it is when the app is not running fullscreen, i.e. it is calculated without the buttons menu bar that is gone when we're in fullscreen.
Any ideas on a better way to retrieve the height or possibly to be aware of the fact that the app is running full screen?

You can use
val size = Point()
windowManager.defaultDisplay.getRealSize(size)
size.y // will be your needed height
or in Java
Point size = new Point()
getWindowManager().getDefaultDisplay().getRealSize(size)
size.y // this one will be your height
Hope it's what you need.

Related

Restricting an app's screen size based on a phone's resolution

I am developing an application in android studio which is displayed correctly on 1080x1920 phones(and lower) but for phones like mine(s8) the app gets messed up and i can't find a way to fix the app's ui for every screen size. So, i was wondering if there is a way to restrict the app's screen size to 1080x1920(with let's say black bars at the top & bottom of the screen) even if a phone's dimensions are bigger than that(this is automatically done in games that are not compatible with s8). Do you guys know a way of achieving this effect?
It's possible, you can set your parent View to exact size given the aspect ratio you want (1080x1920 scales down to 9x16). For this you'd have to programmatically call the View (or create it in code) and set width and height in pixels with LayoutParams:
yourView.setLayoutParams(new LayoutParams(width, height));
for the weight and height you'd want the actual screen dimensions, which you can get from the WindowManager:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int x = point.x;
int y = point.y;
Here you get the x and y, which hold your actual screen size (in pixels). Then, you decide on which one should be reduced (in order to maintain 9x16 aspect ratio) and set your parent View's LayoutParams as mentioned above.
Finally, your set your content View as your parent View:
setContentView(yourView);
That's about it. Hope that helps.
EDIT: Since you've mentioned games, I can tell you that there (if your use Android SDK) you have your SurfaceView as a parent View, the procedure is same.

Does display.getSize() include the black bar at the bottom of some devices?

In my Android app, I need to get the height and width of the view area in the app. I'm using the following code to get that information:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
However, I noticed that when I run the app in the emulator, the height variable also includes the black bar with the back, home and menu buttons. When I run it on my phone, I get a true value because my buttons are on the physical phone, not the screen. I don't have an Android device with the screen buttons to test with.
I'm curious, will my code include the height of the black bar? I would assume that the Android OS would not include the section taken up by that black bar as a usable part of the screen, but I'm not sure.
Is there some alternate way that I could get the height and width of the main relative layout when it's set as match_parent in the XML? This would probably be the better method, but I tried giving the layout an ID and targeting it in the Java code to get the size, but it crashed the app.
Any information or help would be very much appreciated.

how to get android screen size programmatically, once and for all?

How can I find out my screen size programmatically,
in the units used by touch events
and View measurement/layout?
In other words, I want the coordinates
of the bottom-right corner of the screen,
in the coordinate system used by touch events'
getRawX()/getRawY() and View.getLocationOnScreen().
I'm hesitant to call the desired event/view units "pixels"
since evidently there are several notions of "pixels"
on my phone in various modes,
and they're not adding up to a consistent story.
I see this has been asked and answered a lot
on stackoverflow and elsewhere,
but none of the answers actually work on my phone
(droid 4, android 4.1.2) in all modes:
Can I find out width of screen programmatically in android app?
How do I get the ScreenSize programmatically in android
Android set View visibility programmatically based on screen size
How do I get the height of the screen in Android?
Get the screen height in Android
https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
http://shuklaxyz.blogspot.com/2012/02/how-to-programmatically-figure-out.html
http://coderock.net/how-to-determine-screen-resolution-programmatically/
http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
Android and setting width and height programmatically in dp units
http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatically-in-android/
http://www.androidsnippets.com/get-size-and-orientation-of-the-screen
http://grokbase.com/t/gg/android-developers/127aatfqb6/how-to-determine-screen-resolution-programmatically
(wow!)
This is for library code that needs to work
regardless of whether the app is in "screen compatibility mode"
(i.e. targetSdkVersion<=10 in the manifest) or not,
and I also don't want to make any assumptions
about the position, size, or existence of the status bar
or any other similar screen decorations.
Here are the facts:
my phone (a droid 4 running android 4.1.2)
has 540x960 physical pixels,
i.e. little colored glowing dots.
the size of the screen in the desired units,
from looking at touch events and View measurements, is
360x640 when the app is in screen compat mode,
540x960 when the app is not in screen compat mode.
These are the numbers I need to find programmatically,
without mucking with touch events or Views to find them,
but I'm having extreme difficulty finding any API
that will return these numbers.
Display and DisplayMetrics objects obtained
in various ways all claim the screen size
is 540x960 "pixels"
(whether in screen compat mode or not).
To be specific, the following all say 540x960 all the time:
DisplayMetrics.{width,height}Pixels,
Display.getSize(),
Display.getRealSize(),
Display.get{Width,Height}(),
Configuration objects obtained in various ways
all say screen{Width,Height}Dp = 360x614
(whether in screen compat mode or not).
I don't believe that represents the whole screen,
since the aspect ratio is wrong.
(I think it's the whole screen
minus the status bar; I need the whole screen.)
I think it's safe to say that the whole screen is 360x640 dp,
though I don't know any API that returns that 640.
DisplayMetrics obtained in various ways
say the "density" is
1.0f when in screen compat mode,
1.5f when not in screen compat mode.
The activity's
getWindow().getAttributes().{width,height}
isn't helpful since it typically contains MATCH_PARENT
rather than actual sizes.
But I can apparently get the desired answer from an activity's
getWindow().getDecorView().getMeasured{Width,Height}()
(which is actually surprising since
the activity's window's decorView
doesn't look like it's taking up the whole screen;
it looks like it's taking up the screen minus the status bar).
But I don't want to rely on this because if the window ever gets resized
(soft keyboard appearing? someone calling window.setAttributes()?
or maybe I'm not in an Activity at all),
this is clearly going to be all wrong.
I understand the following formula is supposed to hold:
pixels = dp * density
That seems to agree with all the reported numbers ((3),(4),(5) above)
when not in screen compatibility mode:
540x960 = 360x640 * 1.5
But in screen compatibility mode it doesn't add up:
540x960 != 360x640 * 1
So, something is awry.
The simplest explanation, I think,
is that the methods listed in (3) above
are simply giving the wrong answer for "pixels" when
in screen compat mode-- that is, they were intended
to return 360x640 "pixels" but they are wrongly returning 540x960 instead.
But there may be other ways of looking at it.
In any case, getting the desired numbers regardless of mode,
from the above puzzle pieces, is certainly a tricky puzzle.
I have found a way that seems to work on my phone in both modes,
but it is extremely circuitous,
and it relies on two assumptions that still seem rather shaky
(as described in the code comments below).
Here is my recipe:
/** get screen size in "pixels", i.e. touchevent/view units.
* on my droid 4, this is 360x640 or 540x960
* depending on whether the app is in screen compatibility mode
* (i.e. targetSdkVersion<=10 in the manifest) or not. */
public void getScreenSizePixels(int widthHeightInPixels[/*2*/])
{
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;
widthHeightInPixels[0] = (int)(screenWidthInPixels + .5);
widthHeightInPixels[1] = (int)(screenHeightInPixels + .5);
}
Is there any better/cleaner way
to find the size of the screen??
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Now you can measure your screen size in pixel which is a better measurement unit than centimeter because all the buttons ,textviews etc.. are measured in this unit. That what I use normally
By using the DisplayMetrics you can get height and width of the screen of any device. Note that width and height are sensitive to rotation.
here is the code.
DisplayMetrics metrics;
int width = 0, height = 0;
In your onCreate Method
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
height = Math.min(metrics.widthPixels, metrics.heightPixels); //height
width = Math.max(metrics.widthPixels, metrics.heightPixels); //width
Try this.
In your #6, you note that the DecorView seems to provide what you want, but you don't think it is realiable. I believe that is as close as you can come. According to the documentation for Window.getDecorView:
Retrieve the top-level window decor view (containing the standard window frame/decorations and the client's content inside of that), which can be added as a window to the window manager.
The status bar is part of the window decoration mentioned there. Software keyboards and other overlays will receive their own window, so they shouldn't interfere with the relevant values. It is correct that isn't precisely the display metrics, but if your application is full screen it should always be the full screen size filtered through the compatibility translator. Other applications won't have access to your application's Window, so there is no need to worry about some other app changing the attributes while you aren't looking.
Hope that helps.
I should put this as a comment but I don't have the rep for that.
This may not be a totally correct answer but I got my dimensions when I switched the height and width in the DisplayMetrics method.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.heightPixels;
height = metrics.widthPixels;
as I said this may not be correct but I don't know why but it worked for me.
If you are using api level 17 or higher check out getRealMetrics and getRealSize in Display
For api level 14,15 & 16 look here
I've used Pythagoras theorem to find the diagonal size of Android phone/tablet screen, same principal can be applied to iPhone or Blackberry screen.
DisplayMetrics met = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(met);// get display metrics object
String strSize =
new DecimalFormat("##.##").format(Math.sqrt(((met.widthPixels / met.xdpi) *
(met.widthPixels / met.xdpi)) +
((met.heightPixels / met.ydpi) * (met.heightPixels / met.ydpi))));
// using Dots per inches with width and height
Pythagoras must have been a genios, he knew smart phone programming so many years ago :p
I use the below method to get the width of the device :
public static int getDeviceWidth(Context context){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width=display.getWidth();
return width;
}
I think this function will help you to simply get the width and height of your android screen size. The function returns the width and height as an array of integers as shown below
private int[] getScreenSIze(){
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
int w = displaymetrics.widthPixels;
int[] size={w,h};
return size;
}
and on your create method output your width and height as shown below
int[] screenSize= getScreenSIze();
int width=screenSize[0];
int height=screenSize[1];
screenSizes.setText("Phone Screen sizes \n\n width = "+width+" \n Height = "+height);
Download source code and test it on your android studio
This works for me:
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int height = Resources.getSystem().getDisplayMetrics().heightPixels;
I used this to update width of my items in a horizontal recycler view.(according to my requirement)
Hope it helps someone!
For this solution in Kotlin, try this:
private fun yourFunction(){
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
val width = metrics.widthPixels
val height = metrics.heightPixels
}

Samsung's multi window support - Screen size

I'm currently developping my app to be compatible with the samsung multi window feature introduced with the galaxy note 2 and soon the galaxy s3. If you don't know what I'm talking about :
(source: androidheadlines.com)
If you are interested, here is a link to know how to do it : here
My problem is that I need to know the height/width that my app uses.
I'm doing this :
displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
heightScreen = displaymetrics.heightPixels;
widthScreen = displaymetrics.widthPixels;
But this returns the size of the entire screen, not just the part that my app uses. My activity is only compose by a Panel which take the entire space, but the panel.getHeight() or getWidth() return 0.
How can I get the real height/width ?
Thanks in advance.
My activity is only compose by a Panel which take the entire space, but the panel.getHeight() or getWidth() return 0.
Try checking later. You are probably checking for this in onCreate(), which is too soon AFAIK.

Handling different screen resolutions for background images in Android

My Android app (a text-based game) uses background images a lot in order to provide a better visual ambiance. For example, if the action in the game takes you into a tavern, then you get a background image of a tavern in the game. This is a vast improvement, graphically, over the boring black background that you would otherwise get.
It is also a problem, however, since android:background always stretches to the dimensions of the screen. The result is that the background images look very bad if the player switches between portrait and landscape mode. And to make matters worse, many devices have very different aspect ratios (e.g., 320x480 mdpi, 480x800 hdpi, and 480x852 hdpi) and even more variations are coming.
How do others solve this problem? Having individual images for the main resolutions/orientations is not an option for me, as this would result in the apk growing too large.
The first step is to get the screen height and width of the device itself, then stretch/shrink or pad your bitmap as needed. This SO answer has source that should help, copied below. Props to Josef for original answer.
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Here's generic source on getting the orientation.
int orientation = display.getOrientation();
or some more involved source from here (a little messy but looks correct).
public int getscrOrientation()
{
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
// Sometimes you may get undefined orientation Value is 0
// simple logic solves the problem compare the screen
// X,Y Co-ordinates and determine the Orientation in such cases
if(orientation==Configuration.ORIENTATION_UNDEFINED){
Configuration config = getResources().getConfiguration();
orientation = config.orientation;
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(getOrient.getWidth()==getOrient.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(getOrient.getWidth() < getOrient.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
return orientation; // return value 1 is portrait and 2 is Landscape Mode
}
I would suggest you get the width and height of your current view. Right now I am not sure what functions will give you these values but I am sure it is possible. With that you can then calculate an aspect ratio. I'd make the images something like 1000x1000 and just show a certain part of the image, so that the aspect ratio will not be wrong.
I have the same problem with the camera. So my solution was to pick one of the two values, width or height, as fixed, and calculate the correct other value according to the aspect ratio. I'm not sure if there are functions already to just show a part of the image, but I am sure you could write something to copy just a part of the image and show that part.
The drawback is of course that you will be showing just a part of the background. Since the general aspect ratio of the phones is however somewhere between 1:1.3 and 1:1.8 I guess it wouldn't be a too big problem. I for one would rather see the part of an image in the correct way, than looking at an ugly stretched image.
Maybe you could create your background images as NinePatch images so that you are in better control of how it stretches?
Otherwise, you can just prevent your images from stretching (or at least keep the correct aspect ratio) by setting the scaleType attribute e.g. android:scaleType="center".

Categories

Resources