Galaxy Note 5: Density Reduced Automatically - android

I created an app that relies on some screen metrics to function. It works great on all devices, except for the Galaxy Note 5. On the note 5 it reports the screen size of 1080x1920 while the screen is actually 1440x2560. I also see the following message in logcat:
"ActivityThread﹕ Switching default density from 560 to 420"
I'm finding the screen size by calling getWindowVisibleDisplayFrame in the following code:
Rect usable_rect = new Rect();
Window window = activity.getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(usable_rect);
One other odd observation, if I use a package name other then my released app's package name the correct metrics are returned. Please help!

We finally found the answer to the Note 5 reducing the usable space for our app/game. It turned out Samsung is doing some optimization on the usable screen size for battery performance. The only way we found to use the true screen size of the display is by downloading Samsung's Game Tuner app and setting the mode to "Maximum Quality". It appears that without the Game Tuner app installed the default "Balanced Quality" is used, which results in the 1080p usable area.
https://play.google.com/store/apps/details?id=com.samsung.android.gametuner.thin&hl=en

Try this
Point size = new Point();
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
w.getDefaultDisplay().getSize(size);
mWindowWidth = size.x;
mWindowHeight = size.y;
} else {
Display d = w.getDefaultDisplay();
mWindowWidth = d.getWidth();
mWindowHeight = d.getHeight();
}

Related

Change the system display size programmatically Android N

Background: Android N comes with a feature to change system Display Size from settings, in addition to the previously present feature of changing Font Size.
Change Display Size:
Image Source: pcmag.com
Question:
If an app has android.permission.WRITE_SETTINGS permission to change the settings, there are ways to change the system font size programatically as mentioned in How to programmatically change font settings of Device: font style and font size?. However I couldn't find a way to change the display size programmatically. Is it possible?
What I've tried?
I've checked the possible options in the list of Settings.System convenience functions provided for changing settings programmatically.
Update:
I've opened a feature request for the same here: https://code.google.com/p/android/issues/detail?id=214124 . If you feel it would be useful please star it.
Just share my approach to tackle this requirement. I achieve this function by using the dirty Java reflection method - although it's not that elegant.
The main reference source code files are:
ScreenZoomSettings.java (https://github.com/aosp-mirror/platform_packages_apps_settings/blob/master/src/com/android/settings/display/ScreenZoomSettings.java)
DisplayDensityUtils.java (http://androidxref.com/9.0.0_r3/xref/frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java)
WindowManagerGlobal.java (http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/WindowManagerGlobal.java)
And, follow the below steps, then you can get the required control:
Read ZoomScreenSettings.java's onCreate() and commit(). They demonstrate how to correctly get and set the density value into the framework.
Read DisplayDensityUtils.java. It shows how to use WindowManagerService to control the system density. Because we can't get the instance of DisplayDensityUtils via reflection, we need to understand which WindowManagerService methods are utilized.
Use reflection to get WindowManagerService's instance, and write a DisplayDensityUtils-like class into your project.
// Where wm is short for window manager
val wmGlobalClz = Class.forName("android.view.WindowManagerGlobal")
val getWmServiceMethod = wmGlobalClz.getDeclaredMethod("getWindowManagerService")
val wmService = getWmServiceMethod.invoke(wmGlobalClz)
val wmInterfaceClz = Class.forName("android.view.IWindowManager")
// Now, we already have the ability to do many things we want.
// For instance, to get the default density value.
val getInitialDisplayDensityMethod = wmInterfaceClz.getDeclaredMethod(
"getInitialDisplayDensity",
Integer.TYPE
)
val defaultDensity = getInitialDisplayDensityMethod.invoke(
wmService,
Display.DEFAULT_DISPLAY
) as Int
Set or get the density value with your DisplayDensityUtils-like class. One thing just to mention is that, if you want to pass an index value (e.g., 2 for large display size), please feed it to your DisplayDensityUtils-like class's mValues array to get the actual density value which is the right one to pass to the framework. Getting the current density index also applies the same concept.
In manifest, under application: android:configChanges="density"
In an activity/application:
public void adjustDisplayScale(Configuration configuration) {
if (configuration != null) {
Log.d("TAG", "adjustDisplayScale: " + configuration.densityDpi);
if(configuration.densityDpi >= 485) //for 6 inch device OR for 538 ppi
configuration.densityDpi = 500; //decrease "display size" by ~30
else if(configuration.densityDpi >= 300) //for 5.5 inch device OR for 432 ppi
configuration.densityDpi = 400; //decrease "display size" by ~30
else if(configuration.densityDpi >= 100) //for 4 inch device OR for 233 ppi
configuration.densityDpi = 200; //decrease "display size" by ~30
DisplayMetrics metrics = getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.densityDpi * metrics.density;
this.getResources().updateConfiguration(configuration, metrics);
}
}
Call it just after super.onCreate(..):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adjustDisplayScale( getResources().getConfiguration());
This will set the Display Size in-between the "Smaller" and "Small" settings of "Display Size" overriding any Display Size settings set by user.
It self-adjusts correctly for 4in, 5.5in, 6in etc devices.. but I'm sure there would a better way than using those if statements.
While referring Settings.System , there is a [putConfiguration(ContentResolver cr, Configuration config)](https://developer.android.com/reference/android/provider/Settings.System.html#putConfiguration(android.content.ContentResolver, android.content.res.Configuration)) method.
Use of this method is:
Convenience function to write a batch of configuration-related settings from a Configuration object.
In Configuration
This includes both user-specified configuration options (locale list and scaling) as well as device configurations (such as input modes, screen size and screen orientation).
Set configuration with SCREENLAYOUT_SIZE_MASK values for screen size.
It is:
The SCREENLAYOUT_SIZE_MASK bits define the overall size of the screen. They may be one of SCREENLAYOUT_SIZE_SMALL, SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_LARGE, or SCREENLAYOUT_SIZE_XLARGE.
I hope its helps you.

galaxy s7 edge drag and drop

I have a user who has uprgraded from Samsung Galaxy S6 Edge to Samsung Galaxy S7 Edge.
My app has the ability to drag and drop playing card images.
The user indicates that this feature is not working on the S7 Edge but it did on the S6 Edge.
The dragging works, which suggests that the onTouch() and onDrag() are working but when an object is dropped it returns to its original position instead of the required position.
protected void measureDisplay() {
// get info about screen size to determine style of images to use
display = getWindowManager().getDefaultDisplay();
size = new Point();
display.getSize(size);
displayMetrics = new DisplayMetrics();
// get the density of the display
display.getMetrics(displayMetrics);
width = size.x;
height = size.y;
}
private void measureBoard(View v) {
// get the current view width and height
float viewWidth = v.getWidth();
float viewHeight = v.getHeight();
// extract the image offsets inside the view
Matrix matrix = ((ImageView) v).getImageMatrix();
float[] values = new float[9];
matrix.getValues(values);
boardLeft = values[2]; // the X offset
boardRight = viewWidth - boardLeft;
boardTop = values[5]; // the Y offset
boardBottom = viewHeight - boardTop;
cardOffsetW = (boardRight - boardLeft) / 10;
cardOffsetH = (boardBottom - boardTop) / 10;
}
At least some of the problems with behind-the-scenes display scaling can be solved by finding out if the user has Samsung's Game Tuner installed. It changes the Resolution Ratio for any "Game" app, and possibly does it without ever being opened.
To resolve, ask users to specify Resolution Ratio for your game in Game Tuner (they can do that on a per-app basis). See more here: DragEventListener not working on Samsung S7 (6.0)
I am working on an update for my game which would pop a message if they have Game Tuner installed.
This app:
https://play.google.com/store/apps/details?id=com.evozi.displayscaling
will resolve the issue on Samsung devices.
In our game we faced with similar problem and solution was this settings change.
I hope that Samsung will provide fix with some next OS update so we do need to inform users about this bug and forcing them to change settings.

getDesiredMinimumHeight/Width() in 'Wallapper manager'

i looked at these 2 function in the documentation here
i want to get the desired wallaper dimensions,
running those functions on an SGS3 (1280x720) with stock launcher,
i got both minDesiredWidth + minDesiredHight: 1280x1280
same thing with a Note 3 (1920x1080) i got 1920x1920
i want to know the desired ratio of wallpaper the device wants, and i thought i would get it from those 2 functions.
both those devices stock launchers have a static background image of their respective screen resolutions, so why does getDesiredMinimumWidth doesn't give me 1280/1080 for each device respectively?
how do i know the proper ratio for the device?
This is the intended result of the methods, the code used in the WallpaperManager class is:
return sGlobals.mService.getHeightHint();
and
return sGlobals.mService.getWidthHint();
It isn't mentioned anywhere why they return the same value, but to get the true values of WxH, you should use:
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getRealSize(displaySize);
and refer to the values with int width = displaySize.x and int height = displaySize.y

Android touch screen size

I would like to get the size of touch screen. For the reason, when I tested this code in the emulator the minimum values of X is 0(Y too, when pressing the 'corner' of the screen). But when I tested the code on a real devices, X shows displays 2000. So I want to read the absolute values of the screen. I think I need to get the 'minimun, maximum' values of screen. how can I read this value ?
main()
{
int fileno = open("/dev/input/event0",O_RDONLY),num_bytes;
char ev[50];
num_bytes=read(fileno,&ev,sizeof(struct input_event));
if(num_bytes<=0)
{
perror("Cannot access");
exit(FAILURE);
}
printf("%d\n",fileno);
printf("\nNumber of bytes read is %d\n string is%s\n",num_bytes,ev);
close(fileno);
}
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
This will tell you the real size of your screen in pixels, but you'll still need to account for density as well as action bar or title bar in figuring your actuall workable area.

Wrong dimensions returned from Display and DisplayMetrics in Android 3.2?

I was using this code to get full screen size in my application
Display display = getWindowManager().getDefaultDisplay();
int w = display.getWidth();
int h = display.getHeight();
On my tablet, until osVersion = 3.1, this code returned a w=1280 and h=800.
Now, after an upgrade to Os 3.2, these values are 1280x752 (when in landscape)
So it seems that something is changed from 3.1 to 3.2 regarding this call: it now returns available space, not full screen size.
I've tried using DisplayMetrics and widthPixels/heigthPixels but they return same values.
Also using the brand new display.getSize(Point p) return the same values
I've also tried changing minSdkVersion and targetSdk in my manifest file to different values without success.
How to get back full screen size in Android os 3.2 ?
My app should be compatible with android os >=1.6
The difference is due to the soft-keys. 3.2 take them into account when you query for the available screen size but 3.1 doesn't.
You will notice that if you turn the tablet to landscape mode the numbers reported will change as well.

Categories

Resources