CODE EDITED:
I am developing a dictionary app for Android. I have been succeeding in making the app pronounce each word being looked up. Here is the code:
btnPronounce.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Log.i(MAIN_TAG,"Start pronounciation ...");
btnPronounce.setEnabled(false);
String currentWord = edWord.getText().toString().toLowerCase();
try {
ZipFile zip = new ZipFile("/sdcard/app_folder/sound/zip_test.zip");
ZipEntry entry = zip.getEntry(currentWord);
if (entry != null) {
InputStream in = zip.getInputStream(entry);
// see Note #3.
File tempFile = File.createTempFile("_AUDIO_", ".wav");
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
// do something with tempFile (like play it)
File f = tempFile;
try {
if (f.exists())
{
Log.i(MAIN_TAG,"Audio file found!");
MediaPlayer mp = new MediaPlayer();
mp.prepare();
mp.setLooping(false);
mp.start();
while (mp.getCurrentPosition() < mp.getDuration());
mp.stop();
mp.release();
Log.i(MAIN_TAG,"Pronounciation finished!");
}
else
{
Log.i(MAIN_TAG,"File doesn't exist!!");
}
}
catch (IOException e)
{
Log.i(MAIN_TAG,e.toString());
}
btnPronounce.setEnabled(true); }
else {
// no such entry in the zip
}
} catch (IOException e) {
// handle your exception cases...
e.printStackTrace();
}
}
});
But the problem is that there are too many WAV files in one folder, and all these files are treated as music files by Android devices. As a result, it takes ages to index such files. In addition, indexing and user browsing sometimes force the app to crash.
Therefore, I just wonder if the following could be programmatically done:
EDIT: Are there any other ways/solutions that allow audio files to be simply put into one big file (an image, zip or the like...) and then let MediaPlayer read individual files in it?
Thank you very much.
You can use a combination of ZipFile
or ZipInputStream
and java.io
file operations to read the necessary data from the zip, create temp files and play those using MediaPlayer
.
Alternatively, you could just use a TTS engine and not pass out a 50-bagillion-byte APK.
Edit - Example by request:
try {
ZipFile zip = new ZipFile("someZipFile.zip");
ZipEntry entry = zip.getEntry(fileName);
if (entry != null) {
InputStream in = zip.getInputStream(entry);
// see Note #3.
File tempFile = File.createTempFile("_AUDIO_", ".wav");
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
// do something with tempFile (like play it)
} else {
// no such entry in the zip
}
} catch (IOException e) {
// handle your exception cases...
e.printStackTrace();
}
Notes:
I didn't include any safe file handling practices here. That's up to you.
This isn't the way to do it, only a way to do it. There are probably 100 other ways, some of which may be better suited to what you need. I didn't use ZipInputStream
simply because there's a little more logic involved and I was going for brevity. You have to check every entry to see if it's what you're looking for with ZipInputStream
, whereas ZipFile
allows you to just ask for what you want by name. I'm not sure what (if any) performance implications using either over the other would have.
By no means are you required to use temp files (or files at all, really), but Android's MediaPlayer doesn't really like streams, so this is probably the easiest solution.
An alternative you should consider is to download the individual sound files when the user want to listen to a pronunciation. This should reduce the file size although it does mean that you can't listen to a pronunciation when there is no Internet.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.