How can I allow the TTS to write files to my app's directories?
I want to write output from the TextToSpeech engine to my ap开发者_开发问答p's cache directory. In order to for the TTS to write there I first have to give it permissions to do so. But I don't know how. I understand that normally such problems can be solved by handing a FileDescriptor
over thus giving permissions to access a specific file. But I can't do that with TTS, as the TextToSpeech.synthesizeToFile method only accepts the file path as a String, no FileDescriptor
. So what to do?
To make my point that TTS really hasn't permissions to write to my app's directories, here's the code...:
TextToSpeech mTts = new new TextToSpeech(context, this);
mTts.synthesizeToFile(text, null, getCacheDir() + "/" + "speech.wav");
And the debugger log:
08-20 14:46:11.257: ERROR/TtsService(336): Can't create
/data/data/com.myorg.myapp/cache/speech.wav due to exception java.io.IOException: Permission denied
TextToSpeech.synthesizeToFile() doesn't work in real devices. It only works in AVDs.
I have been experimenting with this, too, using both the original Pico TTS engine and a third party TTS engine, trying to write to either the sdcard or the internal memory (on a rooted device):
context.getDir("soundfiles", Context.MODE_WORLD_WRITEABLE);
But, as you noted, the method returns TextToSpeech.SUCCESS
without actually creating the file.
If you must record your TTS output to a WAV file, connect the headset output to the aux input in a sound card in your PC and use any recording software to capture that.
TextToSpeech.synthesizeToFile() does actually work on real devices, though it's a bit screwy. I was having the same issue but eventually got it working. The code I use is:
speakTextTxt = speakText.getText().toString();
HashMap<String, String> myHashRender = new HashMap<String, String>();
myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_SAVE_ID);
String exStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
File appTmpPath = new File(exStoragePath + "/sounds/");
appTmpPath.mkdirs();
String tempFilename = "tmpaudio.wav";
tempDestFile = appTmpPath.getAbsolutePath() + "/" + tempFilename;
mTts.synthesizeToFile(speakTextTxt, myHashRender, tempDestFile);
However, today I found something else quite strange. I switched to a different computer to do development on and then started getting the same error again "java.io.IOException: Permission denied". I then went into the Android SDK Manager and made sure all "SDK Platform" and "Google APIs by Goole Inc." packages were installed for all Android versions. I'm not sure exactly which package version fixed it but it's working again. So apparently you can have perfectly fine code but something might be off with your development environment that can cause issues. I hope this can help someone.
精彩评论