DaVoice Integration Guides
Step-by-step guides to integrate wake word detection into your applications across all major platforms
New to voice activation? Read what a wake word is and how wake word detection works before choosing an integration path.
Android (Kotlin) Integration Guide
📦 Repository
GitHub: https://github.com/frymanofer/Android_Native_Wake_Word
Native Android SDK with NNAPI hardware acceleration support.
Step 1: Add Dependency
Add to app/build.gradle:
dependencies {
implementation 'com.davoice:wake-word-sdk:1.0.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}Step 2: Manifest Configuration
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service
android:name=".WakeWordService"
android:foreground ServiceType="microphone"
android:exported="false" />
</application>Step 3: Kotlin Implementation
import android.Manifest
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.davoice.wakeword.DaVoiceDetector
import com.davoice.wakeword.DetectorConfig
import com.davoice.wakeword.DetectionCallback
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private var detector: DaVoiceDetector? = null
private var isListening = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkPermissions()
}
private fun checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
PERMISSION_REQUEST_CODE
)
} else {
initializeDetector()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE
&& grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initializeDetector()
}
}
private fun initializeDetector() {
val config = DetectorConfig.Builder()
.setModelPath("models/hey_google.onnx")
.setThreshold(0.97f)
.setBufferCount(3)
.enableNoiseReduction(true)
.build()
detector = DaVoiceDetector(this, config)
detector?.setCallback(object : DetectionCallback {
override fun onWakeWordDetected(confidence: Float, timestamp: Long) {
runOnUiThread {
Toast.makeText(
this@MainActivity,
"Wake word detected! Confidence: $confidence",
Toast.LENGTH_SHORT
).show()
handleWakeWordDetection()
}
}
override fun onError(error: String) {
Log.e("WakeWord", "Detection error: $error")
}
})
}
fun toggleListening(view: View) {
if (isListening) {
stopListening()
} else {
startListening()
}
}
private fun startListening() {
CoroutineScope(Dispatchers.Main).launch {
try {
detector?.start()
isListening = true
Log.d("WakeWord", "Started listening")
} catch (e: Exception) {
Log.e("WakeWord", "Failed to start: ${e.message}")
}
}
}
private fun stopListening() {
detector?.stop()
isListening = false
Log.d("WakeWord", "Stopped listening")
}
private fun handleWakeWordDetection() {
// Navigate to voice command screen
// or trigger speech recognition
}
override fun onDestroy() {
super.onDestroy()
detector?.release()
}
companion object {
private const val PERMISSION_REQUEST_CODE = 100
}
}Step 4: Foreground Service (Always-On)
class WakeWordService : Service() {
private var detector: DaVoiceDetector? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForeground(NOTIFICATION_ID, createNotification())
initializeAndStart()
return START_STICKY
}
private fun createNotification(): Notification {
val channelId = "wake_word_channel"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Wake Word Detection",
NotificationManager.IMPORTANCE_LOW
)
getSystemService(NotificationManager::class.java)
.createNotificationChannel(channel)
}
return NotificationCompat.Builder(this, channelId)
.setContentTitle("Wake Word Active")
.setContentText("Listening for voice commands")
.setSmallIcon(R.drawable.ic_mic)
.build()
}
companion object {
private const val NOTIFICATION_ID = 1001
}
}✅ Performance Tips
- • Enable NNAPI for hardware acceleration
- • Use foreground service for reliable detection
- • Implement proper lifecycle management
- • Test on devices with different chipsets
Need Help Getting Started?
Our team provides free integration support and custom wake word training for all platforms.
Free Development Support • Code Examples • Community Discord • 1-2 Week Custom Model Turnaround