Yes, Google Play does filter out content that is not appropriate for the current device. If your device doesn't have a camera, no camera apps should be visible to you, however you may still see apps using the camera as a minor feature. The distinction is made by the use of android:required
when declaring a used feature.
Note that permissions are different from features. Permissions are there for security and you declare the use of permissions by the <uses-permission>
tag. Features on the other hand is there for compatibility and you declare the use of features by the <uses-feature>
tag.
Google Play will filter your application based on what features it uses. However even if your never declare any <uses-feature>
tags in your android-manifest file, you app may still be filtered. This is because Google also reads through all of your declared permissions and infers any feature requirements you haven't explicitly declared. So if you declare the READ_SMS
permission then this implies the use of the android.hardware.telephony
feature. So it won't show up on tablets or other devices without phone capability.
Quoting this section here:
Note: Some system permissions implicitly require the availability of a device feature. For example, if your app requests permission to access to BLUETOOTH, this implicitly requires the FEATURE_BLUETOOTH device feature. You can disable filtering based on this feature and make your app available to devices without Bluetooth by setting the required attribute to "false" in the tag. For more information about implicitly required device features, read Permissions that Imply Feature Requirements.
So to avoid having your app filtered on Google Play based on a certain feature your app is using you need to explicitly declare it with android:required
set to false. Do note however that since the feature is no longer guaranteed to be present on the device your app is running on you need to check that the feature exists at run-time.
Example of what your AndroidManifest.xml should contain.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
And a quote on how google filters apps based on explicitly declared features. Link
An explicitly declared feature is one that your application declares in a element. The feature declaration can include an android:required=["true" | "false"] attribute (if you are compiling against API level 5 or higher), which lets you specify whether the application absolutely requires the feature and cannot function properly without it ("true"), or whether the application prefers to use the feature if available, but is designed to run without it ("false").
Google Play handles explicitly declared features in this way:
- If a feature is explicitly declared as being required, Google Play adds the feature to the list of required features for the application. It then filters the application from users on devices that do not provide that feature. For example:
<uses-feature android:name="android.hardware.camera" android:required="true" />
- If a feature is explicitly declared as not being required, Google Play does not add the feature to the list of required features. For that reason, an explicitly declared non-required feature is never considered when filtering the application. Even if the device does not provide the declared feature, Google Play will still consider the application compatible with the device and will show it to the user, unless other filtering rules apply. For example:
<uses-feature android:name="android.hardware.camera" android:required="false" />
- If a feature is explicitly declared, but without an android:required attribute, Google Play assumes that the feature is required and sets up filtering on it.
In general, if your application is designed to run on Android 1.6 and earlier versions, the android:required attribute is not available in the API and Google Play assumes that any and all declarations are required.
Note: By declaring a feature explicitly and including an android:required="false" attribute, you can effectively disable all filtering on Google Play for the specified feature.
Basically if you using permissions that require a feature, see this list, your should explicitly declare that feature with android:required="false"
next to it and you are good to go. But also since this feature isn't guaranteed to be there you also need to check that the feature exists at run-time before using any methods requiring it. Otherwise a tablet will crash on Phone.call(5551234)
, while with android:required="true"
you won't be required to check that the phone is there as it must be since otherwise it your app should have been filtered out. Though you might want to check it anyway as people might install it from other sources, something to consider.
Example of checking for feature at run-time.
PackageManager pm = getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
// This device does have a phone.
havePhone = true;
}
If you have more questions about this I really recommend reading through these: