Vika SDK Documentation

Android SDK untuk voice-powered navigation dalam aplikasi JKN Mobile. Integrasikan voice assistant dengan mudah menggunakan deep link navigation.

Voice Recognition

AI-powered voice recognition dengan akurasi 98%+ untuk Bahasa Indonesia

Deep Link Navigation

Navigasi otomatis menggunakan Android Deep Links

Real-time Updates

Socket.IO integration untuk response real-time

Minimum Requirements: Android SDK 26+ (Android 8.0 Oreo), Kotlin 2.0+, Jetpack Compose

Installation

1. Configure GitHub Packages

Tambahkan repository GitHub Packages ke settings.gradle.kts:

settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()

        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/arafat1419/VIKA")
        }
    }
}

2. Add Dependency

Tambahkan dependency ke build.gradle.kts (app module):

app/build.gradle.kts
dependencies {
    // Vika SDK
    implementation("com.vika.sdk:vika-sdk:1.0.3")
}

3. Sync Project

Klik Sync Now atau jalankan:

Terminal
./gradlew build
Installation Complete! Sekarang Anda siap untuk mengintegrasikan Vika SDK ke aplikasi JKN Mobile.

Quick Start

Panduan cepat untuk mengintegrasikan Vika SDK dalam 3 langkah sederhana.

Step 1: Initialize SDK

Initialize SDK di Application class:

MyApplication.kt
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // Configure SDK
        val config = SDKConfig.Builder("YOUR_API_KEY")
            .debugMode(BuildConfig.DEBUG)
            .allowedDeepLinkSchemes("jkn")
            .language(VikaLanguage.INDONESIAN)
            .build()

        // Initialize SDK
        VikaSDK.initialize(
            context = this,
            config = config,
            callback = object : VikaSDK.Companion.InitCallback {
                override fun onSuccess() {
                    // SDK ready, register screens
                    registerScreens()
                }

                override fun onError(error: Throwable) {
                    // Handle initialization error
                    Log.e("Vika", "Init failed", error)
                }
            }
        )
    }
}

Step 2: Register Screens

Daftarkan semua screen yang bisa diakses via voice:

Screen Registration
private fun registerScreens() {
    val sdk = VikaSDK.getInstance()

    sdk.registerScreens(listOf(
        ScreenRegistration(
            screenId = "pendaftaran",
            screenName = "Pendaftaran Peserta",
            description = "Halaman untuk mendaftar sebagai peserta BPJS Kesehatan baru",
            deepLink = "jkn://pendaftaran",
            navigationType = NavigationType.DeepLink("jkn://pendaftaran"),
            keywords = listOf("daftar", "registrasi", "peserta baru")
        ),
        ScreenRegistration(
            screenId = "faskes",
            screenName = "Daftar Faskes",
            description = "Daftar fasilitas kesehatan terdekat",
            deepLink = "jkn://faskes",
            navigationType = NavigationType.DeepLink("jkn://faskes"),
            keywords = listOf("rumah sakit", "klinik", "puskesmas")
        )
    ))
}

Step 3: Open Voice UI

Panggil Voice UI dari button atau menu:

MainActivity.kt
// Simple usage
VikaSDK.getInstance().openVikaSDK(context)

// With custom options
val options = VikaUIOptions.builder()
    .displayMode(VikaDisplayMode.BOTTOM_SHEET)
    .appLogo(R.mipmap.ic_launcher)
    .appTitle("JKN Mobile")
    .build()

VikaSDK.getInstance().openVikaSDK(context, options)

[Screenshot: Voice UI Interface]

Configuration

Customize SDK behavior dengan berbagai opsi konfigurasi.

SDKConfig Options

Parameter Type Default Description
apiKey String - Required. API key dari dashboard
minConfidenceThreshold Float 0.7 Minimum confidence (0.0-1.0) untuk navigasi
debugMode Boolean false Enable debug logging (disable di production)
analyticsEnabled Boolean true Track navigation analytics
timeoutMillis Long 10000 Network request timeout (ms)
allowedDeepLinkSchemes List<String> [] Whitelist deep link schemes (e.g., "jkn")
language VikaLanguage ENGLISH UI language (ENGLISH / INDONESIAN)

Complete Configuration Example

Advanced Config
val config = SDKConfig.Builder("your-api-key")
    .minConfidenceThreshold(0.8f)
    .analyticsEnabled(true)
    .debugMode(BuildConfig.DEBUG)
    .timeout(15000L)
    .maxRetries(3)
    .cacheEnabled(true)
    .allowedDeepLinkSchemes("jkn", "bpjs")
    .language(VikaLanguage.INDONESIAN)
    .socketReconnectionAttempts(5)
    .socketReconnectionDelay(2000L)
    .build()

Screen Registration

Register screens agar bisa diakses via voice commands. Semakin detail informasi yang diberikan, semakin akurat AI mencocokkan voice command.

ScreenRegistration Fields

Field Type Required Description
screenId String Unique identifier (e.g., "pendaftaran")
screenName String Display name (e.g., "Pendaftaran Peserta")
description String Detail apa yang ada di screen ini (untuk AI matching)
deepLink String Deep link URI (e.g., "jkn://pendaftaran")
navigationType NavigationType Tipe navigasi (DeepLink only untuk saat ini)
keywords List<String> Additional keywords untuk improve matching accuracy

Best Practices

Use Descriptive Names: Gunakan nama yang jelas dan mudah dipahami pengguna JKN.
Detailed Descriptions: Sertakan detail fitur yang ada di screen untuk improve AI matching.
Add Keywords: Tambahkan variasi kata yang mungkin digunakan user (sinonim, abbreviasi).
Test Voice Commands: Test dengan berbagai cara user mungkin menyebutkan screen.

Example: JKN Mobile Screens

JKN Screen Registration
val jknScreens = listOf(
    // Home / Dashboard
    ScreenRegistration(
        screenId = "home",
        screenName = "Beranda",
        description = "Halaman utama JKN Mobile dengan informasi kartu, riwayat kunjungan, dan menu utama",
        deepLink = "jkn://home",
        navigationType = NavigationType.DeepLink("jkn://home"),
        keywords = listOf("beranda", "home", "utama", "dashboard")
    ),

    // Pendaftaran Peserta
    ScreenRegistration(
        screenId = "pendaftaran",
        screenName = "Pendaftaran Peserta",
        description = "Form pendaftaran peserta BPJS Kesehatan baru dengan upload dokumen KTP dan KK",
        deepLink = "jkn://pendaftaran",
        navigationType = NavigationType.DeepLink("jkn://pendaftaran"),
        keywords = listOf("daftar", "registrasi", "peserta baru", "buat akun")
    ),

    // Faskes Terdekat
    ScreenRegistration(
        screenId = "faskes",
        screenName = "Fasilitas Kesehatan",
        description = "Cari faskes terdekat: rumah sakit, klinik, puskesmas dengan peta dan navigasi",
        deepLink = "jkn://faskes",
        navigationType = NavigationType.DeepLink("jkn://faskes"),
        keywords = listOf("faskes", "rumah sakit", "rs", "klinik", "puskesmas")
    ),

    // Kartu Digital
    ScreenRegistration(
        screenId = "kartu",
        screenName = "Kartu Digital",
        description = "Tampilkan kartu BPJS digital dengan barcode dan informasi peserta",
        deepLink = "jkn://kartu",
        navigationType = NavigationType.DeepLink("jkn://kartu"),
        keywords = listOf("kartu", "bpjs", "digital", "e-kartu")
    ),

    // Riwayat Kunjungan
    ScreenRegistration(
        screenId = "riwayat",
        screenName = "Riwayat Kunjungan",
        description = "Histori kunjungan ke faskes dengan detail diagnosis dan obat",
        deepLink = "jkn://riwayat",
        navigationType = NavigationType.DeepLink("jkn://riwayat"),
        keywords = listOf("riwayat", "history", "kunjungan", "rekam medis")
    )
)

// Register all screens
VikaSDK.getInstance().registerScreens(jknScreens)

Voice UI

Vika SDK menyediakan UI untuk voice recording dengan waveform visualization. UI bisa ditampilkan dalam 3 mode berbeda.

Display Modes

FULLSCREEN

Full screen activity dengan branding app dan waveform besar. Best untuk first-time users.

[Screenshot Fullscreen]

DIALOG

Modal dialog dengan dismiss outside. Compact dan tidak mengganggu context.

[Screenshot Dialog]

BOTTOM_SHEET

Bottom sheet yang slide dari bawah. Modern dan familiar untuk mobile users.

[Screenshot Bottom Sheet]

Usage Examples

Voice UI Examples
// 1. Simple fullscreen (default)
VikaSDK.getInstance().openVikaSDK(context)

// 2. Dialog mode with custom branding
val dialogOptions = VikaUIOptions.builder()
    .displayMode(VikaDisplayMode.DIALOG)
    .appLogo(R.drawable.ic_jkn_logo)
    .appTitle("JKN Mobile")
    .dismissOnTouchOutside(true)
    .build()

VikaSDK.getInstance().openVikaSDK(context, dialogOptions)

// 3. Bottom sheet with custom theme
val customTheme = VikaThemeConfig(
    primaryColor = 0xFF0FAF65,        // JKN Green
    secondaryColor = 0xFF059669,      // Darker green
    backgroundColor = 0xFFFFFFFF,     // White
    textColor = 0xFF1F2937,          // Dark gray
    surfaceColor = 0xFFF9FAFB,       // Light gray
    waveformColor = 0xFF0FAF65       // JKN Green
)

val bottomSheetOptions = VikaUIOptions.builder()
    .displayMode(VikaDisplayMode.BOTTOM_SHEET)
    .appLogo(R.drawable.ic_jkn_logo)
    .appTitle("Vika Assistant")
    .theme(customTheme)
    .dismissOnTouchOutside(true)
    .build()

VikaSDK.getInstance().openVikaSDK(context, bottomSheetOptions)

UI Customization

Customize Voice UI agar match dengan branding JKN Mobile menggunakan VikaThemeConfig.

Theme Configuration

Property Type Description
primaryColor Long (0xFFRRGGBB) Main brand color untuk buttons & accents
secondaryColor Long (0xFFRRGGBB) Secondary color untuk highlights
backgroundColor Long (0xFFRRGGBB) Background color (usually white/dark)
textColor Long (0xFFRRGGBB) Primary text color
surfaceColor Long (0xFFRRGGBB) Card/surface background color
waveformColor Long (0xFFRRGGBB) Waveform visualization color

Predefined Themes

Theme Presets
// Default Dark Theme
val darkTheme = VikaThemeConfig.DEFAULT_DARK

// Default Light Theme
val lightTheme = VikaThemeConfig.DEFAULT_LIGHT

// JKN Mobile Theme (Custom)
val jknTheme = VikaThemeConfig(
    primaryColor = 0xFF0FAF65,        // BPJS Green
    secondaryColor = 0xFF059669,
    backgroundColor = 0xFFFFFFFF,
    textColor = 0xFF111827,
    surfaceColor = 0xFFF3F4F6,
    waveformColor = 0xFF0FAF65
)

// Apply theme
val options = VikaUIOptions.builder()
    .theme(jknTheme)
    .build()

VikaSDK.getInstance().openVikaSDK(context, options)

Socket.IO Events

SDK menggunakan Socket.IO untuk menerima hasil processing voice secara real-time. Anda bisa listen ke events untuk custom handling.

Listen to Conversation Events

Conversation Listener
val sdk = VikaSDK.getInstance()

// Set conversation listener
sdk.setConversationListener(object : VikaSDK.ConversationListener {
    override fun onConversationProcessed(event: ConversationProcessedEvent) {
        // Called when voice is processed and navigation result is ready
        Log.d("Vika", "Transcription: ${event.transcription}")
        Log.d("Vika", "Target Screen: ${event.navigationData.deepLink}")
        Log.d("Vika", "Confidence: ${event.navigationData.confidence}")

        // SDK will automatically navigate via deep link
        // But you can add custom logic here
        if (event.navigationData.confidence < 0.8f) {
            // Show confirmation dialog for low confidence
            showNavigationConfirmation(event.navigationData)
        }
    }

    override fun onError(error: VikaError) {
        // Handle errors
        when (error) {
            is VikaError.Network -> {
                Toast.makeText(context, "Network error", Toast.LENGTH_SHORT).show()
            }
            is VikaError.SocketConnection -> {
                Toast.makeText(context, "Connection lost", Toast.LENGTH_SHORT).show()
            }
            else -> {
                Log.e("Vika", "Error: ${error.message}")
            }
        }
    }
})

Socket Connection Management

Socket Management
val sdk = VikaSDK.getInstance()

// Check connection status
if (sdk.isSocketConnected()) {
    Log.d("Vika", "Socket is connected")
}

// Manually disconnect (if needed)
sdk.disconnectSocket()

// Manually reconnect
sdk.reconnectSocket()
Auto Reconnection: SDK automatically attempts to reconnect dengan exponential backoff jika koneksi terputus. Anda bisa configure max attempts di SDKConfig.

Security

Vika SDK implements multiple security layers untuk protect data dan prevent unauthorized access.

Security Features

AES-256 Encryption

Semua data sensitive di-encrypt dengan AES-256-CBC sebelum dikirim ke server.

Certificate Pinning

Optional certificate pinning untuk prevent man-in-the-middle attacks.

Request Signing

Semua requests di-sign dengan HMAC-SHA256 untuk verify authenticity.

Deep Link Validation

Whitelist allowed schemes untuk prevent malicious deep links.

Security Best Practices

Automatic PII Data Masking: SDK otomatis melakukan masking terhadap PII (Personally Identifiable Information) pada hasil speech-to-text dan deeplink sebelum dikirim ke LLM. Data sensitif peserta BPJS seperti NIK, nomor kartu, nama lengkap, dan informasi pribadi lainnya akan di-anonymize, menjamin privasi data tetap terjaga.
Never Hardcode API Keys: Store API keys in BuildConfig atau encrypted storage, jangan di hardcode di code.
Disable Debug Mode: Set debugMode = false di production builds untuk prevent data leaks.
Validate Deep Link Schemes: Always set allowedDeepLinkSchemes untuk whitelist schemes yang valid.
Use ProGuard: SDK includes ProGuard rules. Enable minifyEnabled di release builds.
Security Config Example
// Secure configuration for production
val secureConfig = SDKConfig.Builder(BuildConfig.VIKA_API_KEY)
    .debugMode(false)  // Disable debug logs
    .allowedDeepLinkSchemes("jkn")  // Only allow "jkn://" scheme
    .certificatePinning(  // Optional: Pin server certificate
        "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
    )
    .build()

// Store API key in BuildConfig (build.gradle.kts)
// buildConfigField("String", "VIKA_API_KEY", "\"${project.findProperty("vika.api.key")}\")"

PII Data Masking

Vika SDK secara otomatis melindungi data sensitif peserta BPJS dengan melakukan masking terhadap PII (Personally Identifiable Information) sebelum data dikirim ke LLM untuk processing.

Keamanan Data BPJS Terjamin: Semua data sensitif peserta seperti NIK, nomor kartu BPJS, nama lengkap, dan informasi pribadi lainnya akan di-anonymize secara otomatis sebelum diproses oleh AI.

Bagaimana Cara Kerjanya?

1
Speech-to-Text Processing:

Hasil konversi voice input menjadi text akan dideteksi dan di-mask PII-nya terlebih dahulu.

2
Deeplink Masking:

Deeplink yang akan dikirim ke LLM juga sudah di-mask untuk menghilangkan parameter sensitif.

3
LLM Processing:

Data yang sudah di-anonymize dikirim ke LLM untuk menentukan intent dan deeplink yang sesuai.

4
Original Data Preserved:

Data asli tetap tersimpan di device dan tidak pernah terekspos ke external services.

Jenis Data yang Di-Mask

Identitas Pribadi

  • NIK (Nomor Induk Kependudukan)
  • Nomor Kartu BPJS
  • Nama Lengkap
  • Tanggal Lahir

Informasi Kontak

  • Nomor Telepon
  • Email Address
  • Alamat Lengkap

Data Kesehatan

  • Nomor Rekam Medis
  • Diagnosis
  • Riwayat Penyakit

Informasi Finansial

  • Nomor Rekening
  • Informasi Pembayaran
  • Iuran BPJS

Contoh Masking

Before Masking (Original Voice Input)
// User voice input hasil speech-to-text
"Saya mau cek status klaim untuk nomor kartu BPJS 0001234567890 atas nama Budi Santoso NIK 3201012345678901"
After Masking (Sent to LLM)
// Data yang dikirim ke LLM sudah di-anonymize
"Saya mau cek status klaim untuk nomor kartu BPJS [MASKED_BPJS_NUMBER] atas nama [MASKED_NAME] NIK [MASKED_NIK]"

// LLM hanya menerima intent, bukan data sensitif
// LLM Response: "navigate to status klaim page"

// Deeplink yang di-return:
"jkn://status-klaim"  // Tanpa parameter sensitif
Zero Configuration Required: PII Masking bekerja otomatis tanpa perlu konfigurasi tambahan. SDK akan mendeteksi dan mem-protect data sensitif secara intelligent.

API Reference

Complete reference untuk semua public APIs di Vika SDK.

VikaSDK Class

Static Methods (Companion)

fun initialize(context: Context, config: SDKConfig, callback: InitCallback?)

Initialize SDK with config. Must be called before using other methods.

fun getInstance(): VikaSDK

Get singleton SDK instance. Throws exception if not initialized.

fun isInitialized(): Boolean

Check if SDK has been initialized.

fun destroy()

Destroy SDK instance and clean up resources.

Instance Methods

fun registerScreen(screen: ScreenRegistration, callback: RegisterCallback?): VikaSDK

Register single screen for voice navigation.

fun registerScreens(screens: List<ScreenRegistration>, callback: RegisterCallback?): VikaSDK

Register multiple screens at once.

fun openVikaSDK(context: Context)

Open Voice UI with default options (fullscreen).

fun openVikaSDK(context: Context, options: VikaUIOptions)

Open Voice UI with custom display mode and theme.

fun setConversationListener(listener: ConversationListener?)

Set listener to receive real-time conversation results via Socket.IO.

fun isBackendReady(): Boolean

Check if backend initialization was successful.

fun isSocketConnected(): Boolean

Check if Socket.IO is currently connected.

Full API Documentation: Lihat KDoc comments di source code untuk detailed documentation setiap method dan parameter.

Troubleshooting

Solusi untuk common issues yang mungkin Anda temui.

SDK Initialization Failed

Error: "Backend initialization failed" atau timeout

Solutions:

  • Check internet connection
  • Verify API key is valid (get from dashboard)
  • Check if backend server is running
  • Increase timeout: .timeout(30000L)
  • Check Logcat for detailed error

Deep Link Not Working

Navigation tidak trigger setelah voice command

Solutions:

  • Verify intent-filter in AndroidManifest.xml
  • Check launchMode is "singleTop" for MainActivity
  • Implement onNewIntent() to handle deep links when app is running
  • Test deep link with ADB: adb shell am start -d "jkn://screen"
  • Verify scheme is in allowedDeepLinkSchemes config

Voice Not Recognized Accurately

AI salah mencocokkan screen atau confidence terlalu rendah

Solutions:

  • Add more detailed descriptions to ScreenRegistration
  • Add more keywords (synonyms, variations)
  • Lower minConfidenceThreshold if too strict (default: 0.7)
  • Test with clear audio in quiet environment
  • Check language setting matches voice input

Socket Connection Lost

Real-time updates tidak diterima

Solutions:

  • SDK auto-reconnects, wait for reconnection
  • Check isSocketConnected() to verify connection status
  • Increase reconnection attempts: .socketReconnectionAttempts(10)
  • Check network stability
  • Call reconnectSocket() to manually trigger reconnect

Dependency Resolution Failed

Gradle sync error: "Could not resolve com.vika.sdk:vika-sdk"

Solutions:

  • Check maven repository URL is correct
  • Verify internet connection
  • Try ./gradlew build --refresh-dependencies
  • Clear Gradle cache: ./gradlew clean

Need More Help?

Jika masih ada masalah, hubungi support team kami: