You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发适配cordova-plugin-tts的Cordova来电监听通知插件需求问询

Fixing Cordova Incoming Call Listener to Pause/Resume TTS

Hey there! I get that you've been grinding on this plugin for a month—totally feel the pain of trial-and-error when you're new to these tools. Let's get your incoming call listener working with cordova-plugin-tts so it stops playing audio during calls and gives a proper notification.

Core Issue Breakdown

Right now, when an incoming call comes in, Android doesn't automatically pause third-party audio like your TTS. We need to:

  • Listen for incoming call state changes (ringing, active, ended)
  • Trigger cordova-plugin-tts to pause when a call starts, then resume when it ends
  • Make sure your plugin has the right permissions and broadcast setup to detect calls

Step 1: Complete the Java Plugin Code

Here's a full, corrected version of your Java code (filling in the gaps from your snippet). This will register a broadcast receiver to detect call states and communicate with your Cordova app:

package com.caller.notifier;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.TelephonyManager;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;

public class CallNotifier extends CordovaPlugin {
    private BroadcastReceiver callReceiver;
    private CallbackContext callbackContext;

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;

        if (action.equals("startListening")) {
            startCallListener();
            callbackContext.success("Call listener started");
            return true;
        } else if (action.equals("stopListening")) {
            stopCallListener();
            callbackContext.success("Call listener stopped");
            return true;
        }
        return false;
    }

    private void startCallListener() {
        callReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

                // Send call state to JS layer to control TTS
                if (state != null) {
                    switch (state) {
                        case TelephonyManager.EXTRA_STATE_RINGING:
                            // Notify JS to pause TTS and show call notification
                            cordova.getActivity().runOnUiThread(() -> {
                                callbackContext.success("{\"state\":\"ringing\"}");
                            });
                            break;
                        case TelephonyManager.EXTRA_STATE_OFFHOOK:
                            // Call is active, keep TTS paused
                            cordova.getActivity().runOnUiThread(() -> {
                                callbackContext.success("{\"state\":\"active\"}");
                            });
                            break;
                        case TelephonyManager.EXTRA_STATE_IDLE:
                            // Call ended, resume TTS
                            cordova.getActivity().runOnUiThread(() -> {
                                callbackContext.success("{\"state\":\"idle\"}");
                            });
                            break;
                    }
                }
            }
        };

        // Register the broadcast receiver
        IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
        cordova.getActivity().registerReceiver(callReceiver, filter);
    }

    private void stopCallListener() {
        if (callReceiver != null) {
            try {
                cordova.getActivity().unregisterReceiver(callReceiver);
            } catch (IllegalArgumentException e) {
                // Ignore if receiver wasn't registered
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopCallListener(); // Clean up receiver when app closes
    }
}

Step 2: Fix plugin.xml Configuration

Make sure your plugin.xml has the right permissions, intent filters, and plugin setup. Here's the corrected section:

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        id="com.caller.notifier"
        version="1.0.0">
    <name>CallNotifier</name>
    <description>Cordova plugin to listen for incoming calls and control TTS</description>
    <author>Your Name</author>
    <license>MIT</license>
    <engines>
        <engine name="cordova" version=">=9.0.0"/>
    </engines>

    <platform name="android">
        <config-file target="AndroidManifest.xml" parent="/manifest">
            <!-- Required permission to read phone state -->
            <uses-permission android:name="android.permission.READ_PHONE_STATE" />
            <!-- For Android 12+, need POST_NOTIFICATIONS to show call alerts -->
            <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
        </config-file>

        <source-file src="src/android/com/caller/notifier/CallNotifier.java" target-dir="src/com/caller/notifier" />

        <js-module name="CallNotifier" src="www/CallNotifier.js">
            <clobbers target="window.CallNotifier" />
        </js-module>
    </platform>
</plugin>

Step 3: Add the JS Layer to Control TTS

Create a www/CallNotifier.js file to bridge the Java plugin with cordova-plugin-tts:

var exec = require('cordova/exec');

var CallNotifier = {
    startListening: function(successCallback, errorCallback) {
        exec(function(result) {
            var callState = JSON.parse(result);
            switch(callState.state) {
                case 'ringing':
                    // Pause TTS and show a notification
                    if(window.TTS) {
                        window.TTS.pause();
                    }
                    alert("Incoming call!"); // Replace with a custom notification if needed
                    break;
                case 'active':
                    // Keep TTS paused
                    if(window.TTS) {
                        window.TTS.pause();
                    }
                    break;
                case 'idle':
                    // Resume TTS after call ends
                    if(window.TTS) {
                        window.TTS.resume();
                    }
                    break;
            }
            successCallback(result);
        }, errorCallback, 'CallNotifier', 'startListening', []);
    },
    stopListening: function(successCallback, errorCallback) {
        exec(successCallback, errorCallback, 'CallNotifier', 'stopListening', []);
    }
};

module.exports = CallNotifier;

Step 4: Use the Plugin in Your App

In your main Cordova app JS, initialize both plugins and start the call listener:

document.addEventListener("deviceready", function() {
    // Initialize TTS first
    window.TTS
        .init({
            lang: 'en-US'
        })
        .then(() => {
            console.log('TTS initialized');
            // Start listening for calls
            window.CallNotifier.startListening(
                function(result) { console.log('Call state:', result); },
                function(error) { console.error('Call listener error:', error); }
            );
        })
        .catch((err) => {
            console.error('TTS init failed:', err);
        });
}, false);

Key Notes for Beginners

  • Permissions: On Android 6+, you'll need to request runtime permissions for READ_PHONE_STATE and POST_NOTIFICATIONS. You can use cordova-plugin-android-permissions to handle this.
  • Testing: Use the Android Studio emulator to simulate incoming calls (go to More > Phone > Enter a number > Call).
  • Cleanup: Always unregister the broadcast receiver when the app closes to avoid memory leaks (the onDestroy method in Java handles this).

内容的提问来源于stack exchange,提问作者user9757264

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:13:20