CS 3180 Mobile Application Development

Week 2: Debugging & Device Testing

CS 3180 — Mobile Application Development

Logcat · Breakpoints · Stack Traces · Physical Devices

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Client Scenario: The Bug Report

"Maria calls — the app crashed when a volunteer entered
a score of 'twelve' instead of '12'. How do we find and fix it?"

Professional developers spend 50%+ of their time debugging

Today's tools: Logcat, debugger, stack traces

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Logcat: Your Window Into a Running App

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Log Levels

Level Method When to Use
Verbose Log.v() Everything — development only
Debug Log.d() Useful development info
Info Log.i() Significant events
Warn Log.w() Unusual but not wrong
Error Log.e() Something definitely broke

Filter Logcat: by package name org.hopefoundation.golftracker or by tag

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Logging in the Golf App

private const val TAG = "ScoreEntry"

fun submitScore(holeNumber: Int, scoreText: String) {
    Log.d(TAG, "Submitting score for hole $holeNumber: $scoreText")

    val score = scoreText.toIntOrNull()
    if (score == null) {
        Log.e(TAG, "Invalid score input: $scoreText")
        return
    }

    if (score < 1 || score > 15) {
        Log.w(TAG, "Unusual score: $score on hole $holeNumber")
    }

    Log.i(TAG, "Score recorded: Hole $holeNumber = $score")
}
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Breakpoint Debugging

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Setting and Using Breakpoints

  1. Set breakpoint — click the gutter (red dot appears)
  2. Run in Debug mode — green bug icon, not the play button
  3. App pauses at the breakpoint — inspect variables in real time
  4. Step controls:
    • F8 — Step Over (next line, don't enter called functions)
    • F7 — Step Into (enter the called function)
    • Shift + F8 — Step Out (finish current function, return to caller)
    • F9 — Resume (continue running until next breakpoint)
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Reading Stack Traces

java.lang.NumberFormatException: For input string: "twelve"
    at java.lang.Integer.parseInt(Integer.java:615)
    at ScoreEntryKt.submitScore(ScoreEntry.kt:15)
    at MainActivityKt$ScoreScreen$1.invoke(MainActivity.kt:42)

Read from bottom to top to understand the call chain

  • MainActivity.kt:42 — button click triggered this
  • ScoreEntry.kt:15 — our code tried to parse "twelve"
  • Integer.parseInt — crashed deep in the standard library
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Live Demo: Debug a Buggy Scorecard

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

The Buggy App

Button(onClick = {
    Log.d("BuggyScore", "User entered: $currentInput")

    // BUG 1: No null check — crashes on non-number input!
    val score = currentInput.toInt()

    holeScores.add(score)

    // BUG 2: Off-by-one in average calculation
    val average = holeScores.sum() / holeScores.size - 1

    Log.d("BuggyScore", "Average so far: $average")
}) {
    Text("Add Score")
}

Task: find both bugs using Logcat and breakpoints

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Bug 1 Fix: Null Safety

// Before — crashes on "twelve", "par", empty string
val score = currentInput.toInt()

// After — safe: returns null if not a number
val score = currentInput.toIntOrNull() ?: return

toIntOrNull() returns null instead of throwing — Elvis handles it

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Bug 2 Fix: Operator Precedence

// Before — divides first, then subtracts 1
val average = holeScores.sum() / holeScores.size - 1

// After — correct average
val average = holeScores.sum() / holeScores.size

// Better — use Kotlin's built-in
val average = holeScores.average()

Lesson: log intermediate values to catch arithmetic bugs

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

AI Debugging Workflow

Paste the full stack trace into Claude:

"I'm getting this crash in my Android app:

java.lang.NumberFormatException: For input string: "twelve"
    at ScoreEntryKt.submitScore(ScoreEntry.kt:15)
    ...

What's causing it and how do I fix it?"

Rule: understand the fix before applying it — exam will ask why

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Physical Device Testing

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Why Physical Devices for Golf App?

  • Test real GPS accuracy — future course map feature
  • Test outdoor visibility — golf is played in sunlight
  • Test actual performance — battery matters during a 4-hour tournament
  • Test "Maria's old phone" vs. "sponsor's new flagship"

Emulators are great for logic. Physical devices are great for experience.

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Enabling Developer Options

On the device:

  1. Settings → About Phone
  2. Tap Build Number seven times
  3. Enter PIN if prompted
  4. Settings → Developer Options now appears
  5. Enable USB Debugging
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Connection Methods

USB (most reliable):

  1. Connect via USB cable → "Allow USB Debugging?" prompt → tap Allow
  2. Device appears in Android Studio's device selector
  3. Run app — noticeably faster than emulator

Wireless Debugging (Android 11+):

  1. Developer Options → Wireless Debugging → Enable
  2. Android Studio → Device Manager → Pair using Wi-Fi
  3. Scan QR code or enter pairing code
  4. Walk around while testing — great for tablet scenarios
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Testing Matrix for Hope Foundation

Device Android Test For
Old phone Android 10 (API 29) minSdk compatibility
Mid-range Android 12-13 Average volunteer experience
Flagship Android 14 Latest features, performance
Tablet Any Leaderboard display (large screen)

Team project requirement: test on at least two real devices

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Debugging Workshop: Golf Score Bugs

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Setup: Clone the Buggy Project

  1. Accept the assignment on GitHub Classroom
  2. Clone: git clone [your repo URL]
  3. Open in Android Studio → wait for Gradle sync
  4. Run the app to see what it does
  5. Goal: find and fix all 5 bugs

You have 25 minutes

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

The 5 Bugs

  1. Crash — app crashes on empty score submission
  2. Logic — total score is always 1 less than correct
  3. State — scores reset when rotating the phone
  4. Validation — negative scores are accepted (impossible in golf)
  5. Edge case — par calculation wrong when not all holes are played

Hint: each bug is isolated to one file. Use Logcat to reproduce, debugger to locate.

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Bug Report Template

Use this format for each bug found:

## Bug #1: [Short description]

**Symptom:** What did you observe?
**Location:** File and line number
**Root Cause:** Why was it happening?
**Fix:** What did you change?
**How I Found It:** Logcat? Debugger? Code reading? AI help?

Submit: GitHub link to fixed repo + bug report document

Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Debrief (10 minutes)

Discussion:

  • Which bug was hardest to find? Why?
  • What debugging technique worked best?
  • Did AI help? When was it useful vs. not?
  • "How many of these bugs could happen on tournament day?"
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Week 2 Wednesday Recap

Skill What to Remember
Logcat Filter by package; TAG every class
Log levels d for debug, w for unusual, e for errors
Stack traces Read bottom-to-top; find OUR code in the trace
Breakpoints Run in Debug mode — not normal Run
toIntOrNull() Never call toInt() on user input directly
Physical devices Emulators ≠ sunlight, battery, real GPS
Week 2 Wednesday: Debugging & Device Testing
CS 3180 Mobile Application Development

Friday: Lab 02

Debug Report — fix the buggy scorecard and document your findings

Before Friday: complete fixes and write bug reports for all 5 bugs

Week 2 Wednesday: Debugging & Device Testing

SPEAKER NOTES: Welcome to the most practical session of the early semester. Today we practice the skill that separates productive developers from frustrated ones: systematic debugging. All examples come from scenarios Maria's volunteers would actually encounter on the golf course. By end of class students will have used Logcat, set breakpoints, read a stack trace, and optionally run the app on a physical device.

SPEAKER NOTES: Make this feel real. On tournament day, Maria is stressed, volunteers are confused, and there's no time to run the debugger at leisure. Good logging and debugging skills today = faster fixes when it matters. The "twelve" scenario is a real class of bug — user input is never what you expect.

SPEAKER NOTES: Logcat is the most important debugging tool for day-to-day Android development. Before breakpoints, before profilers — when in doubt, add a log. We'll learn the log levels, how to filter the noise, and how to write useful log messages in our golf app.

SPEAKER NOTES: Emphasize filtering. Unfiltered Logcat shows every log from every process — overwhelming. Filter by package to see only our app's output. The tag is the second argument to Log methods — it's a short string identifying the source, like "ScoreEntry" or "Leaderboard". Students should develop a habit of always setting a TAG constant.

SPEAKER NOTES: Walk through each log call. The TAG constant at the top is the standard Android pattern. Log.d for the happy path — we always log what was submitted. Log.e when validation fails — we want to see this in Logcat immediately. Log.w for unusual but technically valid scores — a 15 on a par 3 is suspicious but allowed. Log.i for successful completion. This is a complete logging pattern students should copy into their work.

SPEAKER NOTES: Logcat tells you what happened. Breakpoints let you pause time and inspect why. The combination is powerful — logs for production diagnostics, breakpoints for interactive investigation during development. Key prerequisite: run in Debug mode, not normal Run mode. This is the #1 student mistake.

SPEAKER NOTES: Common mistake: students click Run instead of Debug. If the app isn't pausing at breakpoints, that's always why. Demonstrate the difference visually if possible. The Step Over / Step Into distinction matters for following code into a helper function. In the golf app, stepping into submitScore from a button click is a typical debug session.

SPEAKER NOTES: Walk through this deliberately. Students often look at the top of the stack trace (the exception type) and the deepest frame (standard library code) and are confused why it points to java.lang. The actionable frame is always the one that mentions OUR code — in this case ScoreEntry.kt:15. That's where we put the fix. The bottom-to-top reading habit is essential for productive debugging.

SPEAKER NOTES: Time to watch the full workflow in action. The buggy app has two problems — a crash on non-numeric input and an off-by-one error in the average. We'll find and fix both using the techniques we just discussed. Students should watch first, then they'll do a similar exercise themselves.

SPEAKER NOTES: Type "four" and run to reproduce Bug 1. Show the NumberFormatException in Logcat. Set a breakpoint on the toInt() line, run in Debug mode, type "four" again, inspect currentInput. Fix with toIntOrNull() ?: return. For Bug 2: add scores 4, 5, 3 and watch the running average in Logcat — it will be wrong. Trace through the math. Order of operations: sum/size happens first, then -1. Fix by wrapping in parentheses or using a more explicit calculation.

SPEAKER NOTES: This pattern — toIntOrNull() with Elvis ?: return — is something students will write dozens of times in this course. Every time a user types text that should be a number, this is the right approach. Reinforce: the crash happened because we trusted user input. Never trust user input.

SPEAKER NOTES: The - 1 was clearly wrong but easy to miss visually. The log showed us the wrong values — that's how we traced it. Also show holeScores.average() as the idiomatic Kotlin solution: returns Double, handles empty list without divide-by-zero. In the real golf app we'd use this for scorecard averages.

SPEAKER NOTES: Show this workflow live if possible. AI is excellent at explaining stack traces. But the goal is understanding — if a student applies the fix without understanding it, they'll make the same mistake in the next function. The exam will present a stack trace and ask what's wrong. Quick recap: paste the full text, not a screenshot (AI can't read screenshots as accurately).

SPEAKER NOTES: Emulators are convenient but they can't simulate everything. GPS accuracy, sunlight readability, battery drain, haptic feedback — these only exist on real hardware. Hope Foundation's volunteers will use real phones, so physical device testing is not optional for the team project.

SPEAKER NOTES: The sunlight point always resonates. Students haven't thought about it until now — if the screen is hard to read in bright sun, volunteers won't use the app. That's a UX concern that only appears when you walk outside with the app running. Physical testing is a professional responsibility, not optional polish.

SPEAKER NOTES: Walk through this live if you have an Android device. Students with Android phones should follow along. The "tap seven times" easter egg is intentional — it prevents casual users from enabling developer mode by accident. Once enabled, Developer Options persists; it doesn't need to be re-enabled after reboot.

SPEAKER NOTES: Wireless debugging is genuinely useful for testing the golf scorecard while physically moving around — simulates a volunteer walking between holes. For the team project, encourage at least one person per team to set up wireless debugging on their physical device.

SPEAKER NOTES: Students without Android devices: emulators can simulate different API levels and screen sizes. But encourage borrowing a friend's device for at least one physical test. Firebase Test Lab (mentioned in zyBook) runs apps on real cloud-hosted devices — advanced but worth knowing exists.

SPEAKER NOTES: Now students do it themselves. The buggy project is available on GitHub Classroom. Five real bugs — the kind that would actually ruin tournament day. Students have 25 minutes to find and fix them, then we debrief together. Circulate and give hints, but try not to give away the location — the process of searching is the learning.

SPEAKER NOTES: The app is a simple 9-hole scorecard. It runs but has issues. Students should first explore what it's supposed to do, then use the techniques from today to hunt down bugs. Remind them to use Logcat filtering and breakpoints — not just reading the code.

SPEAKER NOTES: Bug 3 (rotation) introduces rememberSaveable — students may not know about it yet. If they get stuck there, hint: "How does Compose save state across configuration changes?" Bug 5 (edge case) requires thinking about partial lists — a good data-structures moment. All 5 are real Android bugs that show up in production apps.

SPEAKER NOTES: The "How I Found It" field is important for reflection. Students who used AI to find bugs should say so — this is part of the AI disclosure policy. The goal is a systematic written record, not just a fixed file. In a real team, this document becomes the post-mortem that prevents recurrence.

SPEAKER NOTES: The last question always produces good discussion. All five bugs are plausible on tournament day — crashes, wrong scores, lost data on rotation, invalid input accepted. Connect back to Maria: every bug in this list is a bug that would make a volunteer give up on the app and go back to paper cards.

SPEAKER NOTES: Quick review before dismissal. The toIntOrNull() habit is something to reinforce repeatedly — it's one of the most common avoidable crashes in Android apps. The physical device row connects to the team project requirements.

SPEAKER NOTES: Lab 02 is the debugging workshop carried to completion. Students who didn't finish in class complete it before Friday. The deliverable: fixed GitHub repo + bug report document. Remind them: the bug report is as important as the fix — future employers look for systematic problem-solving skills, not just working code.