Using the uses-feature Element in Android Manifest for Hardware and Software Capability Declaration
The <uses-feature> element in an Android manifest informs external systems about hardware or software capabilities an app requires or optionally uses. It enables services such as Google Play to filter apps so that they are visible only on devices meeting those capability requirements.
Syntax
<uses-feature
android:name="string"
android:required=["true" | "false"]
android:glEsVersion="integer" />
This declaration resides within <manifest> and specifies a single capability.
Purpose and Behavior
Each <uses-feature> entry describes one hardware or software attribute. The required flag indicates whether the app can function with out it:
required="true": The feature is mandatory; absence makes the app unusable.required="false": The feature is optional; the app works regardless of presence. If omitted,requireddefaults totrue.
Capabilities correspond to constants in PackageManager. Multiple features require separate elements. For instance, requiring both Bluetooth and camera:
<uses-feature android:name="android.hardware.bluetooth" />
<uses-feature android:name="android.hardware.camera" />
Android itself does not block installation based on these declarations, but storefronts and other apps may enforce compatibility checks. Declaring all used features ensures correct filtering.
For graphics, android:glEsVersion denotes required OpenGL ES versions using a 32‑bit value: high 16 bits for major, low 16 bits for minor version (e.g., 0x00020000 for 2.0). Only one such attribute should be present; if multiple are declared, the highest value applies. Absence implies OpenGL ES 1.0 support.
Note: Declaring a capability does not replace permission requests. For example, accessing the camera still needs the CAMERA permission.
Attributes
- android:name: Feature identifier string, e.g.,
android.hardware.camera. Case-sensitive. - android:required: Boolean indicating necessity.
- android:glEsVersion: OpenGL ES version requirement.
Introduced in API level 4. Ignored on older platforms.
Filtering by Google Play
Google Play restricts app visibility by comparing declared feature needs with device capabilities reported via system properties. It constructs a list of required features from explicit <uses-feature> declarations and certain permissions.
Explicit Declarations
When a feature is explicitly declared with required="true", Play treats it as mandatory and hides the app from devices lacking it. With required="false", the feature is excluded from required set, so absence does not affect visibility.
If required is omitted, Play assumes true. For legacy apps targeting API level ≤4, all unmarked declarations are treated as required.
To disable filtering for a specific feature, declare it explicitly with required="false".
Implicit Declarations
Some features are required implicitly even if not declared, due to permissions requested. Play scans <uses-permission> entries and maps them to presumed hardware needs. For example, requesting CAMERA permission infers need for android.hardware.camera and its autofocus subfeature.
To prevent implicit filtering, explicitly declare the feature with required="false".
Bluetooth Special Handling
For Bluetooth, Play applies additional rules:
- If an app requests Bluetooth permissions but omits
<uses-feature>, filtering occurs only whenminSdkVersionortargetSdkVersion≥5. - Explicit
<uses-feature android:name="android.hardware.bluetooth"/>triggers normal filtering. - Adding
required="false"disables Bluetooth-based filtering entirely.
Examples illustrate how different SDK version declarations alter filtering outcomes.
Testing Required Features
Use aapt dump badging from the Android SDK to view effective feature requirements as Play would evaluate:
$ aapt dump badging path/to/app.apk
This outputs declared permissions, features, SDK versions, and inferred requirements.
Common Hardware Feature Identifiers
Prefix with android.hardware. for hardware items. Examples:
- Audio:
audio.low_latency,audio.output,audio.pro,microphone - Bluetooth:
bluetooth,bluetooth_le - Camera:
camera,camera.any,camera.autofocus,camera.flash,camera.front,camera.level.full - Sensors:
sensor.accelerometer,sensor.gyroscope,sensor.light,sensor.proximity - Touch:
faketouch,touchscreen,touchscreen.multitouch.distinct - Connectivity:
wifi,wifi.direct,nfc,usb.host - Graphics:
opengles.aep,vulkan.version,vulkan.level,vulkan.compute
Declare each in its own <uses-feature> element.
Common Software Feature Identifeirs
Prefixed with android.software.. Examples:
- Communication:
sip,sip.voip,webview - Device Management:
backup,device_admin,managed_users - Media:
midi,print,leanback,live_tv - UI:
app_widgets,home_screen,live_wallpaper
Permissions Implying Features
Certain permissions cause Play to infer undeclared features:
| Permission | Implied Feature(s) |
|---|---|
BLUETOOTH[_ADMIN] |
android.hardware.bluetooth |
CAMERA |
android.hardware.camera + autofocus |
RECORD_AUDIO |
android.hardware.microphone |
ACCESS_FINE_LOCATION |
android.hardware.location (+ gps if targetSdk ≤20) |
ACCESS_COARSE_LOCATION |
android.hardware.location (+ network if targetSdk ≤20) |
CALL_PHONE and related |
android.hardware.telephony |
ACCESS_WIFI_STATE etc. |
android.hardware.wifi |
Explicit <uses-feature> with required="false" overrides implied filtering for that feature.