How do you specify in AndroidManifest.xml that you want to forbid installing on devices smaller than a 4.7-inch device?
Asked Answered
G

4

12

I have a game that feels best on 7-inch tablets, and feels acceptably nice on 10-inch tablets and 5-inch Samsung Note-size devices. It's even just passably fun on something the size of a Nexus 4 phone or an S3. It is not at all fun to play on anything smaller. That being the case, how can a Manifest be written such that it can install on anything from a 4.7-inch device to a 10-inch tablet while being restricted from smaller phones?

EDIT

Stepping back for a moment, the reason for this question is because I find the documentation on the Android developer website to be incredibly confusing and conflicting. Let's give some examples to show just where the confusion comes from :

Let's take for example a couple of different devices.

Droid 3

  • 4-inch display
  • 540x960 px
  • 275 ppi

Looking at the documentation for supports-screens, we can infer that...

  • At 4 inches it may be on the bare edge of "large" but probably medium
  • At 540x960 it is well within the minimum for "large"
  • at 275 ppi it claims to be an hdpi screen

However, this device is far smaller than one that I would want to support... but the documentation makes it seem like on 2 of 3 counts, this device has a "Large" screen. By no sane definition of the term is a 4-inch screen "Large." Now, let's go further...

Nexus 4

  • 4.7 inch display
  • 768x1280 px
  • 318 ppi

Looking at the documentation for supports-screens, we can infer that...

  • This screen's physical dimensions are right on the border of Medium and Large
  • The pixel dimensions would indicate that it could be xlarge
  • The ppi indicate that it is an xhdpi device

Again, by no sane definition is a 4.7 inch screen "xlarge"... The screen's size is possibly just large enough to make the game enjoyable, but is it a "medium" screen? A "large" screen? How can you possibly know?

Would both of the above phones be "Medium"? Would the Droid be "Medium" while the Nexus "Large"? Why or why not? And if the Nexus is "Large" then how is that distinct from a 7 inch tablet, which also should be "Large?"

And then there's the fact that the docs claim that supports-screens/size is deprecated as of 3.2 anyway

But then there's no clear guidance on what to use in its place if one wants to support both old phones (assuming proper physical screen size in inches) and new tablets, or if there is it's hidden well out in the woods. Can someone lay out clearly what cretieria really matter and why a given device will fit a given filter or fail it?

Gretchengrete answered 28/1, 2013 at 20:0 Comment(0)
L
3

Unfortunately, there is NO way to filter-out devices according to their 'PHYSICAL' sizes, which is what you want.

There are two reasons.

  1. There are only four types of screen sizes: small, normal, large and x-large. This is too coarse. You want much higher granularity: 'filter out devices which LCD is less than 4.7 inch', which is not supported in current Android platform.
  2. Screen size is determined by the logical density which can be set to a value far different than the physical density. For exaple, let's assume that a device has 5 inch screen with physical density of 180 ppi. This is probably the screen that you want to support. However, for some reason, the manufacturer decide to set the logical density of the device as 320 dpi. Then the device is categorized as small screen device regardless of its physical density.

For your reference, let me show you the internal logic that determines the screen size from the logical density and screen pixel count.

http://androidxref.com/4.0.4/xref/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java#5899

Lewellen answered 14/2, 2013 at 16:33 Comment(1)
I think this might be the closest thing to a correct answer that this issue has. The extra details and link to the Android source code make it more apparent regarding the what and the why of the problem. Thanks for the explanation on why the sort of filtering I'm looking for is not feasible. That's even apart from the fact that Google doesn't even support their own filtering criteria as per android:requiresSmallestWidthDp being ignored.Gretchengrete
A
6

I think based on Google docs this will serves your requirements (5" and smaller):

<compatible-screens>

    <screen android:screenSize="large" android:screenDensity="ldpi" />
    <screen android:screenSize="large" android:screenDensity="mdpi" />

    <screen android:screenSize="xlarge" android:screenDensity="ldpi" />
    <screen android:screenSize="xlarge" android:screenDensity="mdpi" />
    <screen android:screenSize="xlarge" android:screenDensity="hdpi" />
    <screen android:screenSize="xlarge" android:screenDensity="xhdpi" />

</compatible-screens>

Or using this (4.7" and smaller):

<supports-screens android:smallScreens="false"
                  android:normalScreens="true"
                  android:largeScreens="true"
                  android:xlargeScreens="true"
                  android:requiresSmallestWidthDp="536" />

I recommend the second method because it is more accurate.

How 536 is calculated ? Based on http://developer.android.com/guide/practices/screens_support.html we have (height x width):

  • xlarge screens are at least 960dp x 720dp
  • large screens are at least 640dp x 480dp
  • normal screens are at least 470dp x 320dp
  • small screens are at least 426dp x 320dp

(720 - 480) / (7 - 4) = 80, 480 + (80 * 0.7) = 536

And do not worry about "deprecated warning", since the new suggested method is for tablet apps (IMO) which the UI is not full-screen and some spaces from bottom and top of screen occupied for Title-bar and/or back, menu etc. buttons while your game probably runs in full screen mode.

Check this from Google docs at http://developer.android.com/guide/practices/screens_support.html#DeclaringTabletLayouts :

Note: The sizes that you specify using these qualifiers are not the actual screen sizes. Rather, the sizes are for the width or height in dp units that are available to your activity's window. The Android system might use some of the screen for system UI (such as the system bar at the bottom of the screen or the status bar at the top), so some of the screen might not be available for your layout. Thus, the sizes you declare should be specifically about the sizes needed by your activity—the system accounts for any space used by system UI when declaring how much space it provides for your layout. Also beware that the Action Bar is considered a part of your application's window space, although your layout does not declare it, so it reduces the space available for your layout and you must account for it in your design.

Adowa answered 10/2, 2013 at 21:3 Comment(9)
Thank you for the detailed response. I'm not sure why you chose the values you did for your equation, though. Your guess that I'll be running full-screen is correct, by the way (though I still will have the system bar along the bottom of the screen of course)Gretchengrete
Unfortunately trying this still managed to lose the most important end of the 4.7-inch market, while including the medium sized devices still gives you a load of 3" screens as well. It seems that to add insult to injury that Google Play ignores android:requiresSmallestWidthDp in its filtering, which seems surprisingly odd.Gretchengrete
4" screens at least have 480dp width (according to Google docs) and 7" screens have 720dp width, so I calculated the "slope" ( en.wikipedia.org/wiki/Slope ) and result was 80dp which means that by each 1" increase in screen size the width will be increased by 80dp. Since you wanted to support 4.7" screens, I added 80 * 0.7 to 480 (4" screens' minimum dp) and ta-da ! The answer is 536dp which is the least width for 4.7" screens.Adowa
@scriptocalypse: If Google Play ignores android:requiresSmallestWidthDp then I should say there is no other way to implement this rather than the first method that I suggested :/ Although the second one is correct and accurate IMO.Adowa
those numbers do make sense in that context. Perhaps some day Google's market will actually honor the results of that formula. :) Unfortunately, 4.7 inch devices appear to fall into the "Medium" category, so leaving it out isn't an option and there's no guarantee that a device will be on the high or low end of "Medium" based solely on density / ppi.Gretchengrete
This will filter-out devices such as Nexus 4. Its logical DPI is set to 320 dpi and it has resolution of 1280x720. This screen specification is automatically recognized as 'normal-sized' screen.Lewellen
@jiyongPark : When I was writing this answer, the question was about 5" screens but had been modified after that to 4.7". Check this revision stackoverflow.com/revisions/14570173/6 . Although I changed the calculation to meet criteria but I forget to make small-screens available. Thanks for pointing it out, I edited my answer. Anyway I strongly remain confident that my approach is the only way to solve this problem for now.Adowa
I do hope some day that Google will use the requiresSmallestWidthDP property. That should make this solution work once they do, but they don't make any guarantees or promises that they'll ever do so.Gretchengrete
Note that requiresSmallestWidthDp="536" will also filter out 5" devices (such as Nexus 5 whose smallestWidthDp is 360: 1080 pixels, density 3)!Payton
L
3

Unfortunately, there is NO way to filter-out devices according to their 'PHYSICAL' sizes, which is what you want.

There are two reasons.

  1. There are only four types of screen sizes: small, normal, large and x-large. This is too coarse. You want much higher granularity: 'filter out devices which LCD is less than 4.7 inch', which is not supported in current Android platform.
  2. Screen size is determined by the logical density which can be set to a value far different than the physical density. For exaple, let's assume that a device has 5 inch screen with physical density of 180 ppi. This is probably the screen that you want to support. However, for some reason, the manufacturer decide to set the logical density of the device as 320 dpi. Then the device is categorized as small screen device regardless of its physical density.

For your reference, let me show you the internal logic that determines the screen size from the logical density and screen pixel count.

http://androidxref.com/4.0.4/xref/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java#5899

Lewellen answered 14/2, 2013 at 16:33 Comment(1)
I think this might be the closest thing to a correct answer that this issue has. The extra details and link to the Android source code make it more apparent regarding the what and the why of the problem. Thanks for the explanation on why the sort of filtering I'm looking for is not feasible. That's even apart from the fact that Google doesn't even support their own filtering criteria as per android:requiresSmallestWidthDp being ignored.Gretchengrete
S
1

That being the case, how can a Manifest be written such that it can install on anything from a 4.7-inch device to a 10-inch tablet while being restricted from smaller phones?

Technically speaking, you can't.

android:requiresSmallestWidthDp comes closest to your desired aim. Since this is measured in density-independent pixels, and since a density-independent pixel is supposed to be 1/160th of an inch, you can come up with a dp value for any number of inches by multiplying by 160.

However, this is not referring to a diagonal, as per your request. This refers to the width of the shortest side (e.g., width in portrait, height in landscape).

So, if you can recast your desire in terms of smallest width, use android:requiresSmallestWidthDp, and pray that the documentation is just messed up when it refers to whether Google Play honors it. You'll be able to determine that when you upload the app to the Play Store Developer Console and see what devices support it -- find some device you know is too small (but otherwise should run your app) and see if it is filtered.

If the documentation for android:requiresSmallestWidthDp is correct, and the Play Store is ignoring it for filtering purposes (grrrrr...), then you're largely screwed. The next-closest solution would be to use <compatible-screens> per the other answer, claiming that you only support large and xlarge screen sizes. That will knock out various devices that are on the low end of the range that you'd like to support, but normal screen size gets much smaller (down to 3" diagonal) than what you want.

BTW, normal is 3"-5" diagonal, so the Droid 3 is normal, not large. Pixel dimensions have absolutely nothing to do with screen size.

Surculose answered 11/2, 2013 at 0:27 Comment(2)
It appears that the documentation is in fact correct in that android:requiresSmallestWidthDp is ignored by Google Play. I would hate to exclude devices like the S3 or the Nexus 4, so I feel I may have to just live with some small devices getting ahold of the game. My only solace may be that at least the most popular of the more modern phones seem to trend towards having larger screens.Gretchengrete
@scriptocalypse: "It appears that the documentation is in fact correct in that android:requiresSmallestWidthDp is ignored by Google Play" -- grrrrrr.Surculose
H
0

It appears that there isn't a proper way to do it in the actual application. And I agree with you about how horribly confusing and contradictory the android dev guide is. In my experience though, a good work around for that sort of thing is to just change which devices can run your app when you go to publish it in the developer console. I did a quick look though, and found a similar question here:

Filter the device screen size on the Android Market

Seems to be the best way to do it. Good luck!

Hardison answered 13/2, 2013 at 20:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.