Intermediate: Android basics · Android Studio and your first app · topic 19 of 50 · 30 min
Project structure and Gradle
Explanation
A map of the project
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)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.
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.
<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 app module's build.gradle.kts
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)
}| Setting | Meaning |
|---|---|
| applicationId | The app's unique identity on devices and the Play Store; never change it after publishing |
| minSdk | Oldest Android API level the app installs on; lower reaches more phones but limits features |
| targetSdk | The API level whose behaviour you have tested against; Google Play requires a recent one |
| compileSdk | The SDK version used to compile; usually the newest |
| versionCode / versionName | Internal release number (must increase) / the version users see |
Version catalog
[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" }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
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.
// 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))Practice (0/3 done)
Which setting must increase every time you upload a new release to the Play Store?
Where should the text "Add to cart" live so it can be translated?
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Activities and the lifecycleAndroid Studio and your first app · same module
- Hello Compose: your first screenAndroid Studio and your first app · same module
- Gradle in briefJava Programming (Core to Spring Boot) · JDBC, Maven, Gradle and JUnit
- Publishing on Google PlayFlutter and Dart · Publishing to the stores and the web
- Project structure and hot reloadFlutter and Dart · Flutter setup and your first app
- HTTP requests and FutureBuilderFlutter and Dart · Networking, storage and Firebase
Questions people ask about this
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
Which form declares what user data your app and its SDKs collect?Related
Can Kotlin and Java code be used in the same Android project?Related
Answer: Yes, they interoperate
Kotlin was designed to work alongside Java.
Which function shows Compose content in an activity?Related
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
- 2 more topics in “Android Studio and your first app” before its exam: Activities and the lifecycle, Hello Compose: your first screen.
- Module 5 exam: Android Studio and your first app · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
- 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