简体   繁体   English

如何在CodenameOne中使用Android TextToSpeech?

[英]How to use Android TextToSpeech in CodenameOne?

I'd like to include text-to-speech functionality in my Codename One android app, but I can't seem to get it to work. 我想在我的Codename One安卓应用程序中包含文本语音转换功能,但似乎无法正常使用。 As Codename One does not provide this capability in its API, I'm trying to create a Native interface to handle it using the google maps cn1lib as an example. 由于Codename One在其API中未提供此功能,因此我尝试创建一个本机接口来使用google maps cn1lib作为示例来处理它。

Here's what I've got so far: 到目前为止,这是我得到的:

NativeTTS.java NativeTTS.java

public class NativeTTS extends NativeInterface {
    public int speakString (String hello);
}

NativeTTSImpl.java NativeTTSImpl.java

public class NativeTTSImpl implements OnInitListener, LifecycleListener,
                                      IntentResultListener {

    private TextToSpeech tts;

    public void initialize () {
        AndroidNativeUtil.addLifecycleListener (this);
    }

    public void deinitialize () {
        AndroidNativeUtil.removeLifecycleListener (this);
    }

    public int speakString(String text) {
        return tts.speak (text, TextToSpeech.QUEUE_FLUSH, null);
    }


    public void onInit (int status) {
        if ( status == TextToSpeech.SUCCESS ) {
            tts.setLanguage (Locale.US);
        }
    }


    public boolean isSupported() {
        return true;
    }

    public void onActivityResult (int requestCode, int resultCode, Intent data) {
        if ( resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS )
            tts = new TextToSpeech (AndroidNativeUtil.getActivity (), this);
        else {
            Intent installIntent = new Intent ();
            installIntent.setAction (TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
            AndroidNativeUtil.getActivity ().startActivity (installIntent);
        }
    }

    public void onCreate (Bundle savedInstanceState) {
        Intent intent = new Intent ();
        intent.setAction (TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        AndroidNativeUtil.startActivityForResult (intent, this);
    }


    public void onDestroy () {
        if ( tts != null ) {
            tts.stop ();
            tts.shutdown ();
        }
    }


    public void onResume () {}
    public void onPause  () {}
    public void onLowMemory () {}
    public void onSaveInstanceState (Bundle b) {}

}

I'm attempting to use it back in my app like so: 我试图像这样在我的应用中重新使用它:

NativeTTS tts = (NativeTTS) NativeLookup.create (NativeTTS.class);
if ( tts != null && tts.isSupported () ) {
    int success = tts.speakString ("Hello World");
}

However, I'm getting a NullPointerException when I call tts.speakString (...) . 但是,当我调用tts.speakString (...)时,出现NullPointerException tts.speakString (...) I think the problem is that NativeTTSImpl.initialize() never gets called, and I'm clueless as to how/when I should call it. 我认为问题在于NativeTTSImpl.initialize()从未被调用,对于如何/何时调用它我一无所知。

You need to actually invoke initialize. 您需要实际调用初始化。

The lifecycle listener will only work for lifecycle events that occur after you register it not before, if you want more lifecycle events you can register an activity via the manifest but I'm not sure you need all of that complexity. 生命周期侦听器仅适用于您之前注册的生命周期事件,如果您想要更多生命周期事件,可以通过清单来注册活动,但我不确定您是否需要所有这些复杂性。

I don't see why speak doesn't do something like: 我不明白为什么说话不做类似的事情:

if(tts == null) {
    tts = new TextToSpeech (AndroidNativeUtil.getActivity (), this);
}

The real problem was waiting for the TextToSpeech engine to initialize before calling tts.speak(..) . 真正的问题是在调用tts.speak(..)之前,等待TextToSpeech引擎初始化。 I solved this by adding a boolean to indicate when TTS initialization has finished and to submit String s to a queue before initialization is complete. 我通过添加一个boolean (表示TTS初始化何时完成)并在初始化完成之前将String提交到队列来解决此问题。 Here's the new native implementation code: 这是新的本机实现代码:

public class NativeTTSImpl implements OnInitListener {

    private static TextToSpeech tts;
    private static boolean ttsInitialized = false;
    private static final ConcurrentLinkedQueue<String> queue = 
        new ConcurrentLinkedQueue<String>();

    public void speakString (String text) {
        if ( tts == null ) {
            tts = new TextToSpeech (AndroidNativeUtil.getActivity (), this);
        }

        if ( ttsInitialized ) {
            tts.speak (text, TextToSpeech.QUEUE_FLUSH, null);
        } else {
            queue.add (text);
        }
    }


    public void onInit (int status) {
        if ( status == TextToSpeech.SUCCESS ) {
            tts.setLanguage (Locale.US);
            ttsInitialized = true;
            while ( !queue.isEmpty () ) {
                tts.speak (queue.poll (), TextToSpeech.QUEUE_FLUSH, null);
            }
        }
    }


    public boolean isSupported () {
        return true;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM