<compatible-screens> in Android
Asked Answered
E

2

11

Good day, I am trying to restrict screen sizes to only handsets (i.e. not tablets) in google play. After I found this article I added this to my manifest file:

<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" />
    <screen android:screenSize="small" android:screenDensity="mdpi" />
    <screen android:screenSize="small" android:screenDensity="hdpi" />
    <screen android:screenSize="small" android:screenDensity="xhdpi" />
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" />
    <screen android:screenSize="normal" android:screenDensity="mdpi" />
    <screen android:screenSize="normal" android:screenDensity="hdpi" />
    <screen android:screenSize="normal" android:screenDensity="xhdpi" />
</compatible-screens>

But it appears that now users with 5.5++ inch phones cant install my app. Next I also found this article and picture in it:

enter image description here

My first question - is it possible to restrict screen size by specific inch value, or I can use only tags like small, normal, large and xlarge?

At some point I decided to increase support inch size to 7 by updating manifest like this:

<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" />
    <screen android:screenSize="small" android:screenDensity="mdpi" />
    <screen android:screenSize="small" android:screenDensity="hdpi" />
    <screen android:screenSize="small" android:screenDensity="xhdpi" />
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" />
    <screen android:screenSize="normal" android:screenDensity="mdpi" />
    <screen android:screenSize="normal" android:screenDensity="hdpi" />
    <screen android:screenSize="normal" android:screenDensity="xhdpi" />
    <!-- all large size screens -->
    <screen android:screenSize="large" android:screenDensity="ldpi" />
    <screen android:screenSize="large" android:screenDensity="mdpi" />
    <screen android:screenSize="large" android:screenDensity="hdpi" />
    <screen android:screenSize="large" android:screenDensity="xhdpi" />
</compatible-screens>

But users with 5.5 inch phones and even with 5.2 inch still cant install app.

So my second question - what I am doing wrong or don't understand?

I honestly read all similar questions on stackoverflow and articles in android documentation and didn't find proper answer. Thx.

Ely answered 3/10, 2016 at 15:11 Comment(0)
G
6

It looks like you are attempting to restrict screen sizes to only handsets, and not tablets. It is difficult to discern from your question, but either way I think I can clear up the confusion.

When you declare <compatible-screens> in your manifest you must declare every screen configuration that you would like your app to be compatible with:

You must declare each one of these; any combination of size and density that you do not specify is considered a screen configuration with which your application is not compatible.

I suspect the 5.5+ inch phones you mention have a higher density than xhdpi; such as xxhdpi or xxxhdpi. These densities are omitted from the documentation (either because the documentation is outdated or otherwise incomplete) but are still relevant; they are documented on the <compatible-screens> page.

Therefore if you want your app to be compatible with higher density devices, you must include those densities in your <compatible-screens> element. But an easier method would be to use the <supports-screens> element instead. As per the documentation, the <supports-screens> element does not take density into account:

Note: Although you can also use the <compatible-screens> element for the reverse scenario (when your application is not compatible with smaller screens), it's easier if you instead use the <supports-screens> as discussed in the next section, because it doesn't require you to specify each screen density your application supports.

With this you can just specify the following in your manifest:

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

The largestWidthLimitDp attribute should not be necessary, but 840dp seems like a good limit for handsets based on the Material Design documentation for density breakpoints.

Otherwise, you can still use the <compatible-screens> tag if you would like more fine-tuned control over which devices your app is compatible with:

<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" />
    <screen android:screenSize="small" android:screenDensity="mdpi" />
    <screen android:screenSize="small" android:screenDensity="hdpi" />
    <screen android:screenSize="small" android:screenDensity="xhdpi" />
    <screen android:screenSize="small" android:screenDensity="xxhdpi" />
    <screen android:screenSize="small" android:screenDensity="xxxhdpi" />
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" />
    <screen android:screenSize="normal" android:screenDensity="mdpi" />
    <screen android:screenSize="normal" android:screenDensity="hdpi" />
    <screen android:screenSize="normal" android:screenDensity="xhdpi" />
    <screen android:screenSize="normal" android:screenDensity="xxhdpi" />
    <screen android:screenSize="normal" android:screenDensity="xxxhdpi" />
</compatible-screens>
Grader answered 3/10, 2016 at 16:20 Comment(7)
Yeah, sorry for my English, but u understood correctly. Thx!Ely
@Bryan: Your provided solution <screen android:screenSize="small" android:screenDensity="xxhdpi" /> <screen android:screenSize="small" android:screenDensity="xxxhdpi" /> will not be compiled: "AAPT: String types not allowed (at 'screenDensity' with value 'xxxhdpi')" .I know this solution is provided by Google itself (developer.android.com/guide/topics/manifest/…) - what a joke...Exhibitor
@user2281606 Hm, it seems to compile fine for me. I know there was an issue previously, but it seems to be fixed.Grader
@Bryan: thx, what are you building against? Here are my gradle info: compileSdkVersion 23; buildToolsVersion '23.0.3'. In manifest: <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />Exhibitor
@user2281606 It could be the build tools version, I am using the latest; 25.0.1. You should still be able to use the numerical value for each density (i.e. xhdpi => 320, xxhdpi => 480, etc.), but you should probably consider upgrading to the latest build version.Grader
@Bryan, thx, I updated to 25.0.1 and it works, see my edited answerExhibitor
According to Google, you can't use supports-screens to exclude larger screens: "Caution: If you use the <supports-screens> element for the reverse scenario (when your application is not compatible with larger screens) and set the larger screen size attributes to "false", then external services such as Google Play do not apply filtering". See: developer.android.com/guide/practices/screens-distribution.htmlOffspring
E
10

EDIT (2016-12-21)

After Bryan's suggest to use build tool 25.0.1, I have no more build error with his solution:

<compatible-screens>
<!-- all small size screens -->
<screen android:screenSize="small" android:screenDensity="ldpi" />
<screen android:screenSize="small" android:screenDensity="mdpi" />
<screen android:screenSize="small" android:screenDensity="hdpi" />
<screen android:screenSize="small" android:screenDensity="xhdpi" />
<screen android:screenSize="small" android:screenDensity="xxhdpi" />
<screen android:screenSize="small" android:screenDensity="xxxhdpi" />
<!-- all normal size screens -->
<screen android:screenSize="normal" android:screenDensity="ldpi" />
<screen android:screenSize="normal" android:screenDensity="mdpi" />
<screen android:screenSize="normal" android:screenDensity="hdpi" />
<screen android:screenSize="normal" android:screenDensity="xhdpi" />
<screen android:screenSize="normal" android:screenDensity="xxhdpi" />
<screen android:screenSize="normal" android:screenDensity="xxxhdpi" />

BUT... with the new build some devices did not appear in the supported device list (Google Play console): Google Pixel, Nexus 5x, Google Pixel XL, Nexus 6, Nexus 6P.

That's why my new solution looks like this:

<!-- just handsets allowed-->
<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" /> <!-- 120 -->
    <screen android:screenSize="small" android:screenDensity="mdpi" /> <!-- 160 -->
    <screen android:screenSize="small" android:screenDensity="hdpi" /> <!-- 240 -->
    <screen android:screenSize="small" android:screenDensity="280" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="xhdpi" /> <!-- 320 -->
    <screen android:screenSize="small" android:screenDensity="360" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="420" /> <!-- Workaround Google Pixel, Nexus 5x -->
    <screen android:screenSize="small" android:screenDensity="xxhdpi" /> <!-- 480 -->
    <screen android:screenSize="small" android:screenDensity="560" /> <!-- Workaround Google Pixel XL, Nexus 6, Nexus 6P -->
    <screen android:screenSize="small" android:screenDensity="xxxhdpi" />  <!-- 640 -->
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" /> <!-- 120 -->
    <screen android:screenSize="normal" android:screenDensity="mdpi" /> <!-- 160 -->
    <screen android:screenSize="normal" android:screenDensity="hdpi" /> <!-- 240 -->
    <screen android:screenSize="normal" android:screenDensity="280" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="xhdpi" />  <!-- 320 -->
    <screen android:screenSize="normal" android:screenDensity="360" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="420" /> <!-- Workaround Google Pixel, Nexus 5x -->
    <screen android:screenSize="normal" android:screenDensity="xxhdpi" /> <!-- 480 -->
    <screen android:screenSize="normal" android:screenDensity="560" /> <!-- Workaround Google Pixel XL, Nexus 6, Nexus 6P -->
    <screen android:screenSize="normal" android:screenDensity="xxxhdpi" /> <!-- 640 -->
</compatible-screens>

OLD:

According to Bryan's answer, my manifest snippet looks like this:

 <!-- just handsets allowed-->
<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" /> <!-- approximately 120 dpi -->
    <screen android:screenSize="small" android:screenDensity="mdpi" /> <!-- approximately 160 dpi -->
    <screen android:screenSize="small" android:screenDensity="hdpi" /> <!-- approximately 240 dpi -->
    <screen android:screenSize="small" android:screenDensity="280" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="xhdpi"/> <!-- approximately 320 dpi -->
    <screen android:screenSize="small" android:screenDensity="360" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="420" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="480" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="560" /> <!-- Workaround -->
    <screen android:screenSize="small" android:screenDensity="640" /> <!-- Workaround -->
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" /> <!-- approximately 120 dpi -->
    <screen android:screenSize="normal" android:screenDensity="mdpi" /> <!-- approximately 160 dpi -->
    <screen android:screenSize="normal" android:screenDensity="hdpi" /> <!-- approximately 240 dpi -->
    <screen android:screenSize="normal" android:screenDensity="280" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="xhdpi"/> <!-- approximately 320 dpi -->
    <screen android:screenSize="normal" android:screenDensity="360" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="420" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="480" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="560" /> <!-- Workaround -->
    <screen android:screenSize="normal" android:screenDensity="640" /> <!-- Workaround -->
</compatible-screens>

Could not use Bryan's solution because i got a compilation error: "AAPT: String types not allowed (at 'screenDensity' with value 'xxxhdpi')"

It works for (newer) devices like Google Pixel (2.6 * 160 dp = 416 dp -> 420dp -> explanation:) / Pixel XL (3.5 * 160 dp = 560 dp) or Samsung Galaxy S6 (4.0 * 160 dp = 640 dp). The dp-Values are described here: https://material.io/devices/

I think this works because the devices I mentioned above, appeared in "supported devices" list in Google Play console.

Exhibitor answered 19/12, 2016 at 14:28 Comment(3)
Now is 2020 and this is still an issue.. official documentation didn't mention anything about 280, 320, 480 and 640 but if you don't include them those devices won't be able to install them like you said!Poindexter
The list need to be updated, since then Google Pixel 3, 4 and 5 are out. Need to add additional two densities: 400 for Pixel 3a XL and 440 for Pixel 3/3a/4/4a/5. I only checked Pixel line and Nexus line though so not sure if there's other new devices with special densities out there :(Poindexter
Update on my comment above: Seems like 400 and 440 are not supported values in compatible-screens (Google Play throws an error if you try to upload) and there's no workaround according to #57853200 so if you're specifying compatible-screens at all, pixel 3,4,5 users won't be able to install the app :(Poindexter
G
6

It looks like you are attempting to restrict screen sizes to only handsets, and not tablets. It is difficult to discern from your question, but either way I think I can clear up the confusion.

When you declare <compatible-screens> in your manifest you must declare every screen configuration that you would like your app to be compatible with:

You must declare each one of these; any combination of size and density that you do not specify is considered a screen configuration with which your application is not compatible.

I suspect the 5.5+ inch phones you mention have a higher density than xhdpi; such as xxhdpi or xxxhdpi. These densities are omitted from the documentation (either because the documentation is outdated or otherwise incomplete) but are still relevant; they are documented on the <compatible-screens> page.

Therefore if you want your app to be compatible with higher density devices, you must include those densities in your <compatible-screens> element. But an easier method would be to use the <supports-screens> element instead. As per the documentation, the <supports-screens> element does not take density into account:

Note: Although you can also use the <compatible-screens> element for the reverse scenario (when your application is not compatible with smaller screens), it's easier if you instead use the <supports-screens> as discussed in the next section, because it doesn't require you to specify each screen density your application supports.

With this you can just specify the following in your manifest:

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

The largestWidthLimitDp attribute should not be necessary, but 840dp seems like a good limit for handsets based on the Material Design documentation for density breakpoints.

Otherwise, you can still use the <compatible-screens> tag if you would like more fine-tuned control over which devices your app is compatible with:

<compatible-screens>
    <!-- all small size screens -->
    <screen android:screenSize="small" android:screenDensity="ldpi" />
    <screen android:screenSize="small" android:screenDensity="mdpi" />
    <screen android:screenSize="small" android:screenDensity="hdpi" />
    <screen android:screenSize="small" android:screenDensity="xhdpi" />
    <screen android:screenSize="small" android:screenDensity="xxhdpi" />
    <screen android:screenSize="small" android:screenDensity="xxxhdpi" />
    <!-- all normal size screens -->
    <screen android:screenSize="normal" android:screenDensity="ldpi" />
    <screen android:screenSize="normal" android:screenDensity="mdpi" />
    <screen android:screenSize="normal" android:screenDensity="hdpi" />
    <screen android:screenSize="normal" android:screenDensity="xhdpi" />
    <screen android:screenSize="normal" android:screenDensity="xxhdpi" />
    <screen android:screenSize="normal" android:screenDensity="xxxhdpi" />
</compatible-screens>
Grader answered 3/10, 2016 at 16:20 Comment(7)
Yeah, sorry for my English, but u understood correctly. Thx!Ely
@Bryan: Your provided solution <screen android:screenSize="small" android:screenDensity="xxhdpi" /> <screen android:screenSize="small" android:screenDensity="xxxhdpi" /> will not be compiled: "AAPT: String types not allowed (at 'screenDensity' with value 'xxxhdpi')" .I know this solution is provided by Google itself (developer.android.com/guide/topics/manifest/…) - what a joke...Exhibitor
@user2281606 Hm, it seems to compile fine for me. I know there was an issue previously, but it seems to be fixed.Grader
@Bryan: thx, what are you building against? Here are my gradle info: compileSdkVersion 23; buildToolsVersion '23.0.3'. In manifest: <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />Exhibitor
@user2281606 It could be the build tools version, I am using the latest; 25.0.1. You should still be able to use the numerical value for each density (i.e. xhdpi => 320, xxhdpi => 480, etc.), but you should probably consider upgrading to the latest build version.Grader
@Bryan, thx, I updated to 25.0.1 and it works, see my edited answerExhibitor
According to Google, you can't use supports-screens to exclude larger screens: "Caution: If you use the <supports-screens> element for the reverse scenario (when your application is not compatible with larger screens) and set the larger screen size attributes to "false", then external services such as Google Play do not apply filtering". See: developer.android.com/guide/practices/screens-distribution.htmlOffspring

© 2022 - 2024 — McMap. All rights reserved.