Detect device screen size - android

Hi i want to fit my app to all screen sizes and to do so i need to get the screen width and height.
but if i use this code for example
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels
It gives me the pixels so there can happen a situation that it gives me the same dimentions for tablet and a smaller phone.
how can i get the actual screen size?
and another thing, i have a game i made with bitmaps and on my phone it is working fine but on tablet the bitmaps are too small how can i resize them according to screen size?

You need screen density and pixel size. (Number of pixels) / (dots per inch) gives screen size in inches.
See: getting the screen density programmatically in android?
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels
int realWidth = (int)((float)width/metrics.density);
int realHeight = (int((float)height/metrics.density);
Answer to the second question depends on how are you loading your bitmaps. You should provide multiple sizes for different devices. Then you can use built-in scaling mechanism - simply place bitmaps in their matching drawable-(dpi)-(screen size) folders. Other way you would have to load images from assets folder and scale them if necessary.

For your 2nd problem of bitmap appearing too small on tablet, try to nine patch your image and then place those images in their respective folders (hdpi, mdpi, xhdpi, xxhdpi)
Make sure you use the high quality resolution image for nine patching otherwise your image will get stretch (poor quality).
You can nine patch your image from here also nine patching image

try this:
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

You can get screen dimensions with this code:
public int getScreenHeight() {
return getDisplay().getHeight();
}
private Display getDisplay() {
return ((WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
}
public int getScreenWidth() {
return getDisplay().getWidth();
}

Try this.
Add this to onCreate() Method. Declare point!
WindowManager wm = ((WindowManager) getSystemService(WINDOW_SERVICE));
Display display = wm.getDefaultDisplay();
point = getDisplaySize(display);
//here is the method to get device size.
#Deprecated
#SuppressLint("NewApi")
private static Point getDisplaySize(final Display display) {
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
return point;
}

Related

Android proper way to fit layout on all devices horizontally and vertically

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();
}
}

Samsung devices intermittently reporting incorrect screen width

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
}
}

Generating non icon images

I want to add image resources to an Android app that won't be used for icons. I wanted to know what is the right way of doing it while supporting multiple device screen sizes. The only solution I can think of is resizing the image to different pixel (width, height) combinations and storing them in their appropriate drawable folders.
For images that are icons, I use the Android studio image asset tool to automatically generate different sized icons. I want that for images that are not icons(won't be placed in the toolbar and similar places).
Solution that worked for me
Used Android Asset Studio, Generic Icon Generator
to generate the resource images for the different device resolutions.
I think you can try this:
Create folder drawable-nodpi and put your images inside it.
Use this code to find the width of the device:
public static int getWidth() {
int width = 400;
try {
WindowManager wm = (WindowManager) DataBackApplication.getInstance().getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if (Build.VERSION.SDK_INT > 12) {
Point size = new Point();
display.getSize(size);
width = size.x;
} else {
width = display.getWidth(); // Deprecated
}
} catch (Exception e) {
e.printStackTrace();
}
return width;
}
Build your layout.
Load image using this code:
int width = getWidth();
int imgWidth = width/6;
int imgHeight = width/9;
Glide.with(PermissionActivity.this)
.load(R.drawable.privacy_mobile_img)
.override(imgWidth, imgHeight )
.into(imgUserPerm);
Use Glide to load the image because it will resize it for small, mid, or any size device. I used width / 6 as an example, you can adjust as needed.

How to calculate the ScreenSize exactly under the consideration of Samsung Galaxy Edge in android

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;

Fixed Size Screen Element

I attempted to make a simple app to see if I could make an element a fixed size, in this case 4cm wide, regardless of device. To do this I tried to use the screen xDPI, use that as an inch, multiply that by a constant to get 4cm. It doesn't appear this is working after trying it on a few different devices.
final WindowManager w = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
final Display d = w.getDefaultDisplay();
final DisplayMetrics m = new DisplayMetrics();
d.getMetrics(m);
//find the correct x density and multiply it by 1.5748 to get 4cm
float density = m.xdpi;
density = (float) (density * 1.5748);
int intDensity = (int)Math.ceil(density);
//now set the view to be the dimensions that you want, it must be inside of it's own layout?
box.setLayoutParams(new LinearLayout.LayoutParams(intDensity,100));
Any suggestions?

Categories

Resources