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>
Android 12+: Any component with an <intent-filter> must declare android:exported="true|false".

Permissions — Normal vs Dangerous

TypeExamplesGrant
NormalINTERNET, ACCESS_NETWORK_STATEGranted at install automatically.
DangerousCAMERA, READ_EXTERNAL_STORAGE, ACCESS_FINE_LOCATIONDeclare 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" />
Important: Since Android 10–13, the platform strongly prefers Scoped Storage (MediaStore, Storage Access Framework) over legacy read/write storage permissions. Only request dangerous permissions when absolutely necessary.

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" />
Set 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>
At runtime, request 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" />
Best practice: Ask for background location in a second step after users understand the benefit, and consider using a foreground service with a visible notification.

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" />
Start foreground services with a persistent notification so users know something is running.

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.
Avoid 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>
Only declare what you truly need; otherwise the system may limit results.

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>
For production, prefer HTTPS. Use cleartext only for local dev or controlled test endpoints.

Useful <application> Attributes

AttributeWhy it matters
android:themeSets global app theme (colors, typography).
android:icon, android:roundIconApp icons for devices/launchers.
android:allowBackupControls Auto Backup / Key-Value Backup behavior.
android:supportsRtlEnable right-to-left layout mirroring.
android:usesCleartextTrafficPermits or blocks HTTP traffic globally.
android:networkSecurityConfigCustom 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>
exported="true" means other apps can start this component (if the filter matches). Use false for internal-only components.

How Android Uses Your Manifest

Install time └─> System parses Manifest (permissions, components, features) └─> Play Store filters devices by features/requirements Runtime └─> User taps icon → System finds LAUNCHER activity via intent-filter └─> Starts Activity/Service/Receiver as needed (checks exported) └─> Enforces permissions & background execution limits

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:exported correctly.

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:exported on components with intent-filters → build fails on Android 12+.
Tip: Keep a small “Manifest checklist” in your project wiki: components, exported flags, permissions (and why), uses-feature, deep links, FileProvider, network config.