AndroidManifest.xml is a file that describes essential information about your app to the Android build tools, the Android operating system, and Google Play. It contains information such as the app’s package name, components, permissions, features, and compatibility. Every app project must have an AndroidManifest.xml file at the root of the project source set.

Important parts of AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" package="com.apphacking.privacy" platformBuildVersionCode="30" platformBuildVersionName="11">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="30"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<permission android:label="Allows reading user infroatmion" android:name="com.apphacking.privacy.USER_INFO" android:protectionLevel="dangerous"/>
<queries>
<package android:name="com.mwr.example.sieve"/>
</queries>
<application android:theme="@style/Theme.Privacy" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:debuggable="true" android:allowBackup="true" android:supportsRtl="true" android:extractNativeLibs="false" android:networkSecurityConfig="@xml/network_security_config" android:roundIcon="@mipmap/ic_launcher_round" android:appComponentFactory="androidx.core.app.CoreComponentFactory">
<provider android:name="com.apphacking.privacy.UserDatabase" android:enabled="true" android:exported="true" android:authorities="user">
<path-permission android:readPermission="com.apphacking.privacy.USER_INFO" android:path="/User"/>
</provider>
<receiver android:name="com.apphacking.privacy.WeatherNotification" android:enabled="true" android:exported="true"/>
<service android:name="com.apphacking.privacy.MyService" android:enabled="true" android:exported="true"/>
<activity android:name="com.apphacking.privacy.Profile"/>
<activity android:name="com.apphacking.privacy.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Compile SDK Version
android:compileSdkVersion="30" and android:compileSdkVersionCodename="11" . The first one specified the API level which the app was developed with it. The second one is specified the android version which the app was developed for it.
Why android:compileSdkVersionCodename is important?
Because every security feature before android 11 is implemented here. For example in android version 7 we had a big change in trust relationship of certificates. In this version the device storage wasn’t a trustable source anymore by default.
Package Name
This is an unique identifier for each app installed in android OS. This is important to know that you can’t install two APK with same package name. For example if you install a malware with com.whatsapp then you can’t install the original whatsapp app even if you install it by Google Play Store.
<aside>
💡 Android developers permit to choose they desire package name. Therefore Google Play Store check the package name to prevent duplicate package names.
</aside>
Platform Build Version
platformBuildVersionCode="30" and platformBuildVersionName="11" . This parameter specified that the developer test the application with android version 11 to work correctly.
Uses Permissions
This part specified if the user grant these permissions the application permit to use theme and doing or accessing some features or data.
Example:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
This part is very important for reverse engineering and malware analysis.
<aside>
💡 This permissions must be defined in AndroidManifest.xml file before compiling and can’t be added in the feature.
</aside>
One of important permission is <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> which grant the application to access /sdcard path. By default each application in android have an protected directory to store and working with it self files. It’s located on /data/data/<Package Name> . Protect mean the other application doesn’t access to this directory(Root or System users have). When the application use External Storage permissions it want access to /sdcard path which is user files storage. For example when the user download a file or taking a picture the files will store there.
<aside>
💡 /sdcard path didn’t relevant to SD card. Even when the device didn’t have any SD card, this path still exists based on the EMMC(Embedded Multimedia Card).
</aside>
Custom permissions
‣
Queries
In the context of AndroidManifest.xml, the “queries” attribute is used to specify which third-party apps your app can interact with. It allows your app to query and interact with specific apps installed on the user’s device.
The “queries” attribute was introduced in Android 11 as a privacy feature to provide users with more control over app interactions. By specifying which apps your app can query, you ensure that your app only interacts with the desired apps and avoids potential security risks.
Here’s an example of how the “queries” attribute can be used in the AndroidManifest.xml file:
<manifest xmlns:android="<http://schemas.android.com/apk/res/android>"
package="com.example.myapp">
<queries>
<!-- Specify the apps your app can query -->
<package android:name="com.example.app1" />
<package android:name="com.example.app2" />
</queries>
<!-- Other manifest elements -->
...
</manifest>
In the example above, the “queries” section specifies that the app with the package name “com.example.myapp” can query and interact with two specific apps, “com.example.app1” and “com.example.app2”.
By declaring the apps your app needs to query, you can request specific information or services from those apps, such as invoking activities, sharing data, or integrating functionality.
It’s worth noting that starting from Android 11, if your app tries to access a third-party app without declaring it in the “queries” section, it may result in a SecurityException at runtime. Therefore, it’s essential to declare the necessary apps in the “queries” section to ensure compatibility and proper functioning of your app.
Allow Backup
The android:allowBackup="true" attribute allow the user to backup the data which the developer predefined. It’s always a good hobby to check what data will be backup.
Debuggable
The android:debuggable="true" attribute allow the debugger attach it self to the application process for debugging purpose.
<aside>
💡 If you build for release this will be automatically off.
Android Studio
</aside>
App Component Factory
android:appComponentFactory is an attribute that can be added to the <application> tag in the AndroidManifest.xml file. It specifies the name of a class that extends AppComponentFactory, which is used to create instances of the app’s components (such as activities, services, broadcast receivers, and content providers) at runtime.
This attribute is used when you want to provide your own implementation of AppComponentFactory instead of using the default one provided by the Android system. You can use this feature to customize how your app’s components are created and initialized.
Extract Native Libs
It specifies whether native libraries should be extracted from the APK during installation or not. When android:extractNativeLibs is set to true (default) or not added to the manifest, native libraries can be stored compressed in the APK. On the other hand, when android:extractNativeLibs is set to false , the libraries are stored uncompressed in the APK and there is no need to extract them during installation. Instead, they can be loaded on app startup. This attribute was introduced by Google in Marshmallow (Android 6) and is enabled by setting android:extractNativeLibs to false. It is expected that the libraries are stored uncompressed in the APK (STORE method) and zipaligned. This approach can reduce the app size and installation time, but it may result in less optimization from Google Play, for example when generating update patches. It’s worth noting that setting android:extractNativeLibs to false could be counterproductive if the APK contains multiple ABIs. In this case, it’s recommended to keep the default value of true.
<aside>
🚨 Attention:
If the value is true then when you want to reverse engineering the Libs, you should first decompress theme.
</aside>
Android Network Security Config
Is a feature that allows Android app developers to customize their network security settings in a safe configuration file without modifying app code. These settings can be configured for specific domains and for a specific app. For example developer can disable secure HTTPS and force the app traffic to work with plain HTTP.
android:networkSecurityConfig="@xml/network_security_config"
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
<aside>
💡 You can set cleartextTrafficPermitted="true" as an attribute in <Application> tag.
</aside>
This config is very important in case of bypassing Certificate Pinning.
Activity
The <activity> tag in the Android Manifest file is used to declare an activity, which is a subclass of Activity that implements part of an application’s visual user interface. All activities in an Android app must be represented by <activity> elements in the manifest file. If an activity is not declared in the manifest, the system will not recognize it, and it will never run.
Intent-filter
An activity does not necessarily need an <intent-filter> tag. The <intent-filter> tag is used to specify which intents an activity can respond to. The default activity (the one that is launched when the app starts) needs to have an <intent-filter> tag with android.intent.action.MAIN and android.intent.category.LAUNCHER settings, which advertise the activity as the one that initiates the application and should be displayed in the application launcher.
Service
Services are process which is resource intensive and will be done in background. These tasks aren’t allowed to be done in UI threads.
<service android:name="com.apphacking.privacy.MyService" android:enabled="true" android:exported="true"/>
<aside>
💡 If doing resource intensive and long running tasks in UI thread the system will automatically close the application.
</aside>
Receiver
The <receiver> element is used to declare a broadcast receiver in the manifest file. It must contain an android:name attribute to specify the class name of the broadcast receiver
A broadcast receiver is an Android component that allows an application to respond to messages (an Android Intent) that are broadcast by the Android operating system or by an application.
Broadcast receivers can be either static or dynamic. Static broadcast receivers are declared in the manifest file and work even if the app is closed. Dynamic broadcast receivers work only if the app is active or minimized.
<receiver android:name="com.apphacking.privacy.WeatherNotification" android:enabled="true" android:exported="true"/>
Provider
The <provider> tag is used in the AndroidManifest.xml file to declare a content provider component. A content provider is a subclass of ContentProvider that supplies structured access to data managed by the application. All content providers in your application must be defined in a <provider> element in the manifest file. Otherwise, the system is unaware of them and doesn’t run them.
<provider android:name="com.apphacking.privacy.UserDatabase" android:enabled="true" android:exported="true" android:authorities="user">
<path-permission android:readPermission="com.apphacking.privacy.USER_INFO" android:path="/User"/>
</provider>
Note: <path-permission> and <permission> tag should be use together to work. Other application should use <uses-permission> tag to use this component.
Difference between Provider and Query tag
- The
<query> tag is used to specify which apps can query the app’s components using implicit intents. It is used to declare which actions, categories, and data types the app can handle. The <query> tag is used in Android 11 and later versions to replace the <intent-filter> tag for certain types of implicit intents.
- The
<provider> tag is used to declare a content provider component that supplies data from one application to others on request. It specifies the name of the content provider and its authorities, which is its unique identifier. The <provider> tag is used to declare content providers that are part of the application.