# Aplikasi Absensi Akademik Berbasis Koordinat dan Foto Sistem Absensi Mahasiswa Universitas Bhayangkara Jakarta Raya Berbasis Android dengan validasi lokasi GPS dan foto real-time --- ## INFORMASI PROYEK Nama : Rakha Adi Saputro NPM : 202310715083 Mata Kuliah : Pemrograman Mobile Universitas : Universitas Bhayangkara Jakarta Raya Tahun : 2025-2026 --- ## DESKRIPSI SISTEM Aplikasi absensi mahasiswa modern berbasis Android yang mengimplementasikan arsitektur MVVM (Model-View-ViewModel) dengan pendekatan offline-first. Sistem ini memastikan validitas kehadiran mahasiswa melalui verifikasi lokasi GPS dan pengambilan foto selfie secara real-time saat melakukan absensi. Fitur utama: - Validasi lokasi berbasis GPS dengan radius 500 meter dari titik kampus - Pengambilan foto selfie wajib saat absensi - Penyimpanan data lokal dengan sinkronisasi otomatis ke backend - Sistem login offline dengan enkripsi data - Riwayat absensi tersimpan secara lokal - Anti-spam: Satu foto untuk satu kali absensi --- ## DEPENDENCY LENGKAP (build.gradle.kts) ### Core Android ```kotlin // AndroidX Core implementation("androidx.core:core-ktx:1.17.0") // Kotlin standard library dan extensions ``` ### Jetpack Compose ```kotlin // Compose BOM (Bill of Materials) - Mengelola versi Compose implementation(platform("androidx.compose:compose-bom:2024.09.00")) // Compose UI implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") // Material Design 3 implementation("androidx.compose.material3:material3") // Material Icons Extended implementation("androidx.compose.material:material-icons-extended:1.6.0") ``` ### Lifecycle & ViewModel ```kotlin // Lifecycle Runtime implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4") implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0") // ViewModel untuk Compose implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0") ``` ### Activity & Navigation ```kotlin // Activity untuk Compose implementation("androidx.activity:activity-compose:1.9.0") ``` ### Location Services ```kotlin // Google Play Services Location implementation("com.google.android.gms:play-services-location:21.0.1") ``` ### Database (Room) ```kotlin // Room components implementation("androidx.room:room-runtime:2.6.1") implementation("androidx.room:room-ktx:2.6.1") kapt("androidx.room:room-compiler:2.6.1") // Annotation processor ``` ### Network ```kotlin // Retrofit implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") // OkHttp implementation("com.squareup.okhttp3:logging-interceptor:4.11.0") ``` ### Security ```kotlin // Encrypted SharedPreferences implementation("androidx.security:security-crypto:1.1.0-alpha06") ``` ### Background Work ```kotlin // WorkManager implementation("androidx.work:work-runtime-ktx:2.9.0") ``` ### Coroutines ```kotlin // Kotlin Coroutines implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") ``` ### Image Loading ```kotlin // Coil untuk Compose implementation("io.coil-kt:coil-compose:2.6.0") ``` ### JSON Processing ```kotlin // Gson implementation("com.google.code.gson:gson:2.10.1") ``` ### Testing ```kotlin // Unit Testing testImplementation("junit:junit:4.13.2") // Instrumented Testing androidTestImplementation("androidx.test.ext:junit:1.3.0") androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0") androidTestImplementation(platform("androidx.compose:compose-bom:2024.09.00")) androidTestImplementation("androidx.compose.ui:ui-test-junit4") // Debug debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") ``` ### Gradle Plugins ```kotlin plugins { alias(libs.plugins.android.application) // AGP 8.13.2 alias(libs.plugins.kotlin.android) // Kotlin 2.0.21 alias(libs.plugins.kotlin.compose) // Compose Compiler id("org.jetbrains.kotlin.kapt") // KAPT untuk Room } ``` --- ## ALASAN PEMILIHAN TEKNOLOGI ### Mengapa Jetpack Compose? 1. **Modern & Declarative**: Lebih intuitif dan less boilerplate dibanding XML 2. **Type-safe**: Compile-time error detection 3. **Reactive**: Automatic UI updates saat state berubah 4. **Performance**: Efficient rendering dengan recomposition 5. **Official**: Recommended oleh Google untuk new projects 6. **Community**: Strong community support dan active development ### Mengapa Room Database? 1. **Type-safe SQL**: Compile-time SQL query verification 2. **Coroutine Support**: Native async/await dengan suspend functions 3. **Reactive Queries**: Flow untuk reactive updates 4. **Migration Support**: Easy database version management 5. **Performance**: Optimized SQLite wrapper 6. **Official**: Part of Android Jetpack ### Mengapa WorkManager? 1. **Guaranteed Execution**: Task akan dijalankan meski app tertutup 2. **Battery Efficient**: System-managed scheduling 3. **Constraints**: Network, battery, storage constraints 4. **Backward Compatible**: Works dari API 14+ 5. **Retry Logic**: Built-in retry dengan backoff 6. **Official**: Recommended untuk background work ### Mengapa Retrofit + OkHttp? 1. **Type-safe**: Type-safe REST client 2. **Coroutine Support**: Native suspend functions 3. **Converter**: Auto JSON parsing dengan Gson 4. **Interceptor**: Logging, auth, retry logic 5. **Industry Standard**: Most popular Android HTTP client 6. **Maintained**: Active development dan support ### Mengapa Encrypted SharedPreferences? 1. **Security**: AES256-GCM encryption 2. **Hardware-backed**: Android Keystore System 3. **Transparent**: No manual encryption code needed 4. **Simple API**: Same as regular SharedPreferences 5. **Official**: Part of Jetpack Security 6. **Compliant**: Meets security best practices ### Mengapa Kotlin Coroutines? 1. **Lightweight**: Efficient thread management 2. **Structured Concurrency**: Prevents memory leaks 3. **Sequential Code**: Async code looks synchronous 4. **Exception Handling**: Structured exception propagation 5. **Cancellation**: Automatic cleanup 6. **Official**: First-class support in Android ### Mengapa Coil untuk Image Loading? 1. **Kotlin-first**: Written in Kotlin untuk Kotlin 2. **Compose-native**: AsyncImage composable 3. **Coroutine-based**: Non-blocking operations 4. **Modern**: Uses OkHttp, supports latest formats 5. **Lightweight**: Smaller APK size vs Glide/Picasso 6. **Fast**: Memory & disk caching --- ## PERBANDINGAN ALTERNATIF ### UI Framework - **Jetpack Compose** vs XML Views - Compose: Less code, reactive, modern - XML: Mature, more resources, backward compatible - **Pilihan**: Compose (future-proof, better DX) ### Database - **Room** vs Realm vs SQLite - Room: Type-safe, official, Jetpack integration - Realm: Fast, cross-platform - SQLite: Full control, verbose - **Pilihan**: Room (best practices, official support) ### Image Loading - **Coil** vs Glide vs Picasso - Coil: Kotlin-first, Compose-native, modern - Glide: Mature, feature-rich, large - Picasso: Simple, lightweight, older - **Pilihan**: Coil (best for Compose) ### HTTP Client - **Retrofit** vs Ktor vs Volley - Retrofit: Type-safe, widely used, mature - Ktor: Kotlin-native, modern, less adoption - Volley: Google-made, older, less features - **Pilihan**: Retrofit (industry standard) ### State Management - **StateFlow** vs LiveData vs RxJava - StateFlow: Kotlin-native, Compose-friendly - LiveData: Lifecycle-aware, older - RxJava: Powerful, steep learning curve - **Pilihan**: StateFlow (modern, simple, official) --- ## ARSITEKTUR APLIKASI ### Pattern & Struktur MVVM (Model-View-ViewModel) dengan Offline-First Architecture ``` presentation/ UI Layer (Jetpack Compose) ├── auth/ Halaman Login & Registrasi ├── absensi/ Halaman Absensi Utama └── history/ Halaman Riwayat Absensi data/ Data Layer ├── local/ Local Storage │ ├── database/ Room Database │ ├── dao/ Data Access Object │ └── entity/ Database Entity ├── repository/ Repository Pattern ├── network/ Network Service (n8n) ├── worker/ Background Sync Worker └── model/ Data Models utils/ Utility Classes ├── NetworkUtils Network Connection Check └── ImageUtils Image Processing & Base64 ``` --- ## TEKNOLOGI & LIBRARY ### Platform & Bahasa - **Platform**: Android - **Bahasa**: Kotlin 2.0.21 - **Min SDK**: 28 (Android 9.0 Pie) - Alasan: Support untuk Security Crypto, modern permission system, dan coverage market share yang memadai - **Target SDK**: 36 (Android 14+) - **Compile SDK**: 36 - **JDK**: Java 11 (source & target compatibility) ### UI Framework & Design System **Jetpack Compose** - Modern Declarative UI Framework - **Compose BOM**: 2024.09.00 - **androidx.compose.ui**: Core Compose UI - **androidx.compose.ui.graphics**: Graphics primitives - **androidx.compose.ui.tooling**: Preview & debugging tools - **Keunggulan**: - Less code dibanding XML - Reactive & declarative - Type-safe - Hot reload support - Interoperability dengan View system **Material Design 3** - **androidx.compose.material3**: Material Design 3 components - **Components yang digunakan**: - Scaffold (app structure) - TopAppBar (navigation bar) - Card (content containers) - Button & OutlinedButton (actions) - OutlinedTextField (form inputs) - Text (typography) - CircularProgressIndicator (loading states) - AlertDialog (confirmations) - **Fitur**: Dynamic color, adaptive layouts, modern color system **Material Icons Extended** - **Version**: 1.6.0 - **Library**: androidx.compose.material:material-icons-extended - **Icons**: Person, Lock, Visibility, VisibilityOff, CameraAlt, MyLocation, History, Logout, Check, Close - **Total Icons**: 2000+ icons tersedia ### Database & Storage Layer **Room Database** - SQLite ORM (Object-Relational Mapping) - **Version**: 2.6.1 - **Components**: - **room-runtime**: Core library - **room-ktx**: Kotlin extensions & coroutine support - **room-compiler**: Annotation processor (KAPT) - **Fitur yang digunakan**: - @Entity (table definition) - @Dao (data access object) - @Query (SQL queries) - @Insert, @Update, @Delete - Flow untuk reactive queries - Suspend functions untuk coroutines - Migration support - **Table**: attendance_history - **Keunggulan**: Compile-time verification, type-safe queries, reactive streams **Encrypted SharedPreferences** - Secure Key-Value Storage - **Library**: androidx.security:security-crypto:1.1.0-alpha06 - **Encryption**: AES256-GCM (Galois/Counter Mode) - **Key Management**: MasterKey dengan Android Keystore System - **Key Scheme**: AES256_GCM - **Value Encryption**: AES256_GCM - **Key Encryption**: AES256_SIV (Synthetic IV) - **Fitur**: Transparent encryption/decryption, hardware-backed keys - **Data yang disimpan**: Username, Password, isRegistered, isLogin (semua terenkripsi) ### Location Services **Google Play Services Location** - **Version**: 21.0.1 - **Library**: com.google.android.gms:play-services-location - **API**: Fused Location Provider API - **Fitur yang digunakan**: - FusedLocationProviderClient (high-level API) - LocationRequest (accuracy & interval settings) - LocationCallback (location updates) - Priority: PRIORITY_HIGH_ACCURACY - **Validasi**: - 12 campus points dengan koordinat GPS - Haversine Formula untuk kalkulasi jarak - Location.distanceBetween() (Android built-in) - Max radius: 500 meter - **Keunggulan**: Battery-efficient, most accurate location ### Network & Backend Integration **Retrofit** - Type-safe HTTP Client - **Version**: 2.9.0 - **Library**: com.squareup.retrofit2:retrofit - **Fitur**: REST API calls, coroutine support, request/response converters - **Usage**: POST data absensi ke n8n webhook **Gson** - JSON Serialization/Deserialization - **Gson Version**: 2.10.1 - **Retrofit Converter**: com.squareup.retrofit2:converter-gson:2.9.0 - **Fitur**: Automatic JSON parsing, custom type adapters - **Usage**: Convert data objects ke JSON payload **OkHttp** - HTTP Client & Interceptor - **Version**: 4.11.0 - **Library**: com.squareup.okhttp3:logging-interceptor - **Fitur**: HTTP logging, connection pooling, interceptors - **Usage**: Debug network requests/responses, timeout configuration - **Timeout Settings**: 30 detik connection & read timeout **n8n Webhook Integration** - **Backend**: n8n Self-hosted Workflow Automation - **Host**: n8n.lab.ubharajaya.ac.id - **Method**: HTTP POST - **Content-Type**: application/json - **Endpoint Production**: /webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254 - **Endpoint Testing**: /webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254 - **Payload**: JSON dengan foto Base64, koordinat, timestamp, mata kuliah ### Background Processing **WorkManager** - Background Task Scheduler - **Version**: 2.9.0 - **Library**: androidx.work:work-runtime-ktx - **Fitur**: - Guaranteed execution (even after app restart) - Constraints (network, battery, storage) - Retry logic dengan exponential backoff - Work chaining - CoroutineWorker integration - **Usage**: AttendanceSyncWorker untuk sync data PENDING ke backend - **Trigger**: Network available constraint - **Strategy**: Periodic check & automatic retry **Kotlin Coroutines** - Asynchronous Programming - **Version**: 1.7.3 - **Library**: org.jetbrains.kotlinx:kotlinx-coroutines-android - **Dispatchers**: - **Dispatchers.Main**: UI operations & state updates - **Dispatchers.IO**: Network requests & database operations - **Dispatchers.Default**: CPU-intensive computations - **Features**: suspend functions, async/await, structured concurrency - **Usage**: Semua async operations (database, network, location) **Flow & StateFlow** - Reactive Streams - **Flow**: Cold stream untuk one-time operations - **StateFlow**: Hot stream untuk UI state management - **MutableStateFlow**: Mutable state holder - **collectAsState()**: Compose integration untuk observe state - **Usage**: ViewModel state management, database queries, UI updates ### Image Processing **Coil** - Image Loading Library untuk Compose - **Version**: 2.6.0 - **Library**: io.coil-kt:coil-compose - **Fitur**: - AsyncImage composable - Memory & disk caching - Image transformations - Compose-first design - Coroutine-based - **Usage**: Load & display foto absensi di riwayat **Custom Image Utils** - **Base64 Encoding**: Convert Bitmap ke Base64 string - **Bitmap Compression**: JPEG compression dengan quality 80% - **File I/O**: Save/load foto dari internal storage - **Camera Integration**: ActivityResultContracts.TakePicture() - **Usage**: Prepare foto untuk kirim ke backend ### Architecture Components **Lifecycle** - Lifecycle-Aware Components - **lifecycle-runtime-ktx**: 2.9.4 - **lifecycle-runtime-compose**: 2.7.0 - **lifecycle-viewmodel-compose**: 2.7.0 - **Fitur**: LifecycleOwner, ViewModelScope, collectAsStateWithLifecycle - **Usage**: Manage UI lifecycle, survive configuration changes **ViewModel** - UI State Holder - **Library**: androidx.lifecycle:lifecycle-viewmodel-compose - **Features**: Survive configuration changes, ViewModelScope - **ViewModels**: AuthViewModel, AbsensiViewModel, AttendanceHistoryViewModel - **State Management**: StateFlow untuk expose state ke UI **Activity Compose** - **Version**: 1.9.0 - **Library**: androidx.activity:activity-compose - **Features**: setContent {} untuk Compose, ComponentActivity, permission handling - **Usage**: MainActivity sebagai entry point ### Build Tools & Gradle **Gradle** - **Version**: 8.13.2 - **Type**: Kotlin DSL (build.gradle.kts) - **Plugin**: Android Gradle Plugin (AGP) - **Features**: Dependency management, build variants, ProGuard/R8 **Kotlin Compiler** - **Kotlin Version**: 2.0.21 - **Compose Compiler Plugin**: org.jetbrains.kotlin.plugin.compose - **KAPT**: Kotlin Annotation Processing Tool (untuk Room compiler) - **Target**: JVM 11 **Version Catalog** - **File**: gradle/libs.versions.toml - **Fitur**: Centralized dependency management, type-safe accessors - **Benefits**: Single source of truth, easy updates, IDE support ### Testing Framework **Unit Testing** - **JUnit**: 4.13.2 (unit test framework) - **Location**: src/test/java/ **Instrumented Testing** - **AndroidX Test JUnit**: 1.3.0 - **Espresso Core**: 3.7.0 - **Compose UI Test**: androidx.compose.ui:ui-test-junit4 - **Location**: src/androidTest/java/ **Debug Tools** - **Compose UI Tooling**: Preview & inspection - **Compose UI Test Manifest**: Test configuration ### Utilities & Helpers **NetworkUtils.kt** - **Purpose**: Network connectivity checking - **API**: ConnectivityManager - **Usage**: Cek internet sebelum sync ke backend **ImageUtils.kt** - **Purpose**: Image processing & conversion - **Functions**: bitmapToBase64, compression, file operations - **Usage**: Prepare foto untuk upload ### Security & Permissions **Android Permissions** - ACCESS_FINE_LOCATION (GPS) - ACCESS_COARSE_LOCATION (Network location) - CAMERA (Take photos) - INTERNET (Network communication) **Security Features** - Encrypted local storage - HTTPS communication - Hardware-backed key storage (Keystore) - No hardcoded credentials - Certificate transparency --- ## FITUR APLIKASI ### 1. SISTEM LOGIN OFFLINE - Konsep: First-time setup dengan one-time registration - Metode: Offline (tidak menggunakan server) - Penyimpanan: Encrypted SharedPreferences - Enkripsi: AES256-GCM dengan MasterKey - Data tersimpan: - Username (terenkripsi) - Password (terenkripsi) - isRegistered flag - isLogin flag - Flow: - Pertama kali: Buat username & password - Selanjutnya: Login dengan kredensial tersimpan - Validasi: Dilakukan secara lokal ### 2. ABSENSI BERBASIS LOKASI - Validasi radius: Maksimal 500 meter dari titik kampus - Jumlah titik kampus: 12 lokasi strategis - Titik kampus meliputi: - Kampus Ubhara Jaya (Pusat) - Fakultas Ilmu Komputer - Fakultas Ekonomi dan Bisnis - Fakultas Psikologi - Perpustakaan Tanoto - Grha Tanoto - Masjid Ulul Albab - Work Caffe Bekasi - Lapangan Ubhara - Sekretariat Kapal Baja - Ruang Sedang Semu - ATM BRI Ubhara Jaya - Algoritma: Haversine Formula untuk hitung jarak - Response: Menampilkan nama lokasi terdekat & jarak ### 3. PENGAMBILAN FOTO ABSENSI - Mode: Kamera depan (selfie) - Trigger: Langsung saat proses absensi - Batasan: Satu foto untuk satu kali absensi (anti-spam) - Penyimpanan: Internal storage aplikasi - Format: JPEG dengan kompresi - Pengiriman: Konversi ke Base64 untuk dikirim ke backend ### 4. PENYIMPANAN DATA LOKAL Database: Room (SQLite) Table: attendance_history Schema: - id: String (UUID, Primary Key) - studentId: String (NPM mahasiswa) - studentName: String (Nama mahasiswa) - courseName: String (Nama mata kuliah) - photoPath: String (Path foto di storage) - dateTime: Long (Timestamp Unix) - latitude: Double (Koordinat lintang) - longitude: Double (Koordinat bujur) - locationName: String (Nama lokasi terdekat) - distanceMeter: Int (Jarak dari titik kampus) - attendanceStatus: String (SUCCESS/FAILED) - syncStatus: String (PENDING/SYNCED) - createdAt: Long (Timestamp pembuatan) ### 5. SINKRONISASI BACKEND - Service: n8n Webhook Automation - Method: POST HTTP Request - Format: JSON dengan foto Base64 - Strategy: Offline-first dengan background sync - Worker: AttendanceSyncWorker (WorkManager) - Retry: Otomatis saat koneksi internet tersedia - Flow: 1. Simpan data ke local database 2. Cek koneksi internet 3. Jika online: Kirim langsung ke n8n 4. Jika offline: Tandai PENDING 5. Background worker cek pending data 6. Kirim ulang saat internet tersedia 7. Update status menjadi SYNCED Payload ke n8n: ```json { "npm": "202310715083", "nama": "Rakha Adi Saputro", "mata_kuliah": "Nama Mata Kuliah", "latitude": -6.224158, "longitude": 107.009268, "timestamp": "2025-01-14T10:30:00Z", "foto_base64": "base64_encoded_image_string" } ``` ### 6. RIWAYAT ABSENSI - Screen: AttendanceHistoryScreen - Data source: Room Database (local) - Layout: LazyColumn (efficient scrolling) - Card components: - Thumbnail foto absensi - Nama mata kuliah - Waktu absensi (formatted) - Koordinat lokasi - Jarak dari kampus - Status sinkronisasi (PENDING/SYNCED) - Filter: Semua data dari lokal - Offline support: Full offline browsing ### 7. DATA MAHASISWA Data mahasiswa yang digunakan fixed (hardcoded): - NPM: 202310715083 - Nama: Rakha Adi Saputro Catatan: Data ini tidak diambil dari login, tetapi langsung diset di aplikasi --- ## PERMISSIONS ANDROID Aplikasi memerlukan izin berikut: ```xml ``` Hardware features: ```xml ``` --- ## BACKEND INTEGRATION ### n8n Workflow Automation - Platform: n8n (Self-hosted) - Host: n8n.lab.ubharajaya.ac.id - Endpoint Production: /webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254 - Endpoint Testing: /webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254 ### Data Destination 1. Google Sheets - URL: https://docs.google.com/spreadsheets/d/1jH15MfnNgpPGuGeid0hYfY7fFUHCEFbCmg8afTyyLZs - Columns: NPM, Nama, Mata Kuliah, Latitude, Longitude, Timestamp, Foto 2. ntfy Notification Service - URL: https://ntfy.ubharajaya.ac.id/EAS - Purpose: Real-time notification untuk dosen/admin ### Workflow n8n File: n8n-workflow-EAS.json Flow: 1. Webhook Trigger (receive POST data) 2. Data Validation 3. Write to Google Sheets 4. Send notification via ntfy 5. Return response to mobile app --- ## STRUKTUR DATA FLOW ``` User Action (Absensi) | v Validasi Lokasi GPS | v Ambil Foto Selfie | v Simpan ke Room Database (Local) | v Update UI (Riwayat bertambah) | v Cek Koneksi Internet | +---> [Online] ---> Kirim ke n8n Webhook | | | v | Update syncStatus = SYNCED | +---> [Offline] ---> Set syncStatus = PENDING | v WorkManager scheduled | v [Internet tersedia] | v Retry kirim data PENDING | v Update syncStatus = SYNCED ``` --- ## CARA KERJA SISTEM ### Flow Lengkap Absensi: 1. PERSIAPAN - User buka aplikasi - Jika belum login: tampilkan AuthScreen - Jika sudah login: tampilkan AbsensiScreen 2. HALAMAN ABSENSI - Tampilkan NPM dan Nama (hardcoded) - Input mata kuliah - Tombol ambil foto - Request permissions (Camera & Location) 3. PROSES ABSENSI - User klik tombol absensi - Sistem cek permission camera - Buka camera untuk selfie - User ambil foto - Foto ditampilkan sebagai preview - Sistem ambil koordinat GPS otomatis - Validasi jarak dari titik kampus 4. VALIDASI - Cek jarak < 500 meter? - Ya: Lanjut proses - Tidak: Tampilkan error & batalkan - Cek foto valid? - Ya: Lanjut proses - Tidak: Minta foto ulang 5. PENYIMPANAN - Generate UUID untuk attendance ID - Simpan foto ke internal storage - Simpan data ke Room Database - Set syncStatus = PENDING 6. SINKRONISASI - Cek koneksi internet - Jika online: - Encode foto ke Base64 - Kirim POST ke n8n webhook - Jika sukses: Update syncStatus = SYNCED - Jika gagal: Tetap PENDING - Jika offline: - Skip sync - Data tetap PENDING - WorkManager akan retry nanti 7. BACKGROUND SYNC - WorkManager cek setiap internet tersedia - Ambil semua data PENDING - Kirim satu per satu ke n8n - Update status yang berhasil - Retry yang gagal 8. RIWAYAT - User bisa lihat semua absensi di HistoryScreen - Data diambil dari Room Database - Menampilkan status PENDING/SYNCED - Full offline support --- ## KEAMANAN ### 1. Enkripsi Data - Encrypted SharedPreferences dengan AES256-GCM - MasterKey untuk enkripsi kredensial login - Password tidak disimpan plain text ### 2. Validasi Lokasi - Multi-point validation (12 titik kampus) - Radius enforcement (500 meter maksimal) - Real-time distance calculation ### 3. Anti-Fraud - Satu foto untuk satu absensi - Foto harus diambil real-time (tidak bisa dari gallery) - Timestamp server-side di n8n - Validasi koordinat di backend (opsional) ### 4. Offline Security - Data lokal terenkripsi - No sensitive data in plain text - Secure file storage --- ## KONFIGURASI ENDPOINT File: ApiConfig.kt Location: data/network/ApiConfig.kt ```kotlin object ApiConfig { const val N8N_WEBHOOK_URL = "https://n8n.lab.ubharajaya.ac.id/webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254" // Untuk testing: // const val N8N_WEBHOOK_URL = // "https://n8n.lab.ubharajaya.ac.id/webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254" const val CONNECTION_TIMEOUT = 30000 // 30 detik const val READ_TIMEOUT = 30000 // 30 detik } ``` Keuntungan centralized config: - Mudah switch antara production & testing - Tidak perlu ubah banyak file - Maintenance lebih simple - Deploy lebih aman --- ## ANDROID SDK CONFIGURATION ### SDK Versions ```kotlin android { compileSdk = 36 defaultConfig { applicationId = "id.ac.ubharajaya.sistemakademik" minSdk = 28 targetSdk = 36 versionCode = 1 versionName = "1.0" } } ``` ### Min SDK 28 (Android 9.0 Pie) - Coverage & Features **Alasan pemilihan Min SDK 28:** 1. **Market Coverage**: ~80% devices (2024-2025 data) 2. **Security Features**: - Mandatory HTTPS - BiometricPrompt API - Security Crypto support 3. **Modern APIs**: - ImageDecoder API - DisplayCutout support - Indoor positioning (WiFi RTT) 4. **Location Features**: - Foreground location access - Better battery optimization 5. **Camera Features**: - Multi-camera API - Session parameters 6. **Performance**: - ART improvements - Background restrictions ### Target SDK 36 (Android 14+) - Latest Features **Benefits:** 1. Google Play requirement compliance 2. Latest security patches 3. Performance optimizations 4. New API features 5. Better battery management 6. Enhanced privacy controls ### Compile SDK 36 - Access to latest Android APIs - Build tools compatibility - Preview features - Development libraries ### Java Compatibility ```kotlin compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = "11" } ``` **Java 11 Features:** - Lambda expressions - Method references - Stream API - Optional class - Try-with-resources - Type inference (var) --- ## BUILD CONFIGURATION ### Build Types #### Debug Build ```kotlin buildTypes { debug { isMinifyEnabled = false isDebuggable = true applicationIdSuffix = ".debug" versionNameSuffix = "-DEBUG" } } ``` **Features:** - No code obfuscation - Full logging enabled - Faster build time - Debug symbols included - Network profiler enabled #### Release Build ```kotlin buildTypes { release { isMinifyEnabled = false // Set true for production proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) signingConfig = signingConfigs.getByName("release") } } ``` **Features:** - Code shrinking (ProGuard/R8) - Obfuscation - Optimization - Signing required - Smaller APK size ### Build Features ```kotlin buildFeatures { compose = true } ``` - Enables Jetpack Compose - Compose compiler integration - Preview support ### ProGuard/R8 Configuration File: `proguard-rules.pro` **Purpose:** - Code shrinking (remove unused code) - Obfuscation (rename classes/methods) - Optimization (inline, etc.) - APK size reduction **Keep Rules for:** - Room entities (@Entity) - Retrofit interfaces - Gson models - Parcelable classes ### APK Outputs **Debug APK:** - Path: `app/build/outputs/apk/debug/app-debug.apk` - Size: ~15-20 MB (with debug symbols) - Command: `.\gradlew assembleDebug` **Release APK:** - Path: `app/build/outputs/apk/release/app-release.apk` - Size: ~8-12 MB (minified) - Command: `.\gradlew assembleRelease` --- ## GRADLE BUILD SYSTEM ### Requirements - Android Studio Ladybug atau lebih baru - JDK 11 atau lebih tinggi - Android SDK 28-36 - Gradle 8.13.2 - Koneksi internet (untuk dependency download) ### Build Commands Development Build: ```bash .\gradlew assembleDebug ``` Release Build: ```bash .\gradlew assembleRelease ``` Clean Build: ```bash .\gradlew clean assembleDebug ``` Install ke Device: ```bash .\gradlew installDebug ``` Run Tests: ```bash .\gradlew test ``` ### Output Location APK Debug: app/build/outputs/apk/debug/app-debug.apk APK Release: app/build/outputs/apk/release/app-release.apk --- ## TESTING ### Akun Testing Saat pertama kali buka aplikasi: - Buat username dan password bebas - Data tersimpan secara offline - Login selanjutnya gunakan kredensial tersebut ### Testing Lokasi Opsi 1: Test di lokasi kampus (ideal) Opsi 2: Mock location untuk development: - Enable Developer Options - Select mock location app - Gunakan koordinat salah satu dari 12 titik kampus ### Testing n8n Webhook Gunakan endpoint testing: ``` https://n8n.lab.ubharajaya.ac.id/webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254 ``` Ganti di ApiConfig.kt untuk testing ### Monitoring - Google Sheets: Cek data masuk - ntfy: Cek notifikasi real-time - Logcat: Monitor logs di Android Studio --- ## TROUBLESHOOTING ### Issue: Foto tidak terkirim ke backend Solusi: - Cek koneksi internet - Cek endpoint n8n aktif - Lihat syncStatus di riwayat (PENDING berarti belum terkirim) - Background worker akan retry otomatis ### Issue: Lokasi tidak valid padahal di kampus Solusi: - Pastikan GPS aktif - Tunggu GPS lock (butuh waktu) - Cek permission lokasi granted - Pastikan tidak menggunakan VPN yang mengubah lokasi ### Issue: Kamera tidak bisa dibuka Solusi: - Cek permission camera granted - Restart aplikasi - Pastikan camera tidak digunakan app lain - Cek hardware camera berfungsi ### Issue: Data tidak tersimpan di database Solusi: - Cek storage permission - Cek disk space mencukupi - Lihat logcat untuk error Room - Clear app data dan coba lagi ### Issue: WorkManager tidak sync Solusi: - Pastikan internet stabil - Cek battery optimization (disable untuk app ini) - Force sync dengan buka riwayat - Restart device --- ### Author - NAMA : RAKHA ADI SAPUTRO - NPM : 202310715083