AndroidManifest.xml — Complete Guide
The AndroidManifest.xml is the “contract” between your app and Android OS. It declares components (Activities, Services, Receivers, Providers), permissions, hardware requirements, app metadata, deep links, and more. This page builds a strong mental model, then dives into real-world snippets you can paste into your apps.
Mental Model
Components
Activities (UI), Services (background), Receivers (system events), Providers (data share)
Permissions
What your app is allowed to access (Internet, Camera, Location…)
Features
Hardware/software capabilities your app needs (camera, GPS)
Metadata
Theme, app name/icon, exported, queries, FileProvider, deep links
Skeleton Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- Permissions go here (e.g., INTERNET) -->
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.MyApp">
<!-- Launcher Activity -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<intent-filter> must declare android:exported="true|false".
Permissions — Normal vs Dangerous
| Type | Examples | Grant |
|---|---|---|
| Normal | INTERNET, ACCESS_NETWORK_STATE | Granted at install automatically. |
| Dangerous | CAMERA, READ_EXTERNAL_STORAGE, ACCESS_FINE_LOCATION | Declare in Manifest + ask at runtime (API 23+). |
Common Permissions
<!-- Network -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Camera -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Location (foreground); background is separate -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Background location (API 29+). Request only if truly needed. -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- Storage (legacy). Prefer scoped storage APIs instead. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Special (Android 11+): MANAGE_EXTERNAL_STORAGE (use only for file-manager apps) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Hardware & Software Features
Declare what your app uses with <uses-feature>.
Mark a feature required to hide your app from devices that lack it.
<!-- Camera -->
<uses-feature android:name="android.hardware.camera" android:required="false" />
<!-- GPS & Network location -->
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
required="false" if you can gracefully degrade without that feature.
Your app will then still be visible to more devices on Play Store.
Camera: Manifest + FileProvider
To capture a photo into your app’s private file, you typically use a FileProvider (content URI).
Add permission + provider in the manifest, and define file_paths.xml.
<!-- Permission -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- In <application>: FileProvider to share files securely -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
res/xml/file_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Allow sharing files from app-specific cache -->
<cache-path name="images" path="images/" />
<!-- Or external files dir (Pictures) -->
<external-files-path name="photos" path="Pictures/" />
</paths>
CAMERA permission (dangerous). Use content:// URIs with temporary URI permissions; avoid exposing file:// paths.
Geolocation (Foreground & Background)
For location, request COARSE/FINE (foreground). For continuous tracking when app isn’t visible,
background location requires an additional permission and a strong user-facing justification.
<!-- Foreground location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Background location (API 29+) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Foreground Service (Location, Media, etc.)
If you track location or play media in the background, declare foreground service type in Manifest on Android 9+.
<!-- Foreground service types (Android 9/10+) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- In <application>, for your Service -->
<service
android:name=".LocationService"
android:exported="false"
android:foregroundServiceType="location" />
Storage & Scoped Storage (Modern Approach)
Since Android 10+, the platform enforces Scoped Storage. Prefer these APIs:
- MediaStore (photos, videos, audio) — no full storage permission needed.
- Storage Access Framework (SAF) for user-picked documents.
- App-specific directories in internal/external storage.
WRITE_EXTERNAL_STORAGE unless targeting older devices; the permission is deprecated on newer targets.
Deep Links & App Links (Open URLs in Your App)
Handle URLs like https://codingwithsonu.com/article/123 directly in your app via an intent-filter.
autoVerify="true" attempts to verify on install that your domain belongs to you.
<activity
android:name=".ArticleActivity"
android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="codingwithsonu.com"
android:pathPrefix="/article" />
</intent-filter>
</activity>
Package Visibility (Android 11+)
From Android 11, apps are restricted from freely querying what other apps are installed.
If you must discover specific packages/intents, declare a <queries> section.
<queries>
<!-- Query by package name -->
<package android:name="com.example.targetapp" />
<!-- Or by intent action -->
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/*" />
</intent>
</queries>
Network Security Config & Cleartext
If you must allow HTTP (cleartext) during development or point certain domains to debug certificates, use a network security config.
<!-- Application attributes -->
<application
android:usesCleartextTraffic="false"
android:networkSecurityConfig="@xml/network_security_config" >
...
</application>
res/xml/network_security_config.xml
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
Useful <application> Attributes
| Attribute | Why it matters |
|---|---|
android:theme | Sets global app theme (colors, typography). |
android:icon, android:roundIcon | App icons for devices/launchers. |
android:allowBackup | Controls Auto Backup / Key-Value Backup behavior. |
android:supportsRtl | Enable right-to-left layout mirroring. |
android:usesCleartextTraffic | Permits or blocks HTTP traffic globally. |
android:networkSecurityConfig | Custom trust anchors, domain rules. |
android:exported (Android 12+)
For every <activity>, <service>, or <receiver> that has an <intent-filter>,
you must explicitly set android:exported="true|false".
<activity
android:name=".ShareActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
How Android Uses Your Manifest
Best Practices
- Declare only the minimum permissions. Ask dangerous permissions at runtime, just-in-time.
- Use uses-feature with
required="false"if your app can degrade gracefully. - Prefer Scoped Storage APIs; avoid legacy wide storage access.
- For background tasks, prefer WorkManager or Foreground Service with correct foregroundServiceType.
- Secure file sharing via FileProvider (never use file:// URIs).
- For Android 12+, always set
android:exportedcorrectly.
Common Mistakes
- Forgetting to declare a new Activity/Service/Receiver → ActivityNotFoundException or not receiving broadcasts.
- Requesting location/storage permissions but not handling runtime request flow.
- Using cleartext HTTP in production without a network config → requests blocked.
- Missing
android:exportedon components with intent-filters → build fails on Android 12+.