getDesiredMinimumHeight/Width() in 'Wallapper manager' - android

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

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.

Qt Android. Get device screen resolution

I'm developing in qt 5.3 on android device. I can't get the screen resolution.
With the old qt 5 version this code worked:
QScreen *screen = QApplication::screens().at(0);
largh=screen->availableGeometry().width();
alt =screen->availableGeometry().height();
However now it doesn't work (returns a screen size 00x00). Is there another way to do it? thanks
Size holds the pixel resolution
screen->size().width()
screen->size().height();
Whereas, availableSize holds the size excluding window manager reserved areas...
screen->availableSize().width()
screen->availableSize().height();
More info on the QScreen class.
for more information, screen availableSize is not ready at the very beginning, so you have to wait for it, here is the code:
Widget::Widget(QWidget *parent){
...
QScreen *screen = QApplication::screens().at(0);
connect(screen, SIGNAL(virtualGeometryChanged(QRect)), this,SLOT(getScreen(QRect)));
}
void Widget::getScreen(QRect rect)
{
int screenY = screen->availableSize().height();
int screenX = screen->availableSize().width();
this->setGeometry(0,0,screenX,screenY);
}
I found that there are several ways to obtain the device resolution, each outputs the same results and thankfully works across all Os-es supported by Qt...
1) My favorite is to write a static function using QDesktopWidget in a reference class and use it all across the code:
QRect const CGenericWidget::getScreenSize()
{
//Note: one might implement caching of the value to optimize processing speed. This however will result in erros if screen resolution is resized during execution
QDesktopWidget scr;
return scr.availableGeometry(scr.primaryScreen());
}
Then you can just call across your code the function like this:
qDebug() << CGenericWidget::getScreenSize();
It will return you a QRect const object that you can use to obtain the screen size without the top and bottom bars.
2) Another way to obtain the screen resolution that works just fine if your app is full screen is:
QWidget *activeWindow = QApplication::activeWindow();
m_sw = activeWindow->width();
m_sh = activeWindow->height();
3) And of course you have the option that Zeus recommended:
QScreen *screen = QApplication::screens().at(0);
largh=screen->availableSize().width();
alt =screen->availableSize().height();

as3 air and screen size dection issue on devices

I have worked so hard on an app that displays perfectly on my Galaxy Note 3. However, it does not display right on iPhone and also one other Droid I tested on. My issue is with addChild() and then resizing it to fit the screen. For some reason when I add the Background (addBG(); The screen size works but if I load addChild to the BG, this works great on my Note 3 but not on the iPhone or another android device.
My issue is with the screenX, screenY var I created. They seem to be different for devices. Or it is a "rendering order issue" I am not sure. Would be so greatful for the help to fix this issue so it looks great on each phone. I have read some tuts on this subject but they are confusing. I think my code is close, I hope, and maybe it just needs a tweak. !
Here is a shot of the about screen on an IPhone. See the white does not fit the whole screen.
and Here is a shot from my Droid Note 3.
Declared Vars in a package:
This is not my full code, of course but only that which I believe is relevant.
public var screenX:int;
public var screenY:int;
public function Main()
{
if (stage)
{
setStage();
addBG();
}
}
public function setStage()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
if (flash.system.Capabilities.screenResolutionX > stage.stageWidth)
{
screenX = stage.stageWidth;
screenY = stage.stageHeight;
}
else
{
screenX = flash.system.Capabilities.screenResolutionX;
screenY = flash.system.Capabilities.screenResolutionY;
}
}
This works: addBG();
public function addBG()
{
theBG = new BG();
addChild(theBG);
theBG.width = screenX;
theBG.height = screenY;
}
This does not: addAbout();
public function addAbout()
{
About = new viewAbout();
About.width = screenX;
About.height = screenY;
theBG.addChild(About);
TweenMax.fromTo(About,1, {alpha:0}, {alpha:1, ease:Expo.easeOut} );
}
UPDATE: And yet another more complex load is also called from a button and having the same issue. I hope you see the logic of what I am trying to do. First set the BG to the device then load and resize content to fit proportionally into the BG I loaded. The reason being, the BG will be distorted to different proportions and that's ok, but the content can not. So here is the example that loads content into the BG and then content into that container.
public function addRosaryApp()
{
Rosary = new viewRosaryApp();
Rosary.width = screenX;
Rosary.height = screenY;
theBG.addChild(Rosary);
TweenMax.fromTo(Rosary,1, {alpha:0}, {alpha:1, ease:Expo.easeOut} );
contentRosary = new contentRosaryApp();
theBG.addChild(contentRosary);
contentRosary.width = screenX;
contentRosary.scaleY = contentRosary.scaleX;
contentRosary.x = screenX/2 - contentRosary.width/2;
contentRosary.y = menuBanner.height;
}
Have you tried adding the child to stage first, and then setting the size? That's the only difference I can see between addBG and addAbout
About = new viewAbout();
theBG.addChild(About); // do this first
About.width = screenX; // then set width
About.height = screenY; // and height
I think your problem may have to do with either of several things.
My findings so far from my own devices (an Ipad Air, an iphone 4S, an LG G2 and an Acer Iconia A500) is that the only device size that's being reported correctly at all times is the stage.fullScreenWidth and the stage.fullScreenHeight
1st, Android reports Capabilities.screenResolutionX as the LONG side of your Android device.
IOS devices however report the SHORT side of your device to Capabilities.screenResolutionX.
2nd, stage.stageWidth and stage.stageHeight seem to report the wrong size on both Android and IOS.
And in fact if you check these before and after setting stage.scaleMode and stage.align then the values will differ completly (although Android will show it almost correctly).
My suggestion is that you set a base size (width and height) for your app and then compare it with the actual stage.fullScreenWidth and stage.fullScreenHeight reported by the device. That way you can get some nice scaleratios to use to scale your displayobjects. That's what I'm currently on my apps and it scales just fine :-)

Which part of Android is in charge of picking a correct resource profile?

I have a weird problem.
Before you come to an idea to lash out on me, I am working on a custom Jelly Bean. Therefore the "usual nice approaches" might not work here, and dirty workarounds have to be made.
I have an APK which contains the following in assets:
layout
layout-mdpi
layout-land
layout-large-mdpi
layout-large-land-mdpi
layout-large-hdpi
layout-large-xhdpi
And some other metrics code returned this:
D/AppDemo( 2091): measured width: 1920 PE width: 1920 scaleFactor = 1.0
D/AppDemo( 2091): [ANDROID] measured width: 1920 measured height: 1080
D/AppDemo( 2091): [ANDROID] scale for resources: 2.0 xdpi: 320.0 ydpi: 320.0
D/AppDemo( 2091): [ANDROID] screen density: xhdpi
D/AppDemo( 2091): [ANDROID] screen size: large
D/AppDemo( 2091): [ANDROID] using layout: layout-mdpi
So, looking at the metrics, why isn't layout-large-xhdpi being loaded?
Please, tell me where I can look this up. I really need to find a way to force the Layout/Resource/AssetManager to load a specific layout.
I am aware the most popular comment on this issue is "you do not need / why do you have layout-xhdpi, you should have drawable-xhdpi and layout-large" but, bear with me.
I would very appreciate even small hints as to where to look at, and what to look for. So far, AssetManager seems like the place to start digging/logging.
When I omit layout-mdpi, the application crashes on me, with missing resources. The bug seems to be that even though the code returns xhdpi, it assumes mdpi somewhere else. I need to find this, and fix it so my apps look as nice as they did on ICS :)
I am figuring out which layout is loaded in a simple manner - all root layouts have a android:tag element, and when I setContentView(R.layout.main_layout) I grab the tag on the root element and know which folder got loaded. Apart from the visual feedback, this will eventually have to match with my device configuration.
Thanks in advance.
Interesting problem. I had a look, but it all goes a bit down the rabbit hole. No answer as such, but maybe my analysis will set you in the right direction.
I looked at what happened from setContentView forwards. Obviously at that point you are talking in terms of a density-agnostic layout reference (e.g. R.layout.main_layout) and then later it will be turned into a reference to a specific file in the APK. When and where is your question.
I used landscape/portrait qualifiers so that I could change the quality at runtime, and I used a debugger with the Android source attached.
Here's a flow, starting some way into it.
Resources.getLayout(int)
Resources.loadXmlResourceParser(int, String)
Resources.getValue(int, TypedValue, boolean)
AssetManager.getResourceValue(int, int, TypedValue, boolean)
StringBlock.get(int)
StringBlock.nativeGetString(int,int)
Let's work backwards.
Step 6 is a native (C) method that returns the qualified reference, e.g. /res/layout-land/yourview.xml. Its parameter is an index, however, and this changes based on whether we are in landscape or portrait.
To see where that came from we have to go back to step 4. The index is a field within the TypedValue, but it is not initially set correctly when it is passed in to this method.
Step 4 calls another native method, AssetManager.loadResourceValue(), which alters the passed in TypedValue and sets the index appropriately.
Maybe you can start looking at the C for that and see how you get on.
There are so many hacked devices in the market like Micromax Funbook which have a screen size large but uses the mdpi resources trust me I have worked with them and it was very frustrating.
As you mentioned your app is working great with every other device it's just not working with this praticular tablet you may need to implement such kinda solution posted here
http://android-developers.blogspot.in/2011/07/new-tools-for-managing-screen-sizes.html
You must read the last segment on this page it will surely help.
to summarize it here the suggested approach is to create a seperate layout with the different name using the different resources altogether.
You are driving the resource picking process here not the system. which may be time consuming but will surely help.
public class MyActivity extends Activity {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
Configuration config = getResources().getConfiguration();
if (config.smallestScreenWidthDp >= 600) {
setContentView(R.layout.main_activity_tablet);
} else {
setContentView(R.layout.main_activity);
}
}
}
I don't know if i get you right, you are building a custom AndroidOS and you want this custom AndroidOS to always load the same layout resource, in your case layout-large-xhdpi?
If so, i think you have customize the Configuration Class. If you want it quick and dirty, you could maybe override the int-Constants on line 72 and below.
Concrete, change:
....
100 public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
108 public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
to:
....
100 public static final int SCREENLAYOUT_SIZE_LARGE = 0x04;
108 public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
Other way could be to override the Constructor and the setToDefaults()-Method so it always loads the same screenlayout.
I didn't tried it out, I do not know if it is working, and I have no credible and/or official sources (Excluded offical Android Code), but i hope i could help you.

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.

Categories

Resources