Mehdi Tmimi Mobile

Mobile Development Lab 1 Part 1 of 8

Find your way in the project

Your project builds, yet it has no screen. What can ▶ open? By the end of this part, you know.

Start of session

  1. Start Android Studio: it reopens Notes by itself. If the Welcome window shows instead: ProjectsNotes.
  2. Start the phone from the project: Device Manager (the phone icon on the window’s right edge, or ViewTool WindowsDevice Manager), ▶ on Pixel 7. It appears in Running Devices.
  3. Wait until indexing ends (the bar at the bottom) before Alt+Enter or Ctrl+O.
The phone at the end of Part 0: the Android home screen of the Pixel 7.
Where you start

Before you start

By the end you can

  • read the five values of the app’s Gradle file;
  • add a library to the project, then sync Gradle;
  • say what the manifest declares.
  • Android Studio Project · Android
  • Gradle Gradle Scripts
  • Manifest manifests
Behind, or a fresh project? Start from here a fresh project: about 5 min
  1. The project: your own from Part 0. If it does not build, create a fresh one: Part 0, steps 0.3 and 0.4 (about 5 minutes).

  2. Your package name, for the code of this page:

    Without JavaScript, the code says com.yourname.notes: replace yourname by the name you chose.

Step 1 of 4

Find your files in the Project window

4 min

Goal Find Android Studio’s windows, and the plain com.yourname.notes for your Java code.

  • Android Studio Project · Android
  1. Find Project (left), the editor (middle), Running Devices (right), Build (bottom).

    Android Studio The whole windowFull size
    The whole Android Studio window: Project on the left, the editor with build.gradle.kts (:app) in the middle, the Build window at the bottom and Running Devices with the phone on the right.
    1. Project, Android display: your files.
    2. The editor: one tab per open file.
    3. Running Devices: the phone, tab Pixel 7 API 37.0.
    4. The bottom tool windows: Build, later Logcat.
  2. Your app’s folders, in the Android display.

    1. At the top of Project, the menu says Android: keep it. If not, click it, then Android in the list that opens.
    2. In Project, click the arrow › at the left of app, unless its folders already show.
    3. Open manifests the same way: it holds AndroidManifest.xml.
    4. Open kotlin+java: the plain com.yourname.notes is for your code. No arrow: still empty.
    5. Open res: drawable, mipmap, values, xml.
    6. Open Gradle Scripts, at the bottom of the tree: the build files.
    Project · Android Project window · leftFull size
    The Project window in the Android display: app with manifests, kotlin+java holding com.yourname.notes, com.yourname.notes (androidTest) and com.yourname.notes (test), res, keepRules, then Gradle Scripts with seven files.
    1. Android: the display to keep (Project shows the real folders).
    2. manifests: AndroidManifest.xml.
    3. kotlin+java › the plain com.yourname.notes: your code. (androidTest) and (test) hold tests.
    4. Gradle Scripts: the build files. Above it, keepRules serves release builds: leave it.
  3. The real folders, seen once.

    1. Click Android, the menu at the top of Project. In the list that opens, click Project.
    2. Open Notes › app › src › main, each with its arrow ›. Skip a folder already open.
    3. Under main, find the folder java: on disk, it is what kotlin+java shows.
    4. Click the menu again, then click Android: keep it from now on.

Done I see the plain com.yourname.notes, with no arrow: still empty.

Stuck? 4 symptoms
  • The phone opened in its own window, not in Running Devices You started it from the Welcome window. Close the phone’s window, then start the phone from the project’s Device Manager.
  • No manifests folder in the tree The menu at the top says Project, which shows the real folders. Pick Android.
  • The captures say yourname, your tree does not Normal: your package carries the name you chose in Part 0. Type it in the package field, under Behind? at the top: the code then shows yours.
  • Later, a grey java (generated) under kotlin+java The build writes it. Never put code there.

No file changes in this step.

Step 2 of 4

Read the app’s Gradle file

5 min

Goal Read the five values of build.gradle.kts (Module :app), then say which phones can install your app.

  • Gradle Gradle Scripts › build.gradle.kts (Module :app)

Predict first

Can an Android 6 phone (API 23) install your app? And your API 37 emulator?

See the answer

Only the API 37 one. minSdk = 24 is the oldest Android that may install the app: 23 is below 24, and 37 is above.

  1. The app’s Gradle file, open.

    1. In Project, under Gradle Scripts, double-click build.gradle.kts (Module :app), not the (Project: Notes) one.
    2. It opens in the editor. At its top, if a banner offers the Project Structure dialog, click Hide notification.
  2. Its five values and its libraries.

    1. In your editor, find the lines the panel marks: 6 to 8, 12 to 14, then 35.
    2. Read the six notes under the panel below: each number sits on its line.
Gradle Scripts › build.gradle.kts (Module :app)Read only
plugins {    alias(libs.plugins.android.application)}
android { namespace = "com.yourname.notes" compileSdk { version = release(37) }
defaultConfig { applicationId = "com.yourname.notes" minSdk = 24 targetSdk = 37 versionCode = 1 versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
buildTypes { release { optimization { enable = true packageScope = setOf("androidx.**", "kotlin.**", "kotlinx.**") } } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 }}
dependencies { implementation(libs.appcompat) implementation(libs.material) testImplementation(libs.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(libs.ext.junit)}

.kts: Gradle’s Kotlin notation, not your app’s code.

  1. namespace: the Java package of your code.
  2. compileSdk: the Android version your code is compiled against, here 37 (Android 17).
  3. applicationId: the app’s unique name on a phone, its package name.
  4. minSdk = 24: the oldest Android that can install the app (Android 7).
  5. targetSdk = 37: the Android whose rules the app follows.
  6. dependencies: the libraries the app uses. Step 1.3 adds one.

Done I see minSdk = 24: API 23 cannot install the app, API 37 can.

Stuck? 3 symptoms
  • No minSdk in the file You opened build.gradle.kts (Project: Notes). Open the (Module :app) one.
  • Grey text after some lines, such as androidx.appcompat:appcompat:1.8.0 A hint from Android Studio, not part of the file. Leave it.
  • Your numbers are higher than on this page A newer Android Studio writes newer ones. Keep yours: the answers stay the same.

No file changes in this step.

Step 3 of 4

Add the ConstraintLayout library

5 min

Goal Add the ConstraintLayout library to the project in three lines, then sync Gradle.

  • Gradle libs.versions.toml
  • Gradle build.gradle.kts (Module :app)
  1. Paste The library’s version, in libs.versions.toml.

    1. In Project, under Gradle Scripts, double-click libs.versions.toml: it opens in the editor.
    2. In the panel below, beside After line 7, click Copy 1 line.
    3. In the editor, click at the end of line 7, material = "…". Press Enter, then Ctrl+V.
    4. A banner Gradle files have changed… may appear at the top: leave it until action d.
    Gradle Scripts › libs.versions.tomlAdd the marked lines
    [versions]agp = "9.5.0"junit = "4.13.2"junitVersion = "1.3.0"espressoCore = "3.7.0"appcompat = "1.8.0"material = "1.14.0"constraintlayout = "2.2.2"
    [libraries]junit = { group = "junit", name = "junit", version.ref = "junit" }ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }material = { group = "com.google.android.material", name = "material", version.ref = "material" }constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
    [plugins]android-application = { id = "com.android.application", version.ref = "agp" }
  2. Paste The library’s name, in the same file.

    1. In the panel below, beside After line 15, click Copy 1 line.
    2. In the editor, click at the end of line 15, material = { … }. Press Enter, then Ctrl+V.
    Gradle Scripts › libs.versions.tomlAdd the marked lines
    [versions]agp = "9.5.0"junit = "4.13.2"junitVersion = "1.3.0"espressoCore = "3.7.0"appcompat = "1.8.0"material = "1.14.0"constraintlayout = "2.2.2"
    [libraries]junit = { group = "junit", name = "junit", version.ref = "junit" }ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }material = { group = "com.google.android.material", name = "material", version.ref = "material" }constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
    [plugins]android-application = { id = "com.android.application", version.ref = "agp" }
  3. Paste The library, in the app’s dependencies.

    1. Click the editor’s tab build.gradle.kts (:app), the file of step 1.2. Closed? Double-click build.gradle.kts (Module :app) under Gradle Scripts.
    2. In the panel below, beside After line 37, click Copy 1 line.
    3. In the editor, click at the end of line 37, implementation(libs.material). Press Enter, then Ctrl+V.
    4. The new line turns red: normal until the sync.
    Gradle Scripts › build.gradle.kts (Module :app)Add the marked lines
    plugins {    alias(libs.plugins.android.application)}
    android { namespace = "com.yourname.notes" compileSdk { version = release(37) }
    defaultConfig { applicationId = "com.yourname.notes" minSdk = 24 targetSdk = 37 versionCode = 1 versionName = "1.0"
    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
    buildTypes { release { optimization { enable = true packageScope = setOf("androidx.**", "kotlin.**", "kotlinx.**") } } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 }}
    dependencies { implementation(libs.appcompat) implementation(libs.material) implementation(libs.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(libs.ext.junit)}
  4. The Gradle sync.

    1. In the banner at the top, Gradle files have changed…, click Sync Now. The sync takes about 5 seconds.
    build.gradle.kts (:app) Editor · centreFull size
    The editor on build.gradle.kts (:app): the new line implementation(libs.constraintlayout), still red, and above it the banner Gradle files have changed since last project sync, with Sync Now.
    1. The added line: implementation(libs.constraintlayout), red until the sync.
    2. Sync Now: runs the Gradle sync (about 5 seconds).

Why ConstraintLayout is not part of Android: it is a library, which Gradle fetches at the sync. Your screens use it from Part 2 on.

Done I see no red text in either file.

Stuck? 2 symptoms · the files
  • The new line is red Normal before the sync. Click Sync Now on the banner.
  • The sync fails: Could not resolve androidx.constraintlayout… Check the three lines character by character, then the network.

The files at the end of this step, to compare. Do not paste them whole: keep your own version numbers.

Gradle Scripts › libs.versions.tomlRead only
[versions]agp = "9.5.0"junit = "4.13.2"junitVersion = "1.3.0"espressoCore = "3.7.0"appcompat = "1.8.0"material = "1.14.0"constraintlayout = "2.2.2"
[libraries]junit = { group = "junit", name = "junit", version.ref = "junit" }ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }material = { group = "com.google.android.material", name = "material", version.ref = "material" }constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
[plugins]android-application = { id = "com.android.application", version.ref = "agp" }
Gradle Scripts › build.gradle.kts (Module :app)Read only
plugins {    alias(libs.plugins.android.application)}
android { namespace = "com.yourname.notes" compileSdk { version = release(37) }
defaultConfig { applicationId = "com.yourname.notes" minSdk = 24 targetSdk = 37 versionCode = 1 versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
buildTypes { release { optimization { enable = true packageScope = setOf("androidx.**", "kotlin.**", "kotlinx.**") } } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 }}
dependencies { implementation(libs.appcompat) implementation(libs.material) implementation(libs.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(libs.ext.junit)}

Step 4 of 4

Read the manifest, then run the app

4 min

Goal Read what the manifest declares, predict what ▶ does, then read Android Studio’s answer.

  • Manifest manifests › AndroidManifest.xml
  • Android Studio Run
  1. What the manifest declares.

    1. In Project, under app › manifests, double-click AndroidManifest.xml.
    2. Find line 10, android:label: it reads "Notes". Android Studio folds @string/app_name.
    3. Click "Notes": the reference @string/app_name shows.
    4. Read the three notes under the panel.
    manifests › AndroidManifest.xmlRead only
    <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools">
    <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Notes" />
    </manifest>
    1. android:icon: the app’s icon on the phone.
    2. android:label: its name, Notes.
    3. android:theme, then />: the <application> ends with no <activity> inside. No screen is declared.
  2. Predict, then run the app.

    Predict first

    The manifest declares no screen. What does ▶ do?

    See the answer

    It builds and installs the app, then stops: a red balloon says Error running 'app', Default Activity not found.

    1. In the toolbar, check that the device menu says Pixel 7.
    2. Click ▶ Run 'app' in the toolbar, or press Shift+F10.
  3. Android Studio’s answer.

    1. Wait: Android Studio builds the app, then installs it on the phone.
    2. A red balloon opens by the Run button of the left bar: read it.
    Build and Run Tool window · bottomFull size
    The bottom left of Android Studio after Run: the Build window says Build Notes: finished, and a red balloon at the Run button says Error running 'app', Default Activity not found.
    1. Build Notes: finished: the build succeeded.
    2. Error running 'app' · Default Activity not found: no activity to open.
    3. The Run button of the left bar: the message points at it.

Why ▶ looks in your manifest for the LAUNCHER activity and finds none: Android Studio stops after the install. Chapter 02 showed that line.

Done I see Default Activity not found in a red balloon.

Stuck? 2 symptoms
  • “Waiting for all target devices to come online” The phone is still booting: wait.
  • BUILD SUCCESSFUL, and nothing opens on the phone That is this step’s result. Look for the red balloon by the Run button of the left bar.

No file changes in this step: the project is as at the end of step 1.3.

Now you

One line for Android 6

Which line would let an Android 6 phone (API 23) install your app? Say it; change nothing.

See the answer

minSdk = 23, line 13 of build.gradle.kts (Module :app). Keep yours at 24: the lab is tested with it.

If it doesn’t work

  • “A newer version of … is available”, in yellow Leave the versions as they are: the lab is tested with these.
  • “New Minor Gradle Version Available”, in Build Ignore it: the lab is tested with this Gradle.

End of the part

Recap

Gradle says who the app is and what it is built with. The manifest says what Android may open: nothing yet, hence Default Activity not found.

  • read the five values of the app’s Gradle file;
  • add a library to the project, then sync Gradle;
  • say what the manifest declares.
Your project at the end of Part 1: Run answers Default Activity not found.
Your app now
← Lab 1, all parts