Loading android/src/com/reecedunn/espeak/TtsService.java +127 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioTrack; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; Loading @@ -42,6 +43,11 @@ import android.util.Pair; import com.reecedunn.espeak.SpeechSynthesis.SynthReadyCallback; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; Loading @@ -49,6 +55,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** * Implements the eSpeak engine as a {@link TextToSpeechService}. Loading @@ -71,6 +79,9 @@ public class TtsService extends TextToSpeechService { private BroadcastReceiver mOnLanguagesDownloaded = null; private AsyncExtract mAsyncExtract; public static final String BROADCAST_LANGUAGES_UPDATED = "com.reecedunn.espeak.LANGUAGES_UPDATED"; @Override public void onCreate() { initializeTtsEngine(); Loading @@ -83,6 +94,7 @@ public class TtsService extends TextToSpeechService { if (mOnLanguagesDownloaded != null) { unregisterReceiver(mOnLanguagesDownloaded); } mAsyncExtract.cancel(true); } /** Loading Loading @@ -131,9 +143,24 @@ public class TtsService extends TextToSpeechService { registerReceiver(mOnLanguagesDownloaded, filter); } final Intent intent = new Intent(this, DownloadVoiceData.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); final File dataPath = CheckVoiceData.getDataPath(this).getParentFile(); mAsyncExtract = new AsyncExtract(this, R.raw.espeakdata, dataPath) { @Override protected void onPostExecute(Integer result) { switch (result) { case RESULT_OK: final Intent intent = new Intent(DownloadVoiceData.BROADCAST_LANGUAGES_UPDATED); sendBroadcast(intent); break; case RESULT_CANCELED: // Do nothing? break; } } }; mAsyncExtract.execute(); return new Pair<>(null, TextToSpeech.LANG_MISSING_DATA); } Loading Loading @@ -341,4 +368,101 @@ public class TtsService extends TextToSpeechService { mCallback.done(); } }; /** * Begin voice data download here instead of an activity. */ private static final int PROGRESS_STARTING = 0; private static final int PROGRESS_EXTRACTING = 1; private static final int RESULT_OK = -1; private static final int RESULT_CANCELED = -2; private static class ExtractProgress { int total; int progress = 0; int state = PROGRESS_STARTING; File file; public ExtractProgress(int total) { this.total = total; } } private static class AsyncExtract extends AsyncTask<Void, ExtractProgress, Integer> { private final Context mContext; private final int mRawResId; private final File mOutput; public AsyncExtract(Context context, int rawResId, File output) { mContext = context; mRawResId = rawResId; mOutput = output; } @Override protected Integer doInBackground(Void... params) { FileUtils.rmdir(CheckVoiceData.getDataPath(mContext)); final InputStream stream = mContext.getResources().openRawResource(mRawResId); final ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(stream)); try { ExtractProgress progress = new ExtractProgress(stream.available()); progress.state = PROGRESS_EXTRACTING; final byte[] buffer = new byte[10240]; int bytesRead; ZipEntry entry; while (!isCancelled() && ((entry = zipStream.getNextEntry()) != null)) { progress.file = new File(mOutput, entry.getName()); publishProgress(progress); if (entry.isDirectory()) { progress.file.mkdirs(); FileUtils.chmod(progress.file); continue; } // Ensure the target path exists. progress.file.getParentFile().mkdirs(); final FileOutputStream outputStream = new FileOutputStream(progress.file); try { while (!isCancelled() && ((bytesRead = zipStream.read(buffer)) != -1)) { outputStream.write(buffer, 0, bytesRead); progress.total += bytesRead; } } finally { outputStream.close(); } zipStream.closeEntry(); // Make sure the output file is readable. FileUtils.chmod(progress.file); } final String version = FileUtils.read(mContext.getResources().openRawResource(R.raw.espeakdata_version)); final File outputFile = new File(mOutput, "espeak-ng-data/version"); FileUtils.write(outputFile, version); return RESULT_OK; } catch (Exception e) { e.printStackTrace(); } finally { try { zipStream.close(); } catch (IOException e) { e.printStackTrace(); } } return RESULT_CANCELED; } } } Loading
android/src/com/reecedunn/espeak/TtsService.java +127 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioTrack; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; Loading @@ -42,6 +43,11 @@ import android.util.Pair; import com.reecedunn.espeak.SpeechSynthesis.SynthReadyCallback; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; Loading @@ -49,6 +55,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** * Implements the eSpeak engine as a {@link TextToSpeechService}. Loading @@ -71,6 +79,9 @@ public class TtsService extends TextToSpeechService { private BroadcastReceiver mOnLanguagesDownloaded = null; private AsyncExtract mAsyncExtract; public static final String BROADCAST_LANGUAGES_UPDATED = "com.reecedunn.espeak.LANGUAGES_UPDATED"; @Override public void onCreate() { initializeTtsEngine(); Loading @@ -83,6 +94,7 @@ public class TtsService extends TextToSpeechService { if (mOnLanguagesDownloaded != null) { unregisterReceiver(mOnLanguagesDownloaded); } mAsyncExtract.cancel(true); } /** Loading Loading @@ -131,9 +143,24 @@ public class TtsService extends TextToSpeechService { registerReceiver(mOnLanguagesDownloaded, filter); } final Intent intent = new Intent(this, DownloadVoiceData.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); final File dataPath = CheckVoiceData.getDataPath(this).getParentFile(); mAsyncExtract = new AsyncExtract(this, R.raw.espeakdata, dataPath) { @Override protected void onPostExecute(Integer result) { switch (result) { case RESULT_OK: final Intent intent = new Intent(DownloadVoiceData.BROADCAST_LANGUAGES_UPDATED); sendBroadcast(intent); break; case RESULT_CANCELED: // Do nothing? break; } } }; mAsyncExtract.execute(); return new Pair<>(null, TextToSpeech.LANG_MISSING_DATA); } Loading Loading @@ -341,4 +368,101 @@ public class TtsService extends TextToSpeechService { mCallback.done(); } }; /** * Begin voice data download here instead of an activity. */ private static final int PROGRESS_STARTING = 0; private static final int PROGRESS_EXTRACTING = 1; private static final int RESULT_OK = -1; private static final int RESULT_CANCELED = -2; private static class ExtractProgress { int total; int progress = 0; int state = PROGRESS_STARTING; File file; public ExtractProgress(int total) { this.total = total; } } private static class AsyncExtract extends AsyncTask<Void, ExtractProgress, Integer> { private final Context mContext; private final int mRawResId; private final File mOutput; public AsyncExtract(Context context, int rawResId, File output) { mContext = context; mRawResId = rawResId; mOutput = output; } @Override protected Integer doInBackground(Void... params) { FileUtils.rmdir(CheckVoiceData.getDataPath(mContext)); final InputStream stream = mContext.getResources().openRawResource(mRawResId); final ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(stream)); try { ExtractProgress progress = new ExtractProgress(stream.available()); progress.state = PROGRESS_EXTRACTING; final byte[] buffer = new byte[10240]; int bytesRead; ZipEntry entry; while (!isCancelled() && ((entry = zipStream.getNextEntry()) != null)) { progress.file = new File(mOutput, entry.getName()); publishProgress(progress); if (entry.isDirectory()) { progress.file.mkdirs(); FileUtils.chmod(progress.file); continue; } // Ensure the target path exists. progress.file.getParentFile().mkdirs(); final FileOutputStream outputStream = new FileOutputStream(progress.file); try { while (!isCancelled() && ((bytesRead = zipStream.read(buffer)) != -1)) { outputStream.write(buffer, 0, bytesRead); progress.total += bytesRead; } } finally { outputStream.close(); } zipStream.closeEntry(); // Make sure the output file is readable. FileUtils.chmod(progress.file); } final String version = FileUtils.read(mContext.getResources().openRawResource(R.raw.espeakdata_version)); final File outputFile = new File(mOutput, "espeak-ng-data/version"); FileUtils.write(outputFile, version); return RESULT_OK; } catch (Exception e) { e.printStackTrace(); } finally { try { zipStream.close(); } catch (IOException e) { e.printStackTrace(); } } return RESULT_CANCELED; } } }