Skip to main content

Managing App Configuration

1. Using BuildConfig

Field Type Description
BuildConfig.DEBUG Boolean Indicates if the app is built in debug mode.
BuildConfig.APPLICATION_ID String Package name of the application.
BuildConfig.VERSION_CODE Int Version code of the app as defined in build.gradle.
BuildConfig.VERSION_NAME String Version name of the app as defined in build.gradle.

Example: Accessing BuildConfig in Kotlin

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (BuildConfig.DEBUG) {
            Log.d("MainActivity", "App is running in debug mode")
        }

        val versionName = BuildConfig.VERSION_NAME
        Log.d("MainActivity", "App Version: $versionName")
    }
}
Note: BuildConfig fields are generated at compile time and are not modifiable at runtime.

2. Creating Build Variants

Variant Name Description Typical Use Case
debug Build variant for development and testing with debugging enabled. Local development, debugging, performance profiling
release Build variant for production deployment with optimizations. App store release, performance optimization

Example: Build Variant Configuration in build.gradle.kts

android {
    buildTypes {
        getByName("debug") {
            isDebuggable = true
            applicationIdSuffix = ".debug"
        }

        getByName("release") {
            isMinifyEnabled = true
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
        }
    }

    flavorDimensions("version")
    productFlavors {
        create("free") {
            dimension = "version"
            applicationIdSuffix = ".free"
        }

        create("paid") {
            dimension = "version"
            applicationIdSuffix = ".paid"
        }
    }
}
Note: Build variants allow you to customize your app for different environments or user segments without maintaining separate codebases.

3. Setting Application Class

In Android, the Application class is a base class for maintaining global application state. You can customize this class to initialize global variables, set up logging, or perform other application-level operations.

Property Description Example
android:name Specifies the custom Application class to use in the manifest. <application android:name=".MyApplication">

Example: Custom Application Class

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // Initialize global state here
        Log.d("MyApp", "Application created")
    }
}

Example: Registering Application Class in Manifest

<application
    android:name=".MyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name">
</application>

4. Initializing in Application

Example: Application Class Initialization

import android.app.Application
import android.util.Log

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Log.d("MyApp", "Application initialized")
        // Initialize third-party libraries here
        // e.g., Firebase, Crashlytics, etc.
    }
}
Property Description Usage
onCreate() Called when the application is starting, before any other components Use for global initialization logic
context Application context for accessing global resources Access shared preferences, databases, etc.
Note: The Application class is instantiated before any other component, making it ideal for initializing libraries that require global setup.

5. Using AndroidManifest.xml

Element Description Usage
<manifest> Root element of the AndroidManifest.xml Must be present at the top level
<application> Defines the application's metadata and components Contains all app-level configurations
<activity> Declares an Activity component Used to define UI screens
<service> Declares a Service component Used for background tasks
<receiver> Declares a BroadcastReceiver component Used for handling broadcasts
<provider> Declares a ContentProvider component Used for sharing data between apps

Example: Declaring an Activity

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">
    <application>
        <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>

Example: Declaring Permissions

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application>
        ...
    </application>
</manifest>
Note: The android:name attribute in components can be a full class name or a relative path from the package.
Warning: The android:exported attribute must be set to true for activities that are launched by the system (e.g., launcher activities).

6. Setting Activity Attributes

Attribute Description Values Notes
android:name Activity name com.example.MainActivity Must be fully qualified class name
android:label Activity label @string/app_name Used in launcher and title bar
android:theme Activity theme @style/Theme.AppCompat.Light Applies to this activity only
android:exported Can be launched by components outside app true or false Required for launchable activities
android:launchMode Activity launch behavior standard, singleTop, singleTask, singleInstance Determines how new instances are created
android:screenOrientation Screen orientation portrait, landscape, sensor Controls device rotation behavior

Example: Declaring Activity in Manifest

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat.Light"
    android:exported="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait">
</activity>

7. Configuring Application Theme

Property Value Description
android:theme @style/Theme.AppCompat.Light Applies a theme to the entire application
android:windowBackground @drawable/background_drawable Sets the background for the window
colorPrimary ?attr/colorPrimary Primary color for app elements like action bar
colorSecondary ?attr/colorSecondary Secondary color for UI components

Example: Define a Custom Theme

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">&#64;color/primary_color</item>
        <item name="colorPrimaryDark">&#64;color/primary_dark</item>
        <item name="colorAccent">&#64;color/accent_color</item>
    </style>
</resources>

Example: Apply Theme in Manifest

<application
    android:theme="&#64;style/AppTheme">
    ...
</application>
Note: Themes in Android are defined in res/values/themes.xml or within styles.xml.
Warning: Avoid using android:theme in individual activities unless you want to override the app-wide theme.

8. Using Metadata Tags

Tag Description Usage
android:name Unique identifier for the metadata tag <meta-data android:name="com.example.api_key" android:value="secret123" />
android:value String value of the metadata <meta-data android:name="version" android:value="1.0.0" />
android:resource Reference to a resource (e.g., string, integer) <meta-data android:name="config_resource" android:resource="@string/config_value" />

Example: Reading Metadata in Kotlin

val metadata = packageManager.getApplicationInfo(
    packageName,
    PackageManager.GET_META_DATA
).metaData

val apiKey = metadata.getString("com.example.api_key")
val version = metadata.getString("version")
Note: Metadata tags are read-only and must be defined in the AndroidManifest.xml.

Deep links allow your Android app to handle URLs that open specific screens or perform actions within the app. This is particularly useful for integrating with web services, sharing content, or enabling external apps to launch your app.

Component Description Notes
Intent Filter Used in AndroidManifest.xml to declare which deep links your app can handle. Must include <intent-filter> with appropriate <action>, <category>, and <data> elements.
Data URI Defines the scheme and host of the deep link (e.g., https://myapp.com). Can include path, port, and other components to match specific URLs.
Activity The activity that will be launched when the deep link is triggered. Must have android:name attribute set to the full class name.
<activity
    android:name=".DeepLinkActivity"
    android:exported="true">
    <intent-filter>
        <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="myapp.com"
            android:pathPrefix="/deep" />
    </intent-filter>
</activity>
class DeepLinkActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deep_link)

        val uri = intent.data
        if (uri != null) {
            // Handle the deep link data
            val path = uri.path
            val param = uri.getQueryParameter("param")
        }
    }
}
Note: Ensure that android:exported="true" is set for the activity to allow external apps to launch it.
Warning: Make sure the <data> element in the intent filter matches the URL structure exactly to avoid mismatches.

10. Managing Feature Flags

Flag Name Type Default Value Description
feature_new_ui Boolean false Enables the new user interface for the app
feature_push_notifications Boolean true Controls whether push notifications are enabled
feature_analytics Boolean true Enables or disables analytics collection

Example: Feature Flag Usage in Kotlin

class FeatureFlags {
    companion object {
        const val NEW_UI = "feature_new_ui"
        const val PUSH_NOTIFICATIONS = "feature_push_notifications"
        const val ANALYTICS = "feature_analytics"
    }
}

fun isFeatureEnabled(flag: String): Boolean {
    return when (flag) {
        FeatureFlags.NEW_UI -> false
        FeatureFlags.PUSH_NOTIFICATIONS -> true
        FeatureFlags.ANALYTICS -> true
        else -> false
    }
}
Note: Feature flags can be managed via backend services or local configuration files.

Was this article helpful?