2026-01-14 19:31:41 +07:00

30 KiB

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

// AndroidX Core
implementation("androidx.core:core-ktx:1.17.0")
// Kotlin standard library dan extensions

Jetpack Compose

// 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

// 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

// Activity untuk Compose
implementation("androidx.activity:activity-compose:1.9.0")

Location Services

// Google Play Services Location
implementation("com.google.android.gms:play-services-location:21.0.1")

Database (Room)

// 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

// 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

// Encrypted SharedPreferences
implementation("androidx.security:security-crypto:1.1.0-alpha06")

Background Work

// WorkManager
implementation("androidx.work:work-runtime-ktx:2.9.0")

Coroutines

// Kotlin Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")

Image Loading

// Coil untuk Compose
implementation("io.coil-kt:coil-compose:2.6.0")

JSON Processing

// Gson
implementation("com.google.code.gson:gson:2.10.1")

Testing

// 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

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:

{
  "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:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>

Hardware features:

<uses-feature android:name="android.hardware.camera" android:required="false"/>

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

  2. ntfy Notification Service

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

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

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

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

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

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

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:

.\gradlew assembleDebug

Release Build:

.\gradlew assembleRelease

Clean Build:

.\gradlew clean assembleDebug

Install ke Device:

.\gradlew installDebug

Run Tests:

.\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