TD6 — Android Studio & NotesPad v1
S7 Inf A3 — Java for Graphical and Mobile Programming
Stéphane Derrode — Centrale Lyon
Part 3 — Android
Duration: 2h · Follow the setup tutorial before starting
Objectives
- Install Android Studio and configure an emulator
- Understand the project structure generated by Android Studio
- Build NotesPad v1: one Activity, one layout, one button
- Handle a click event and display a Toast
- Use Logcat to debug
Part 0 — Environment Setup (done before the session)
Follow the Android Studio & Emulator Setup Tutorial available on the course website before arriving.
Quick check — Android Studio opens and the emulator starts:
- Open Android Studio
- Open AVD Manager (Tools → Device Manager)
- Start the Pixel 6a API 33 emulator
- Verify the emulator boots to the Android home screen
If anything fails, come 10 minutes early.
Part 1 — Create the NotesPad Project (15 min)
1.1 New project
In Android Studio:
- File → New → New Project
- Choose template: Empty Views Activity
- Fill in:
- Name:
NotesPad - Package name:
com.s7infa3.notespad - Save location: your choice
- Language: Java
- Minimum SDK: API 26 (Android 8.0)
- Click Finish and wait for Gradle sync
1.2 Explore the generated structure
Locate and open each file. Note what it contains.
| File | Location | Purpose |
|---|---|---|
MainActivity.java |
app/src/main/java/com/s7infa3/notespad/ |
Activity logic |
activity_main.xml |
app/src/main/res/layout/ |
UI definition |
strings.xml |
app/src/main/res/values/ |
Text constants |
AndroidManifest.xml |
app/src/main/ |
App declaration |
build.gradle (app) |
app/ |
Dependencies |
1.3 Run the default app
Click ▶ Run (Shift+F10). The emulator should show "Hello World!".
Part 2 — Build the Layout (25 min)
Replace the content of activity_main.xml with the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="28sp"
android:textStyle="bold"
android:layout_marginBottom="24dp"/>
<EditText
android:id="@+id/noteInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_note"
android:inputType="text"
android:layout_marginBottom="12dp"/>
<Button
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_add"/>
<TextView
android:id="@+id/statusView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textSize="14sp"
android:layout_marginTop="16dp"
android:textColor="#757575"/>
</LinearLayout>
Now open strings.xml and add the missing strings:
<resources>
<string name="app_name">NotesPad</string>
<string name="hint_note">Enter a note…</string>
<string name="btn_add">Add</string>
<string name="error_empty">Note cannot be empty</string>
<string name="note_added">Note added!</string>
</resources>
Run the app — you should see the layout. The button does nothing yet.
Part 3 — Add the Click Handler (30 min)
3.1 Connect the widgets
Replace the content of MainActivity.java:
package com.s7infa3.notespad;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "NotesPad";
private List<String> notes = new ArrayList<>();
private EditText noteInput;
private TextView statusView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. Get widget references
noteInput = findViewById(R.id.noteInput);
statusView = findViewById(R.id.statusView);
Button addButton = findViewById(R.id.addButton);
// 2. Set up the click listener
addButton.setOnClickListener(v -> addNote());
}
private void addNote() {
String text = noteInput.getText().toString().trim();
if (text.isEmpty()) {
Toast.makeText(this,
R.string.error_empty,
Toast.LENGTH_SHORT).show();
return;
}
notes.add(text);
noteInput.setText("");
statusView.setText(notes.size() + " note(s) in memory");
Log.d(TAG, "Note added: " + text
+ " — total: " + notes.size());
Toast.makeText(this,
R.string.note_added,
Toast.LENGTH_SHORT).show();
}
}
3.2 Test
- Run the app
- Type a note and tap Add → Toast appears, status updates
- Tap Add with an empty field → error Toast appears
- Add 3 notes → status shows "3 note(s) in memory"
- Open Logcat (bottom panel in Android Studio), filter by
NotesPad→ see your Log.d() messages
Part 4 — Explore the Lifecycle (20 min)
4.1 Override lifecycle methods
Add the following methods to MainActivity.java to observe the lifecycle:
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause() — notes in memory: "
+ notes.size());
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy()");
}
4.2 Observe the sequence
With Logcat open and filtered by NotesPad:
- Launch the app → which methods are called?
- Press Home (not Back) → which methods are called?
- Reopen the app → which methods are called?
- Press Back → which methods are called?
- Add notes then rotate the emulator (Ctrl+Left/Right in emulator) → what happens to your notes?
The notes disappear on rotation — this is the problem that
onSaveInstanceState()andSharedPreferencessolve (CM8).
Part 5 — Exploration (remaining time)
5.1 Change the button color: in activity_main.xml, add android:backgroundTint="@color/purple_500". Where does purple_500 come from? Open colors.xml.
5.2 Add a second button Clear All that empties the notes list and resets the status text.
5.3 Make the Add button disabled at startup and enable it only when the EditText is not empty. Use a TextWatcher:
noteInput.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override public void onTextChanged(
CharSequence s, int start, int before, int count) {
addButton.setEnabled(s.toString().trim().length() > 0);
}
@Override public void afterTextChanged(Editable s) {}
});
Deliverable
No formal submission. Verify that: - The app runs on the emulator - Adding a note shows a Toast and updates the status - Empty note shows an error Toast - Lifecycle methods print to Logcat correctly
Keep this project — you will extend it in TD7.
Common Errors
| Error | Cause | Fix |
|---|---|---|
Gradle sync failed |
Missing SDK | Open SDK Manager (Tools → SDK Manager), install API 33 |
Cannot resolve symbol R |
XML has an error | Fix the XML error; rebuild (Build → Rebuild Project) |
NullPointerException on findViewById |
Called before setContentView() |
Always call setContentView() first in onCreate() |
| Toast shows nothing | Forgot .show() |
Add .show() at the end of the Toast chain |
| Emulator is very slow | Hardware acceleration off | Enable HAXM or use an x86 system image |