Skip to content

Intermediate: Android basics · Android Studio and your first app · topic 19 of 50 · 30 min

Project structure and Gradle

Explanation

A new project has an app module with Kotlin code under src/main/java, resources (strings, images, themes) under src/main/res, and AndroidManifest.xml describing the app. Gradle build files written in Kotlin (build.gradle.kts) set the applicationId, minSdk, targetSdk, compileSdk, version and dependencies, and a version catalog (libs.versions.toml) keeps library versions in one place.

A map of the project

output
HelloIndia/
├── settings.gradle.kts         // which modules exist, where to download libraries
├── build.gradle.kts            // top-level build settings
├── gradle/libs.versions.toml   // version catalog: library versions in one place
└── app/
    ├── build.gradle.kts        // the app module's build settings
    └── src/
        ├── main/
        │   ├── AndroidManifest.xml
        │   ├── java/com/example/helloindia/MainActivity.kt   // Kotlin code lives here too
        │   └── res/            // resources: values/strings.xml, drawable/, mipmap/ (icons)
        ├── test/               // local unit tests (run on your computer)
        └── androidTest/        // instrumented tests (run on a device)
Switch the Project panel to the "Android" view for a simpler, grouped layout.

The folder is called java for historical reasons, but it holds your Kotlin files. A module is a part of the project that is built on its own; small apps have one module called app.

Think of it like this: Think of the project as a restaurant. The java folder is the kitchen where the cooking (your code) happens. The res folder is the storeroom of ready ingredients: text, images, colours and icons. The manifest is the licence on the wall telling the authorities what the restaurant is allowed to do. Gradle is the supplier who brings in everything else you need.

Resources in res are referred to by name, not by file path. Android Studio generates an ID for each one, so code writes R.string.app_name or R.drawable.logo, and Android picks the right version for the device: a Hindi string for a Hindi phone, a sharper image for a high-resolution screen.

AndroidManifest.xml

The manifest is the app's ID card for the Android system: its components (activities), the permissions it needs, its icon and theme, and which activity starts when the user taps the icon.

xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.HelloIndia">
        <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>
The MAIN/LAUNCHER intent filter makes MainActivity the screen that opens from the home screen icon.

The app module's build.gradle.kts

kotlin
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}

android {
    namespace = "com.example.helloindia"
    compileSdk = 36                     // example: the SDK you compile against

    defaultConfig {
        applicationId = "com.example.helloindia"   // unique ID on the Play Store
        minSdk = 24                     // oldest Android version you support
        targetSdk = 36                  // version you have tested and target
        versionCode = 1                 // integer, must increase for every release
        versionName = "1.0"             // shown to users
    }
}

dependencies {
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.material3)
}
Exact numbers and plugin names change with each Android Studio version; trust what the current template generates.
SettingMeaning
applicationIdThe app's unique identity on devices and the Play Store; never change it after publishing
minSdkOldest Android API level the app installs on; lower reaches more phones but limits features
targetSdkThe API level whose behaviour you have tested against; Google Play requires a recent one
compileSdkThe SDK version used to compile; usually the newest
versionCode / versionNameInternal release number (must increase) / the version users see

Version catalog

ini
[versions]
composeBom = "2025.xx.xx"

[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
gradle/libs.versions.toml (shown with placeholder versions). Build files refer to libs.androidx.material3.

A BOM (bill of materials) is a list of library versions tested together. With the Compose BOM, you set one version and all Compose libraries match.

Gradle sync

Whenever you change a Gradle file, Android Studio asks you to Sync. Syncing downloads new dependencies and updates the project model. If sync fails, read the first error in the Build window; it usually names a missing library, a typo or a version conflict.

Common mistakes

  • Changing applicationId after publishing: the Play Store treats it as a different app.
  • Forgetting to increase versionCode before uploading an update: Play Console rejects it.
  • Editing generated folders like build/. Your changes are lost on the next build.
  • Putting strings directly in code instead of res/values/strings.xml, which makes translation (for example to Hindi) hard.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Project structure and Gradle · 1/6

app/src/main

A project has an app module with code, resources, and a manifest.

Prefer a video by a teacher? Find free videos on “android studio project structure gradle kts manifest explained” on YouTube ↗

In real life: Supporting older phones

A grocery startup wants its app to work for customers with older budget phones. The developer checks Android Studio's distribution data, keeps minSdk at 24 (Android 7.0) so older devices can install it, sets targetSdk to the latest required level, and adds Hindi translations in res/values-hi/strings.xml. One project now serves new and old phones, in English and Hindi.

kotlin
// res/values/strings.xml       ->  <string name="add_to_cart">Add to cart</string>
// res/values-hi/strings.xml    ->  <string name="add_to_cart">कार्ट में डालें</string>

// In Compose, the right one is picked from the phone's language:
// Text(stringResource(R.string.add_to_cart))
Android chooses the resource folder that matches the device language.

Practice (0/3 done)

Task 1 · Question

Which setting must increase every time you upload a new release to the Play Store?

Task 2 · Question

Where should the text "Add to cart" live so it can be translated?

Task 3 · Practice

Open your HelloIndia project. Find and write down: the applicationId, minSdk, targetSdk and compileSdk; the launcher activity in the manifest; and the Compose BOM version in the version catalog. Add a Hindi strings file (values-hi) with a translated app name and run the app with the phone set to Hindi.

Quick quiz

Question 1

1.What does minSdk decide?

Question 2

2.What is applicationId?

Question 3

3.What does a BOM do?

Question 4

4.Which file declares permissions like INTERNET?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does minSdk decide?

Answer: The oldest Android version the app can install on

Devices below minSdk cannot install the app.

What is applicationId?

Answer: The app's unique identity on devices and the Play Store

It must never change after publishing.

What does a BOM do?

Answer: Pins a set of library versions known to work together

The Compose BOM aligns Compose library versions.

Which file declares permissions like INTERNET?

Answer: AndroidManifest.xml

Permissions are declared in the manifest.

Which file is a Gradle build script in Kotlin?Related

Answer: build.gradle.kts

.kts = Kotlin script.

From Gradle in brief

Which form declares what user data your app and its SDKs collect?Related

Answer: Data safety

Shown to users on the listing.

From Publishing on Google Play

Can Kotlin and Java code be used in the same Android project?Related

Answer: Yes, they interoperate

Kotlin was designed to work alongside Java.

From Kotlin and Android: the big picture

Which function shows Compose content in an activity?Related

Answer: setContent

setContent { } hosts the composables.

From Hello Compose: your first screen

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Android Studio and your first app” before its exam: Activities and the lifecycle, Hello Compose: your first screen.
  2. Module 5 exam: Android Studio and your first app · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Jetpack Compose UI. 50 topics left in the course before the final exam.

← Previous: Setting up Android Studio, an emulator and your phone