How to Build a Custom Cordova Plugin for Native Text-to-Speech on Android and iOS
Creating a Custom Cordova Plugin: Native Text-to-Speech for Android & iOS
Need native-level control in your Cordova app? In this article, we'll build a fully custom Cordova plugin from scratch that connects JavaScript to the native Text-to-Speech (TTS) capabilities of Android and iOS.
🧱 Step 1: Plugin Folder Structure
In your workspace, create a plugin folder:
cordova-plugin-tts/
├── plugin.xml
├── www/
│ └── TTS.js
├── src/
│ ├── android/
│ │ └── TTSPlugin.java
│ └── ios/
│ └── TTSPlugin.swift
📄 Step 2: plugin.xml (metadata & platform bindings)
<plugin id="cordova-plugin-tts" version="1.0.0"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<name>TTSPlugin</name>
<js-module src="www/TTS.js" name="TTS">
<clobbers target="TTS" />
</js-module>
<platform name="android">
<source-file src="src/android/TTSPlugin.java" target-dir="src/com/example/tts"/>
</platform>
<platform name="ios">
<source-file src="src/ios/TTSPlugin.swift" />
</platform>
</plugin>
💬 Step 3: JavaScript Bridge (www/TTS.js)
var exec = require('cordova/exec');
exports.speak = function(text, success, error) {
exec(success, error, "TTSPlugin", "speak", [text]);
};
🤖 Step 4: Android Implementation (src/android/TTSPlugin.java)
package com.example.tts;
import android.speech.tts.TextToSpeech;
import android.content.Context;
import org.apache.cordova.*;
import org.json.JSONArray;
import java.util.Locale;
public class TTSPlugin extends CordovaPlugin {
private TextToSpeech tts;
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
if ("speak".equals(action)) {
final String text = args.optString(0);
cordova.getActivity().runOnUiThread(() -> {
tts = new TextToSpeech(cordova.getContext(), status -> {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.US);
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
callbackContext.success("Speaking");
} else {
callbackContext.error("TTS init failed");
}
});
});
return true;
}
return false;
}
}
🍎 Step 5: iOS Implementation (src/ios/TTSPlugin.swift)
import Foundation
import AVFoundation
import Cordova
@objc(TTSPlugin) class TTSPlugin: CDVPlugin {
var synthesizer = AVSpeechSynthesizer()
@objc(speak:)
func speak(command: CDVInvokedUrlCommand) {
guard let text = command.arguments[0] as? String else {
return
}
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
synthesizer.speak(utterance)
let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "Speaking")
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
}
}
📦 Step 6: Add Plugin to Your Cordova Project
In your Cordova project:
cordova plugin add ../cordova-plugin-tts
📱 Step 7: Use It in Your App
<button onclick="TTS.speak('Hello from native TTS!')">Speak</button>
✅ Final Notes
- You now have a working, cross-platform native plugin.
- For production, manage lifecycle (release TTS engine, handle errors, language options).
- Plugins like this are ideal when you need performance or access to platform-specific features not exposed by default Cordova APIs.
🧠 Related Resources
With this approach, you’ve bridged JavaScript to native power — one of Cordova’s most underrated strengths.
Comments
Post a Comment