# ๐ง 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