# ๐Ÿ”ง Troubleshooting Guide ## Common Issues & Solutions ### ๐Ÿšจ Build Issues #### Issue 1: Gradle Sync Failed **Error**: `Gradle sync failed: Failed to resolve...` **Solutions**: 1. Clean project: `Build` โ†’ `Clean Project` 2. Invalidate caches: `File` โ†’ `Invalidate Caches / Restart` 3. Sync Gradle: `File` โ†’ `Sync Now` 4. Delete `.gradle` folder and try again 5. Check internet connection (gradle downloads dependencies) --- #### Issue 2: Missing Dependencies **Error**: `Unresolved reference: LocationValidator` atau similar **Solutions**: 1. Verify file exists in correct package structure 2. Check package declaration at top of file 3. Rebuild project: `Build` โ†’ `Rebuild Project` 4. Check that all imports are present 5. File โ†’ Invalidate Caches / Restart --- #### Issue 3: Kotlin Syntax Error **Error**: `Type mismatch: inferred type is String? but Boolean was expected` **Solutions**: 1. Check null-safety: use `?.` or `!!` appropriately 2. Verify data class properties match their types 3. Look for missing type annotations 4. Check imports for correct classes --- ### ๐Ÿ“ Location Issues #### Issue 1: GPS Not Acquiring Location **Error**: "Lokasi tidak tersedia" **Causes & Solutions**: - โŒ Location permission not granted โ†’ Check Settings โ†’ Apps โ†’ Permissions โ†’ Location (Allow) - โŒ Location services disabled โ†’ Enable in Settings โ†’ Location โ†’ Location Services - โŒ Cold start GPS (takes time to acquire) โ†’ Wait 30-60 seconds for GPS to warm up โ†’ Or enable "Use high accuracy" in location settings - โŒ Testing in emulator โ†’ Use Extended Controls โ†’ Location to simulate GPS โ†’ Or use GPX file for GPS simulation **Quick Check**: ```kotlin // Test if GPS is available val hasLocationPermission = ContextCompat.checkSelfPermission( context, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED // Test if location services enabled val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager val isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ``` --- #### Issue 2: Location Always Invalid **Error**: "โœ— Lokasi tidak valid (2500m, maksimal 100m)" **Causes & Solutions**: - โŒ Reference coordinates wrong โ†’ Update `REFERENCE_LATITUDE` dan `REFERENCE_LONGITUDE` di `AttendanceConfig.kt` โ†’ Verify with Google Maps - โŒ Radius too small โ†’ Increase `ALLOWED_RADIUS_METERS` temporarily for testing โ†’ Default is 100m, try 200m or 300m - โŒ Testing from wrong location โ†’ Go to actual campus location โ†’ Or use emulator GPS simulation **How to Fix**: ```kotlin // File: AttendanceConfig.kt const val REFERENCE_LATITUDE = -7.025 // โ† Update this const val REFERENCE_LONGITUDE = 110.415 // โ† Update this const val ALLOWED_RADIUS_METERS = 100.0 // โ† Or increase this ``` **How to Verify Reference Coordinates**: 1. Go to campus location with device 2. Open Google Maps 3. Long-click on map โ†’ Coordinates appear at top 4. Copy latitude and longitude 5. Update in `AttendanceConfig.kt` --- #### Issue 3: Distance Calculation Wrong **Error**: Shows 5000m distance when clearly close to reference **Causes & Solutions**: - โŒ Latitude/longitude swapped โ†’ Check: latitude is first, longitude is second โ†’ Format should be: (-7.025, 110.415) not (110.415, -7.025) - โŒ Wrong location acquired โ†’ Check Logcat: `Log.d("Location", "Lat: $lat, Lon: $lon")` โ†’ Verify with Google Maps - โŒ Haversine formula bug โ†’ Run unit tests: `./gradlew test` โ†’ Check LocationValidatorTest results **Debug Steps**: ```kotlin // Add logging to MainActivity Log.d("AbsensiApp", "Reference: -7.0, 110.4") Log.d("AbsensiApp", "Student: ${state.location?.latitude}, ${state.location?.longitude}") Log.d("AbsensiApp", "Distance: ???") // Or test manually val distance = LocationValidator.calculateDistance( -7.0, 110.4, -7.0035, 110.4042 ) Log.d("Distance Test", "Result: $distance meters") ``` --- ### ๐Ÿ“ธ Camera Issues #### Issue 1: Camera Permission Denied **Error**: "Izin kamera ditolak" **Solutions**: 1. Open Settings โ†’ Apps โ†’ YourApp โ†’ Permissions 2. Find "Camera" permission 3. Tap it โ†’ Select "Allow" 4. Return to app and try again **For Emulator**: 1. Device Manager โ†’ Create/Edit device 2. Verify "Camera" is checked in hardware 3. Set Camera: "Emulated" --- #### Issue 2: Photo Not Captured **Error**: Camera opens but no photo saved **Causes & Solutions**: - โŒ User canceled camera intent โ†’ Just tap button again to retry - โŒ Storage permission issue (older Android) โ†’ Grant `WRITE_EXTERNAL_STORAGE` in Settings - โŒ Camera intent failure โ†’ Check if device has camera: `hasSystemFeature(PackageManager.FEATURE_CAMERA)` **Debug**: ```kotlin // Check in logcat Log.d("Camera", "Result Code: $resultCode") Log.d("Camera", "Data: ${result.data}") Log.d("Camera", "Bitmap: ${bitmap != null}") ``` --- #### Issue 3: Photo Preview Not Showing **Error**: PhotoPreviewCard shows "Belum ada foto" **Causes & Solutions**: - โŒ Bitmap is null โ†’ Check Activity.RESULT_OK returned โ†’ Verify `result.data?.extras?.getParcelable` working - โŒ UI not updating โ†’ Ensure state.copy() is called โ†’ Check LaunchedEffect dependencies **Quick Fix**: ```kotlin // Add logging if (bitmap != null) { Log.d("Photo", "Bitmap size: ${bitmap.width}x${bitmap.height}") state = state.copy(foto = bitmap) } else { Log.d("Photo", "Bitmap is null!") } ``` --- ### ๐ŸŒ Network Issues #### Issue 1: Cannot Connect to Webhook **Error**: "Gagal kirim ke server" or timeout **Causes & Solutions**: - โŒ No internet connection โ†’ Check WiFi/mobile data enabled โ†’ Ping google.com to verify - โŒ Wrong webhook URL โ†’ Verify in `AttendanceConfig.kt` โ†’ Copy exact URL from N8n dashboard - โŒ Firewall/VPN blocking โ†’ Disable VPN temporarily โ†’ Check if institution firewall allows HTTPS - โŒ N8n server down โ†’ Test with curl: `curl -X POST https://n8n.lab.ubharajaya.ac.id/webhook/...` โ†’ Check N8n status page **Webhook URL Check**: ```kotlin // File: AttendanceConfig.kt const val WEBHOOK_PRODUCTION = "https://n8n.lab.ubharajaya.ac.id/webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254" // โ†‘ Copy exact URL, no typos! ``` --- #### Issue 2: Server Returns 400/500 Error **Error**: "Absensi ditolak server" with error code **Causes & Solutions**: - **Status 400**: Data format wrong โ†’ Verify JSON structure matches expectations โ†’ Check all fields are present (npm, nama, lat, lon, foto) โ†’ Check foto is valid Base64 - **Status 401**: Authentication failed โ†’ Add authentication token if required โ†’ Contact server admin - **Status 500**: Server error โ†’ Check N8n workflow logs โ†’ Verify database connection โ†’ Retry after server is fixed **Test with Test Webhook First**: ```kotlin // In MainActivity isTest = true // Set this to test first // Check results at: https://n8n.lab.ubharajaya.ac.id/webhook-test/... ``` --- #### Issue 3: Timeout (Takes Too Long) **Error**: Request hangs for 30+ seconds then fails **Solutions**: 1. Check network speed: Test with speed.test.com 2. Reduce photo size: Decrease `PHOTO_QUALITY` in `AttendanceConfig.kt` 3. Increase timeout: Change `API_TIMEOUT_MS` (but not recommended) 4. Check server response time (might be slow) ```kotlin // File: AttendanceConfig.kt const val PHOTO_QUALITY = 70 // Reduce from 80 to 70 const val API_TIMEOUT_MS = 30000 // Current 30 seconds ``` --- ### โš™๏ธ Permission Issues #### Issue 1: Permission Dialog Not Appearing **Error**: App crashes or silently fails **Solutions**: 1. Verify permission in `AndroidManifest.xml`: ```xml ``` 2. Check permission launcher is called: ```kotlin LaunchedEffect(Unit) { locationPermissionLauncher.launch( Manifest.permission.ACCESS_FINE_LOCATION ) } ``` 3. For Android 12+, check targetSdk: ```gradle targetSdk = 36 ``` --- #### Issue 2: Permission Stuck on Denied **Error**: User clicks "Deny" and can't recover **Solutions**: 1. User must go to Settings manually: โ†’ Settings โ†’ Apps โ†’ YourApp โ†’ Permissions โ†’ Allow 2. Add UI hint in app: ```kotlin if (state.errorMessage?.contains("Izin") == true) { Button("Buka Pengaturan") { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) startActivity(intent) } } ``` --- ### ๐Ÿ’พ Data & State Issues #### Issue 1: Form Not Validating **Error**: Submit button always disabled or always enabled **Causes & Solutions**: - โŒ Validation logic wrong โ†’ Check `LocationValidator.isLocationValid()` implementation โ†’ Run unit tests: `./gradlew test` - โŒ State not updating โ†’ Verify state.copy() being called โ†’ Check all conditions in button enabled state **Validation Checklist**: ```kotlin // Button should be enabled only when ALL true: val canSubmit = ( state.location != null && // Location acquired state.foto != null && // Photo taken state.validationResult.isValid && // Location valid !state.isLoadingSubmit // Not currently submitting ) SubmitButtonWithLoader( // ... isEnabled = canSubmit // โ† Check this ) ``` --- #### Issue 2: State Lost on Screen Rotation **Error**: Form data disappears when device rotates **Solutions**: This is normal - Compose restores state automatically via `remember {}` To persist across full app restart: ```kotlin // Would need ViewModel + SavedStateHandle (advanced feature) // Currently: state is reset on process death (acceptable for MVP) ``` --- #### Issue 3: Photo Bitmap Memory Issue **Error**: "OutOfMemoryError: Bitmap too large" or app crashes **Solutions**: 1. Reduce photo quality: ```kotlin const val PHOTO_QUALITY = 60 // Reduce from 80 ``` 2. Compress after capture: ```kotlin // In bitmapToBase64: bitmap.compress(Bitmap.CompressFormat.JPEG, PHOTO_QUALITY, outputStream) ``` 3. For low-memory devices: - Scale down bitmap before encoding - Or use WebP format (better compression) --- ### ๐Ÿงช Testing Issues #### Issue 1: Unit Tests Not Running **Error**: "No tests found" or tests fail **Solutions**: 1. Run from command line: ```bash ./gradlew test ``` 2. Or in Android Studio: - Right-click test file โ†’ Run 'LocationValidatorTest' - Or use Test Configuration 3. Verify test file location: ``` app/src/test/java/.../LocationValidatorTest.kt โœ“ Correct app/src/androidTest/java/.../LocationValidatorTest.kt โœ— Wrong ``` --- #### Issue 2: Manual Testing Stuck **Error**: Can't reproduce the flow **Quick Test Checklist**: - [ ] Device/emulator has internet - [ ] Location services enabled - [ ] All permissions granted - [ ] Camera app works - [ ] Webhook URL correct **Fastest Flow**: 1. Grant permissions automatically 2. Hardcode valid location (for testing) 3. Take photo 4. Click submit 5. Should complete in < 10 seconds --- ### ๐ŸŽจ UI Issues #### Issue 1: Layout Cut Off on Small Screens **Error**: Buttons/text not visible **Solutions**: 1. Already implemented: `verticalScroll(rememberScrollState())` 2. Reduce padding: `modifier.padding(16.dp)` โ†’ `modifier.padding(8.dp)` 3. Use `Column` scrolling instead of fixed height ```kotlin Column( modifier = modifier .fillMaxSize() .padding(16.dp) .verticalScroll(rememberScrollState()) // โ† This allows scrolling ) ``` --- #### Issue 2: Dark Mode Not Working **Error**: Text hard to read or colors wrong **Solutions**: 1. Theme already supports dynamic colors (Material 3) 2. Verify `Theme.kt` has proper dark/light variants 3. Test: Settings โ†’ Display โ†’ Dark theme โ†’ On/Off --- #### Issue 3: Loading Spinner Not Showing **Error**: Button says "Mengirim..." but no spinner **Solutions**: 1. Check `isLoading` state is true: ```kotlin state = state.copy(isLoadingSubmit = true) ``` 2. Verify spinner code in `SubmitButtonWithLoader`: ```kotlin if (isLoading) { CircularProgressIndicator(...) // โ† Should show } ``` --- ## ๐Ÿ†˜ Emergency Troubleshooting ### App Crashes on Launch 1. Check Logcat for full error stack trace 2. Look for line number where crash happens 3. Most common: Missing permission or dependency 4. Try: `Build` โ†’ `Clean Project` โ†’ `Rebuild Project` ### Complete State Reset ```bash # Uninstall app completely ./gradlew uninstallDebug # Clean all build artifacts ./gradlew clean # Rebuild everything ./gradlew installDebug ``` ### Last Resort: Check Dependencies ```gradle // Verify all dependencies installed ./gradlew dependencies // Check for conflicts ./gradlew dependencyInsight --dependency location-services ``` --- ## ๐Ÿ“Š Debugging Commands ### View All Logs ```bash adb logcat ``` ### Filter Specific Tags ```bash adb logcat | grep "AbsensiApp" adb logcat | grep "N8nService" adb logcat | grep "LocationValidator" ``` ### Clear Logs ```bash adb logcat -c ``` ### Install Debug App ```bash ./gradlew installDebug ``` ### Uninstall App ```bash adb uninstall id.ac.ubharajaya.sistemakademik ``` ### View App Logs in Real-time ```bash adb logcat *:S AbsensiApp:D ``` --- ## ๐Ÿ” Verification Checklist Before declaring bug fixed, verify: - [ ] Issue is reproducible - [ ] Logs show no errors - [ ] All permissions granted - [ ] Internet connection active - [ ] Coordinates correct - [ ] Server responding - [ ] Photo quality acceptable - [ ] Location accuracy good - [ ] Form submission successful - [ ] Data received at webhook --- **Still stuck?** 1. Re-read QUICK_REFERENCE.md 2. Check DOKUMENTASI.md for detailed explanations 3. Review TESTING_CHECKLIST.md for testing procedures 4. Check ARCHITECTURE.md for design understanding 5. Look at comments in actual code files --- **Last Updated**: January 14, 2026 **Version**: 1.0