我需要调用synthesizeToFile来创建一些音频文件,并且我需要知道何时完成所有这些文件的创建,以便通知用户。

我已经阅读了其他问题,但是找不到适合我的问题,或者该问题与speak功能有关。

build.gradle(模块:应用):

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.domain.appName"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


MainActivity.java:

public class MainActivity extends AppCompatActivity {
TextToSpeech tts;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
protected void onResume() {
    super.onResume();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        Map<String, String> mapFilesToGenerate = new HashMap<>();

        List<MyEnum> listMyEnum = new ArrayList<>(Arrays.asList(MyEnum.values()));
        for (MyEnum e : listMyEnum)
        {
            File file = new File(getApplicationContext().getFilesDir() + "/" + e.id);
            if (!file.exists())
            {
                mapFilesToGenerate.put(e.id, e.name);
            }
        }

        // this Toast will be shown
        Toast.makeText(getApplicationContext(), "Preparing audio files...", Toast.LENGTH_SHORT).show();
        Log.d("testTTS", "Preparing audio files...");

        tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener()
        {
            @Override
            public void onInit(int status)
            {
                if (status == TextToSpeech.SUCCESS)
                {
                    tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
                    {
                        // **********
                        // all Toasts and Logs in this block aren't showed
                        // **********

                        @Override
                        public void onStart(String utteranceId) {
                            Toast.makeText(getApplicationContext(), "generating audio files... (" + mapFilesToGenerate.size() + " files)", Toast.LENGTH_LONG).show();
                            Log.d("testTTS", "generating audio files... (" + mapFilesToGenerate.size() + " files)");
                        }

                        @Override
                        public void onDone(String utteranceId) {
                            Toast.makeText(getApplicationContext(), "Generation complete.", Toast.LENGTH_LONG).show();
                            Log.d("testTTS", "Generation complete.");
                            new Thread()
                            {
                                public void run()
                                {
                                    MainActivity.this.runOnUiThread(new Runnable()
                                    {
                                        public void run()
                                        {

                                            Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();
                                            Log.d("testTTS", "TTS Completed");
                                        }
                                    });
                                }
                            }.start();
                        }

                        @Override
                        public void onError(String utteranceId) {
                            Log.d("testTTS", "error.");
                        }
                    });

                    generateAudioFiles("en", mapFilesToGenerate);

                } else {
                    Toast.makeText(getApplicationContext(), "TTS inizialization failed! status = " + status, Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}

private void generateAudioFiles(Map<String, String> mapFilesToGenerate)
{
    for (Map.Entry<String, String> entry : mapFilesToGenerate.entrySet())
    {
        saveAudioFileWithTTS("en", entry.getValue(), entry.getKey());
    }
}

private boolean saveAudioFileWithTTS(String text, String pathFileName)
{
    int returnCode = -2;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        Locale locale = new Locale("en");

        tts.setLanguage(locale);

        tts.setPitch(1.2f);
        tts.setSpeechRate(0.8f);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            tts.setVoice(new Voice("nomeVoce", locale, Voice.QUALITY_VERY_HIGH, Voice.LATENCY_NORMAL, false, null));
        }

        String completePath = getApplicationContext().getFilesDir().getAbsolutePath() + "/" + pathFileName;

        File fileToCreate = new File(completePath);
        returnCode = tts.synthesizeToFile
            (
                text
                , null
                , fileToCreate
                , pathFileName
            );
    }

    return returnCode == 0;
}


为什么没有显示setOnUtteranceProgressListener中的所有Toast和Logs?

我究竟做错了什么?我有什么不考虑的吗?

谢谢

最佳答案

我会说以下任何一种可能性:

A)致电

generateAudioFiles("en", mapFilesToGenerate);


设置UtteranceProgressListener之后过早。

B)仅在不必要时使用'new Thread()'

runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();
    }
});
Log.d("testTTS", "TTS Completed");


有必要的。

C)在所有UtteranceProgressListener回调中不使用上述技术(B)(由于所有这些回调均在后台线程上调用,因此除非您包装了此类代码,否则不会显示敬酒)。

D)您使用的TTS引擎无法准确报告synthesizeToFile()的完成情况

...您还可以检查synthesizeToFile()的返回值-如果返回false,则根本不进行综合,这将解释为没有回调被调用。

07-26 09:28