does cocos2d-x support android's XHDPI mode? - android

I want to know if cocos2d-x support android's XHDPI mode
and if yes, how to do that?

Yes you can do that.
For that you'll have to write a native function which will return you the dpi of the device.
Accordingly you can then set the directory for resources.
Here is the native code in java which will return you the the dpi of screen.
Write this code in Cocos2dxActivity (library file for cocos2d-x android)
static int dpiValue;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
dpiValue = dm.densityDpi;
public static int deviceDPI()
{
return dpiValue;
}
Now in your AppDelegate.cpp you can get this value and set the resource folder accordingly
Here is the example code for that
//getting dpi in case of android
JniMethodInfo t;
JniHelper::getStaticMethodInfo(t
, "org/cocos2dx/lib/Cocos2dxActivity"
, "deviceDPI"
, "()I");
int deviceDPI = t.env->CallIntMethod(t.classID, t.methodID, NULL);
CCLog("DPI of screen is %d", deviceDPI);
if(deviceDPI <= 120)
{
//ldpi
}
else if(deviceDPI <= 160)
{
//mdpi
}
else if(deviceDPI <= 240)
{
//mdpi
}
else
{
//xhdpi
}
Hope this helps you!! :)

You can simply use the function CCDevice::getDPI()
If that doesn't help you, you should read this one carefully, it really helped me a lot.
Hope it helps you too

Related

Is there a list of all android values folder?

I need to know which device uses which values folder. I couldn't find any code like this. I just wanted to do this.
public String getValuesFolder(){
....
return "values-sw600dp";//after this method finished, it would give me correctly unique values-folder
}
But after some searching, there is no method like this. So I just decided to create all values folder in the test project. Every values folder has a string.xml that contains its name, for example
in values-v19
->string.xml
<string name="folder_name">v19</string>
In this way, If I have all values folder in this test project, I would learn easily which values folder be in use?
But I couldn't find any full list. Is there any list like that?
You can use the combination of following values to figure out the values being used based on the device the app is running.
private void getDisplayDensity() {
// this will return you the density of the screen - hdpi/xhdpi/xxhdpi/xxxhdpi...etc
float density = getResources().getDisplayMetrics().density;
if (density >= 4.0) {
//xxxhdpi
} else if (density >= 3.0) {
//xxhdpi
} else if (density >= 2.0) {
//xhdpi
} else if (density >= 1.5) {
//hdpi
} else if (density >= 1.0) {
//mdpi
} else {
//ldpi
}
}
public double getDeviceScreenSize(Activity activity) {
//this will return you screen size of the device like 5.5 or 7 inches etc.
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
return Math.sqrt(x + y);
}
If you have folders like values-sw600dp that will used if density of the device is xhdpi and screen size is more that 7 inches. similarly, you can figure out this based screen size and density matrix as shown in the images below to create a generic logic for the same.

How to handle different screen resolutions on Android?

Nexus 10 holds 2500*1600 resolution whereas the previous neighbor in the same density family holds 1024*800 - ** DOUBLE **
My concern is completely on images, I already hold images of x*x px, If I use the same image in Nexus - it stretches ?
How to handle these type of resolutions ?
There are many possible ways to achieve this one of the major thing is using components size
width -- height in dp,
text size in sp
other is you can use layout-ldpi, layout-mdpi, layout-hdpi, layout-xhdpi
dp and sp will solve your problem
http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
You should have alternative resources depending on screen resolution.
For example if you want alternative layout for extra large screens, you need to place the alternative layouts in layout-xlarge. The general rule is resources_name-qualifier. You can find out about the options in the android guide for supporting multiple resolutions and screen sizes: http://developer.android.com/guide/practices/screens_support.html
Arun chandravanshi
Handle multiple resolutions in android:
1) In android Application project anatomy 4 folder 1) hdpi,mdpi,ldpi and xhdpi (in res folder ) you can put your images here for multiple screen size devices. The system automatically choose images from these folder according to device.
2) use sp instead of dp when give font size.
3) us dp in place of px.
4) Mostly us Linear layout and Relative layout instead of other layout.
5) Use 9 patch images.
6) Avoid using of Absolute layout.
7) use png images.
8) use layout-land folder for landscape mode.
Thanks.
you can determine the size of the screen by code and then apply the necessary code. for example, I need to change text size base on different screen resolution.
public void setMainButtonTextSize(){
if (isXLargeScreen()){
mainButtonTextSize = 38;
mainButtonDownTextSize = 32;
titleTopButtonTextSize = 80;
titleBottomButtonTextSize = 60;
timeTextSize = 36;
dayTextSize = 26;
dateTextSize = 36;
} else if (isLargeScreen()){
mainButtonTextSize = 28;
mainButtonDownTextSize = 22;
titleTopButtonTextSize = 70;
titleBottomButtonTextSize = 50;
timeTextSize = 26;
dayTextSize = 16;
dateTextSize = 26;
} else if (isNormalScreen()){
mainButtonTextSize = 18;
mainButtonDownTextSize = 14;
titleTopButtonTextSize = 40;
titleBottomButtonTextSize = 30;
timeTextSize = 16;
dayTextSize = 12;
dateTextSize = 16;
} else if (isSmallScreen()){
mainButtonTextSize = 12;
mainButtonDownTextSize = 10;
titleTopButtonTextSize = 30;
titleBottomButtonTextSize = 20;
timeTextSize = 12;
dayTextSize = 8;
dateTextSize = 12;
}
}
public Boolean isLargeScreen(){
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
return true;
} else
return false;
}
public Boolean isNormalScreen(){
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
return true;
} else
return false;
}
public Boolean isSmallScreen(){
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
return true;
} else
return false;
}
public Boolean isXLargeScreen(){
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
return true;
} else
return false;
}
depending on the return value, i change the text size accordingly.
The points in this thread are generic tips to design layouts for multiple screen-
I got the answer -
We can even sub categorize the drawable's depending on resolution using drawing-sw1200-xhdpi
Regards
SS

Defining xml layout by device's resolution

I was given a task to provide devices with < 1024x800 resolution with one group of layouts and >=1024x800 - with another.
Below there's some code I'm using. Regarding on _isTablet flag application can decide which layout it should use.
Do you think it's a decent tactic or should I consider another functionality for achieving resolution-based segregation of design layouts ? Thanks.
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
final int height = display.getHeight();
final int width = display.getWidth();
_leadingSideResolution = Math.max(height, width);
if (_leadingSideResolution <= HANDSET_LAYOUT_RESOLUTION) {
_isTablet = false;
} else if(_leadingSideResolution > HANDSET_LAYOUT_RESOLUTION
&& _leadingSideResolution <= TABLET_LAYOUT_RESOLUTION) {
_isTablet = true;
}
Try this code to check whether the device is tablet or not
public boolean onTablet()
{
int intScreenSize = context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
return (intScreenSize == Configuration.SCREENLAYOUT_SIZE_LARGE) // LARGE
|| (intScreenSize == Configuration.SCREENLAYOUT_SIZE_LARGE + 1); // Configuration.SCREENLAYOUT_SIZE_XLARGE
}
if(!onTablet())
{
setContentView(R.layout.not_tablet_layout);
}
else
{
setContentView(R.layout.tablet_layout);
}
For supporting android mobile devices and tablets, android has provided a very simple solution. You can get it from: http://developer.android.com/guide/practices/screens_support.html
From this please read:
1. How to Support Multiple Screen
2. Designing alternative layouts and drawables
3. Declaring Tablet Layouts for Android 3.2
4. Configuration examples

How to know whether its a tablet or phone in android programmatically? [duplicate]

This question already has answers here:
Tablet or Phone - Android
(30 answers)
Closed 8 years ago.
I would like to get to detect whether the given device is a tablet or phone in android.I have tried the two in the simulator but none worked. Both are here:
First
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE)
{
//code
}
Second
private boolean isTabletDevice()
{
if (android.os.Build.VERSION.SDK_INT >= 11)
{
// honeycomb
// test screen size, use reflection because isLayoutSizeAtLeast is only available since 11
Configuration con = getResources().getConfiguration();
try {
Method mIsLayoutSizeAtLeast = con.getClass().getMethod("isLayoutSizeAtLeast");
Boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con, 0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
return r;
} catch (Exception x)
{
return false;
}
}
return false;
}
Try this code. You can get the screen inches
String inputSystem;
inputSystem = android.os.Build.ID;
Log.d("hai",inputSystem);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
Log.d("hai",width+"");
Log.d("hai",height+"");
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(width/dm.xdpi,2);
double y = Math.pow(height/dm.ydpi,2);
double screenInches = Math.sqrt(x+y);
Log.d("hai","Screen inches : " + screenInches+"");
create two layout folders in res folder like this layout and layout_xlarge.Create one unwanted view in layout-xlarge file.Get this unwanted view id programatically.Access that unwanted id in code within try catch blocak if you get null pointer exception then it is small device otherwise it is tablet.one more thing hide the unwanted view in layout-xlarge screen.
I think the first question to answer is what you mean by "phone" or "tablet". We may have some distinction in our minds, but in reality, your application should not care. The Asus Transformer is a tablet, the Samsung Galaxy Nexus is a phone. What is the Samsung Galaxy Note? Engadget and others call it a "phablet" -- what should your application assume in that case?
Is your definition of "tablet" any device that does not have a SIM card? That is also a faulty definition because there are many tablets that do have a built in SIM card. Is your definition of "tablet" any device that defaults to landscape mode and rotates to portrait mode? Perhaps that is one approach but I doubt that is sufficient since there could be tablets that default to portrait, or worse, have square form factors in future.
In my opinion, the best way to handle this is to use Android's guidelines and switch on UI layouts. If you think you have a clear definition of tablets versus phones and absolutely need to detect one over the other, you probably need to do something like extract the model name from the browser's user agent string and then match it against a database of names of tablets that you maintain. I know. Yuck.
place this method in onResume() and can check.
public double tabletSize() {
double size = 0;
try {
// Compute screen size
DisplayMetrics dm = context.getResources().getDisplayMetrics();
float screenWidth = dm.widthPixels / dm.xdpi;
float screenHeight = dm.heightPixels / dm.ydpi;
size = Math.sqrt(Math.pow(screenWidth, 2) +
Math.pow(screenHeight, 2));
} catch(Throwable t) {
}
return size;
}
generally tablets starts after 6 inch size.

Tablet or Phone - Android

Is there a way to check if the user is using a tablet or a phone?
I've got problems with my tilt function and my new tablet (Transformer)
As it has been mentioned before, you do not want to check whether the device is a tablet or a phone but you want to know about the features of the device,
Most of the time, the difference between a tablet and a phone is the screen size which is why you want to use different layout files. These files are stored in the res/layout-<qualifiers> directories. You can create an XML file in the directoy res/values-<same qualifiers> for each of your layouts and put an int/bool/string resource into it to distinguish between the layouts you use.
Example:
File res/values/screen.xml (assuming res/layout/ contains your layout files for handsets)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">phone</string>
</resources>
File res/values-sw600dp/screen.xml (assuming res/layout-sw600dp/ contains your layout files for small tablets like the Nexus 7)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">7-inch-tablet</string>
</resources>
File res/values-sw720dp/screen.xml (assuming res/layout-sw720dp/ contains your layout files for large tablets like the Nexus 10):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">10-inch-tablet</string>
</resources>
Now the screen type is accessible via the R.string.screen_type constant.
To detect whether or not the device is a tablet use the following code:
public boolean isTablet(Context context) {
boolean xlarge = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
boolean large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
return (xlarge || large);
}
LARGE and XLARGE Screen Sizes are determined by the manufacturer based on the distance from the eye they are to be used at (thus the idea of a tablet).
More info : http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f
This post helped me a lot,
Unfortunately I don't have the reputation necessary to evaluate all the answers that helped me.
I needed to identify if my device was a tablet or a phone, with that I would be able to implement the logic of the screen. And in my analysis the tablet must be more than 7 inches (Xlarge) starting at MDPI.
Here's the code below, which was created based on this post.
/**
* Checks if the device is a tablet or a phone
*
* #param activityContext
* The Activity Context.
* #return Returns true if the device is a Tablet
*/
public static boolean isTabletDevice(Context activityContext) {
// Verifies if the Generalized Size of the device is XLARGE to be
// considered a Tablet
boolean xlarge = ((activityContext.getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE);
// If XLarge, checks if the Generalized Density is at least MDPI
// (160dpi)
if (xlarge) {
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) activityContext;
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
// DENSITY_TV=213, DENSITY_XHIGH=320
if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
|| metrics.densityDpi == DisplayMetrics.DENSITY_TV
|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
// Yes, this is a tablet!
return true;
}
}
// No, this is not a tablet!
return false;
}
Why not calculate the size of the screen diagonal and use that to make the decision whether the device is a phone or tablet?
private boolean isTablet()
{
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
int width = displayMetrics.widthPixels / displayMetrics.densityDpi;
int height = displayMetrics.heightPixels / displayMetrics.densityDpi;
double screenDiagonal = Math.sqrt( width * width + height * height );
return (screenDiagonal >= 9.0 );
}
Of course one can argue whether the threshold should be 9 inches or less.
there is no difference. You should define what you think is the difference, and check for that. Is a galaxy tab a phone? or a tablet? and why?
You should define what specific features you are looking for, and code for that.
It seems you are looking for 'tilt'. I think this is the same as the accelerometer (is that a word?). You can just check if the device supports it, using:
public class Accel extends Activity implements SensorListener {
...
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SENSOR_ACCELEROMETER,
SENSOR_DELAY_UI);
...
}
(from http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/ . i have not tested it)
My assumption is that when you define 'Mobile/Phone' you wish to know whether you can make a phone call on the device which cannot be done on something that would be defined as a 'Tablet'. The way to verify this is below. If you wish to know something based on sensors, screen size, etc then this is really a different question.
Also, while using screen resolution, or the resource managements large vs xlarge, may have been a valid approach in the past new 'Mobile' devices are now coming with such large screens and high resolutions that they are blurring this line while if you really wish to know phone call vs no phone call capability the below is 'best'.
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
In the Google IOSched 2017 app source code, the following method is used:
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Based on Robert Dale Johnson III and Helton Isac I came up with this code Hope this is useful
public static boolean isTablet(Context context) {
TelephonyManager manager =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
//Tablet
return true;
} else {
//Mobile
return false;
}
}
public static boolean isTabletDevice(Context activityContext) {
// Verifies if the Generalized Size of the device is XLARGE to be
// considered a Tablet
boolean xlarge =
((activityContext.getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
// If XLarge, checks if the Generalized Density is at least MDPI (160dpi)
if (xlarge) {
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) activityContext;
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
// DENSITY_TV=213, DENSITY_XHIGH=320
if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
// Yes, this is a tablet!
return true;
}
}
// No, this is not a tablet!
return false;
}
So in your code make a filter like
if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
//Tablet
} else {
//Phone
}
No code needed
The other answers list many ways of programmatically determining whether the device is a phone or tablet. However, if you read the documentation, that is not the recommended way to support various screen sizes.
Instead, declare different resources for tablets or phones. You do this my adding additional resource folders for layout, values, etc.
For Android 3.2 (API level 13) on, add a sw600dp folder. This means the smallest width is at least 600dp, which is approximately the phone/tablet divide. However, you can also add other sizes as well. Check out this answer for an example of how to add an additional layout resource file.
If you are also supporting pre Android 3.2 devices, then you will need to add large or xlarge folders to support tablets. (Phones are generally small and normal.)
Here is an image of what your resources might like after adding an extra xml files for different screen sizes.
When using this method, the system determines everything for you. You don't have to worry about which device is being used at run time. You just provide the appropriate resources and let Android do all the work.
Notes
You can use aliases to avoid duplicating identical resource files.
Android docs worth reading
Supporting Multiple Screens
Supporting Different Screen Sizes
Distributing to Specific Screens
For those who want to refer to Google's code of deciding which devices will use a Tablet UI can refer to below:
// SystemUI (status bar) layout policy
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
if (shortSizeDp < 600) {
// 0-599dp: "phone" UI with a separate status & navigation bar
mHasSystemNavBar = false;
mNavigationBarCanMove = true;
} else if (shortSizeDp < 720) {
// 600-719dp: "phone" UI with modifications for larger screens
mHasSystemNavBar = false;
mNavigationBarCanMove = false;
} else {
// 720dp: "tablet" UI with a single combined status & navigation bar
mHasSystemNavBar = true;
mNavigationBarCanMove = false;
}
}
This method is a recommend by Google. I see this code in Google Offical Android App iosched
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
If screen size detection doesn't return correct value on newer devices, give a try:
/*
Returns '1' if device is a tablet
or '0' if device is not a tablet.
Returns '-1' if an error occured.
May require READ_EXTERNAL_STORAGE
permission.
*/
public static int isTablet()
{
try
{
InputStream ism = Runtime.getRuntime().exec("getprop ro.build.characteristics").getInputStream();
byte[] bts = new byte[1024];
ism.read(bts);
ism.close();
boolean isTablet = new String(bts).toLowerCase().contains("tablet");
return isTablet ? 1 : 0;
}
catch (Throwable t)
{t.printStackTrace(); return -1;}
}
Tested on Android 4.2.2 (sorry for my English.)
If you are only targeting API level >= 13 then try
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
cheers :-)
Thinking on the "new" acepted directories (values-sw600dp for example) i created this method based on the screen' width DP:
public static final int TABLET_MIN_DP_WEIGHT = 450;
protected static boolean isSmartphoneOrTablet(Activity act){
DisplayMetrics metrics = new DisplayMetrics();
act.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int dpi = 0;
if (metrics.widthPixels < metrics.heightPixels){
dpi = (int) (metrics.widthPixels / metrics.density);
}
else{
dpi = (int) (metrics.heightPixels / metrics.density);
}
if (dpi < TABLET_MIN_DP_WEIGHT) return true;
else return false;
}
And on this list you can find some of the DP of popular devices and tablet sizes:
Wdp / Hdp
GALAXY Nexus: 360 / 567
XOOM: 1280 / 752
GALAXY NOTE: 400 / 615
NEXUS 7: 961 / 528
GALAXY TAB (>7 && <10): 1280 / 752
GALAXY S3: 360 / 615
Wdp = Width dp
Hdp = Height dp
Well, the best solution that worked for me is quite simple:
private boolean isTabletDevice(Resources resources) {
int screenLayout = resources.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
boolean isScreenLarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_LARGE);
boolean isScreenXlarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE);
return (isScreenLarge || isScreenXlarge);
}
Used like this:
public void onCreate(Bundle savedInstanceState) {
[...]
if (this.isTabletDevice(this.getResources()) == true) {
[...]
}
}
I really don't want to look at the pixels sizes but only rely on the screen size.
Works well as Nexus 7 (LARGE) is detected as a tablet, but not Galaxy S3 (NORMAL).
Use this method which returns true when the device is a tablet
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
I know this is not directly an answer to your question, but other answers here give a good idea of how to identify screen size. You wrote in your question that you got problems with the tilting and this just happened to me as well.
If you run the gyroscope (or rotation sensor) on a smartphone the x- and y-axis can be differently defined than on a tablet, according to the default orientation of that device (e.g. Samsung GS2 is default portrait, Samsung GT-7310 is default landscape, new Google Nexus 7 is default portrait, although it is a tablet!).
Now if you want to use Gyroscope you might end up with a working solution for smartphones, but axis-confusion on some tablets or the other way round.
If you use one of the solutions from above to only go for screen-size and then apply
SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Y, outputRotationMatrix);
to flip the axis if it has a large or xlarge screen-size this might work in 90% of the cases but for example on the Nexus 7 it will cause troubles (because it has default portrait orientation and a large screen-size).
The simplest way to fix this is provided in the RotationVectorSample that ships with the API demos by setting the sceenOrientation to nosensor in your manifest:
<activity
...
android:screenOrientation="nosensor">
...
</activity>
com.sec.feature.multiwindow.tablet in package manager is specific only to tablet and com.sec.feature.multiwindow.phone is specific to phone.
below method is calculating the device screen's diagonal length to decide the device is a phone or tablet. the only concern for this method is what is the threshold value to decide weather the device is tablet or not. in below example i set it as 7 inch and above.
public static boolean isTablet(Activity act)
{
Display display = act.getWindow().getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
float width = displayMetrics.widthPixels / displayMetrics.xdpi;
float height = displayMetrics.heightPixels / displayMetrics.ydpi;
double screenDiagonal = Math.sqrt( width * width + height * height );
int inch = (int) (screenDiagonal + 0.5);
Toast.makeText(act, "inch : "+ inch, Toast.LENGTH_LONG).show();
return (inch >= 7 );
}
public boolean isTablet() {
int screenLayout = getResources().getConfiguration().screenLayout;
return (Build.VERSION.SDK_INT >= 11 &&
(((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) ||
((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE)));
}
It is getting increasingly harder to draw the line between phone and tablet. For instance (as of Aug 2015) the Samsung Mega 6.3 device pulls resources from the sw600dp folders -- so as far as Android is concerned it is a tablet.
The answer from #Vyshnavi works in all devices we have tested but not for Mega 6.3.
#Helton Isac answer above returns the Mega 6.3 as a phone -- but since the device still grabs resources from sw600dp it can cause other issues - for instance if you use a viewpager for phones and not for tablets you'll wind up with NPE errors.
In the end it just seems that there are too many conditions to check for and we may just have to accept that some phones are actually tablets :-P
This is the method that i use :
public static boolean isTablet(Context ctx){
return = (ctx.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Using:
Configuration.SCREENLAYOUT_SIZE_MASK
Configuration.SCREENLAYOUT_SIZE_LARGE
This is the recommended method!
why use this?
Use this method which returns true when the device is a tablet
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
i see many ways above.the Configuration class has get the right answer just below:
/**
* Check if the Configuration's current {#link #screenLayout} is at
* least the given size.
*
* #param size The desired size, either {#link #SCREENLAYOUT_SIZE_SMALL},
* {#link #SCREENLAYOUT_SIZE_NORMAL}, {#link #SCREENLAYOUT_SIZE_LARGE}, or
* {#link #SCREENLAYOUT_SIZE_XLARGE}.
* #return Returns true if the current screen layout size is at least
* the given size.
*/
public boolean isLayoutSizeAtLeast(int size) {
int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
return cur >= size;
}
just call :
getResources().getConfiguration().
isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
it's ok?
I needed to detect the smartphone/tablet only in the layout file, because I'm using the navigation code.
What I did first was to create a layout-sw600dp directory but it was not working well because it would activate on my Nokia 8 in landscape mode, but the screen height would be too small.
So, I renamed the directory as layout-sw600dp-h400dp and then I got the desired effect. The h-xxxdp parameter should depend on how much content you want to drop on your layout and as such should be application dependent.
Please check out below code.
private boolean isTabletDevice() {
if (android.os.Build.VERSION.SDK_INT >= 11) { // honeycomb
// test screen size, use reflection because isLayoutSizeAtLeast is
// only available since 11
Configuration con = getResources().getConfiguration();
try {
Method mIsLayoutSizeAtLeast = con.getClass().getMethod(
"isLayoutSizeAtLeast", int.class);
boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con,
0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
return r;
} catch (Exception x) {
x.printStackTrace();
return false;
}
}
return false;
}
I think a tablet has a min and max 600 px width and height,
so need to know the screen density and the height/width in dp,
to retrieve the value :
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
float density = metrics.density;
if((width/density>=600 && height/density>=600))
isTablette = true;
else
isTablette = false;
E.g. have one important difference (at least for my program) between the phone and tablet. It is the default orientation of the device. Phone has a portrait orientation, the tablet - landscape. And respectively method to determine the device:
private static boolean isLandscapeDefault(Display display) {
Log.d(TAG, "isTablet()");
final int width = display.getWidth();
final int height = display.getHeight();
switch (display.getOrientation()) {
case 0: case 2:
if(width > height) return true;
break;
case 1: case 3:
if(width < height) return true;
break;
}
return false;
}
EDITED:
Following the discussions with Dan Hulme changed the name of the method.
I'm recommend android library 'caffeine' That's contain get Phone or tablet, and 10inch~!
very easy use.
the library is here.
https://github.com/ShakeJ/Android-Caffeine-library
and use
DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);
For me the distinction between phone and tablet is not size of device and/or pixel density, which will change with technology and taste, but rather the screen ratio. If I'm displaying a screen of text I need to know if, say, 15 long lines are needed (phone) vs 20 shorter lines (tablet). For my game I use the following for a ballpark estimation of the rectangle my software will be dealing with:
Rect surfaceRect = getHolder().getSurfaceFrame();
screenWidth = surfaceRect.width();
screenHeight = surfaceRect.height();
screenWidthF = (float) screenWidth;
screenHeightF = (float) screenHeight;
widthheightratio = screenWidthF/screenHeightF;
if(widthheightratio>=1.5) {
isTablet=false;
}else {
isTablet=true;
}
I think this is the easiest way to be honest. This will check the screen size that's being used:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Best of luck!

Categories

Resources