| @@ -9,6 +9,9 @@ The espeak-ng project is a fork of the espeak project. | |||
| ### 1.52 (In Development) | |||
| android: | |||
| * Added directBoot support -- beqabeqa473 | |||
| updated languages: | |||
| * ba (Bashkir) -- Andiv06 | |||
| * be (Belarusian) -- Andiv06, bespsm, Alaksiej Stankievič | |||
| @@ -9,12 +9,14 @@ | |||
| android:required="false" /> | |||
| <application | |||
| android:name="com.reecedunn.espeak.EspeakApp" | |||
| android:icon="@drawable/icon" | |||
| android:theme="@style/AppTheme" | |||
| android:label="@string/app_name" > | |||
| <service | |||
| android:name=".TtsService" | |||
| android:label="@string/app_name" > | |||
| android:label="@string/app_name" | |||
| android:directBootAware="true"> | |||
| <intent-filter> | |||
| <action android:name="android.intent.action.TTS_SERVICE" /> | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2012-2013 Reece H. Dunn | |||
| * Copyright (C) 2009 The Android Open Source Project | |||
| * | |||
| @@ -83,11 +84,12 @@ public class CheckVoiceData extends Activity { | |||
| protected void onCreate(Bundle savedInstanceState) { | |||
| super.onCreate(savedInstanceState); | |||
| Context storageContext = EspeakApp.getStorageContext(); | |||
| ArrayList<String> availableLanguages = new ArrayList<String>(); | |||
| ArrayList<String> unavailableLanguages = new ArrayList<String>(); | |||
| boolean haveBaseResources = hasBaseResources(this); | |||
| if (!haveBaseResources || canUpgradeResources(this)) { | |||
| boolean haveBaseResources = hasBaseResources(storageContext); | |||
| if (!haveBaseResources || canUpgradeResources(storageContext)) { | |||
| if (!haveBaseResources) { | |||
| unavailableLanguages.add(Locale.ENGLISH.toString()); | |||
| } | |||
| @@ -95,7 +97,7 @@ public class CheckVoiceData extends Activity { | |||
| return; | |||
| } | |||
| final SpeechSynthesis engine = new SpeechSynthesis(this, mSynthReadyCallback); | |||
| final SpeechSynthesis engine = new SpeechSynthesis(storageContext, mSynthReadyCallback); | |||
| final List<Voice> voices = engine.getAvailableVoices(); | |||
| for (Voice voice : voices) { | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2012-2013 Reece H. Dunn | |||
| * Copyright (C) 2009 The Android Open Source Project | |||
| * | |||
| @@ -45,10 +46,11 @@ public class DownloadVoiceData extends Activity { | |||
| setContentView(R.layout.download_voice_data); | |||
| mProgress = (ProgressBar)findViewById(R.id.progress); | |||
| Context storageContext = EspeakApp.getStorageContext(); | |||
| final File dataPath = CheckVoiceData.getDataPath(this).getParentFile(); | |||
| final File dataPath = CheckVoiceData.getDataPath(storageContext).getParentFile(); | |||
| mAsyncExtract = new AsyncExtract(this, R.raw.espeakdata, dataPath, mProgress) { | |||
| mAsyncExtract = new AsyncExtract(storageContext, R.raw.espeakdata, dataPath, mProgress) { | |||
| @Override | |||
| protected void onPostExecute(Integer result) { | |||
| switch (result) { | |||
| @@ -0,0 +1,41 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| package com.reecedunn.espeak; | |||
| import android.app.Application; | |||
| import android.content.Context; | |||
| import android.os.Build; | |||
| public class EspeakApp extends Application { | |||
| private static Context storageContext; | |||
| public void onCreate() { | |||
| super.onCreate(); | |||
| Context appContext = getApplicationContext(); | |||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | |||
| EspeakApp.storageContext = appContext.createDeviceProtectedStorageContext(); | |||
| } | |||
| else { | |||
| EspeakApp.storageContext = appContext; | |||
| } | |||
| } | |||
| public static Context getStorageContext() { | |||
| return EspeakApp.storageContext; | |||
| } | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2012-2015 Reece H. Dunn | |||
| * Copyright (C) 2011 Google Inc. | |||
| * | |||
| @@ -61,6 +62,7 @@ public class TtsService extends TextToSpeechService { | |||
| public static final String ESPEAK_INITIALIZED = "com.reecedunn.espeak.ESPEAK_INITIALIZED"; | |||
| private static final String TAG = TtsService.class.getSimpleName(); | |||
| private static Context storageContext; | |||
| private static final boolean DEBUG = false; | |||
| private SpeechSynthesis mEngine; | |||
| @@ -73,6 +75,8 @@ public class TtsService extends TextToSpeechService { | |||
| @Override | |||
| public void onCreate() { | |||
| storageContext = EspeakApp.getStorageContext(); | |||
| storageContext.moveSharedPreferencesFrom(this, this.getPackageName() + "_preferences"); | |||
| initializeTtsEngine(); | |||
| super.onCreate(); | |||
| } | |||
| @@ -94,7 +98,7 @@ public class TtsService extends TextToSpeechService { | |||
| mEngine = null; | |||
| } | |||
| mEngine = new SpeechSynthesis(this, mSynthCallback); | |||
| mEngine = new SpeechSynthesis(storageContext, mSynthCallback); | |||
| mAvailableVoices.clear(); | |||
| for (Voice voice : mEngine.getAvailableVoices()) { | |||
| mAvailableVoices.put(voice.name, voice); | |||
| @@ -118,7 +122,7 @@ public class TtsService extends TextToSpeechService { | |||
| } | |||
| private Pair<Voice, Integer> findVoice(String language, String country, String variant) { | |||
| if (!CheckVoiceData.hasBaseResources(this) || CheckVoiceData.canUpgradeResources(this)) { | |||
| if (!CheckVoiceData.hasBaseResources(storageContext) || CheckVoiceData.canUpgradeResources(storageContext)) { | |||
| if (mOnLanguagesDownloaded == null) { | |||
| mOnLanguagesDownloaded = new BroadcastReceiver() { | |||
| @Override | |||
| @@ -131,7 +135,7 @@ public class TtsService extends TextToSpeechService { | |||
| registerReceiver(mOnLanguagesDownloaded, filter); | |||
| } | |||
| final Intent intent = new Intent(this, DownloadVoiceData.class); | |||
| final Intent intent = new Intent(storageContext, DownloadVoiceData.class); | |||
| intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
| startActivity(intent); | |||
| @@ -303,7 +307,7 @@ public class TtsService extends TextToSpeechService { | |||
| mCallback = callback; | |||
| mCallback.start(mEngine.getSampleRate(), mEngine.getAudioFormat(), mEngine.getChannelCount()); | |||
| final VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(this), mEngine); | |||
| final VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(storageContext), mEngine); | |||
| mEngine.setVoice(mMatchingVoice, settings.getVoiceVariant()); | |||
| mEngine.Rate.setValue(settings.getRate(), request.getSpeechRate()); | |||
| mEngine.Pitch.setValue(settings.getPitch(), request.getPitch()); | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2013 Reece H. Dunn | |||
| * Copyright (C) 2011 The Android Open Source Project | |||
| * | |||
| @@ -35,14 +36,21 @@ import com.reecedunn.espeak.preference.SpeakPunctuationPreference; | |||
| import com.reecedunn.espeak.preference.VoiceVariantPreference; | |||
| public class TtsSettingsActivity extends PreferenceActivity { | |||
| private static Context storageContext; | |||
| @Override | |||
| @SuppressWarnings("deprecation") | |||
| protected void onCreate(Bundle savedInstanceState) { | |||
| super.onCreate(savedInstanceState); | |||
| PreferenceManager preferenceManager = getPreferenceManager(); | |||
| preferenceManager.setStorageDeviceProtected (); | |||
| // Migrate old eyes-free settings to the new settings: | |||
| final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | |||
| storageContext = EspeakApp.getStorageContext(); | |||
| final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(storageContext); | |||
| final SharedPreferences.Editor editor = prefs.edit(); | |||
| String pitch = prefs.getString(VoiceSettings.PREF_PITCH, null); | |||
| @@ -56,7 +64,7 @@ public class TtsSettingsActivity extends PreferenceActivity { | |||
| String rate = prefs.getString(VoiceSettings.PREF_RATE, null); | |||
| if (rate == null) { | |||
| // Try the old eyes-free setting: | |||
| SpeechSynthesis engine = new SpeechSynthesis(this, null); | |||
| SpeechSynthesis engine = new SpeechSynthesis(storageContext, null); | |||
| int defaultValue = engine.Rate.getDefaultValue(); | |||
| int maxValue = engine.Rate.getMaxValue(); | |||
| @@ -164,7 +172,7 @@ public class TtsSettingsActivity extends PreferenceActivity { | |||
| pref.setMax(parameter.getMaxValue()); | |||
| pref.setDefaultValue(defaultValue); | |||
| final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |||
| final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(storageContext); | |||
| final String prefString = prefs.getString(key, null); | |||
| if (prefString == null) { | |||
| pref.setProgress(defaultValue); | |||
| @@ -181,8 +189,8 @@ public class TtsSettingsActivity extends PreferenceActivity { | |||
| * summary with the current entry value. | |||
| */ | |||
| private static void createPreferences(Context context, PreferenceGroup group) { | |||
| SpeechSynthesis engine = new SpeechSynthesis(context, null); | |||
| VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(context), engine); | |||
| SpeechSynthesis engine = new SpeechSynthesis(storageContext, null); | |||
| VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(storageContext), engine); | |||
| group.addPreference(createImportVoicePreference(context)); | |||
| group.addPreference(createVoiceVariantPreference(context, settings, R.string.espeak_variant)); | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2013 Reece H. Dunn | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| @@ -20,6 +21,7 @@ import android.content.Context; | |||
| import android.content.DialogInterface; | |||
| import android.content.SharedPreferences; | |||
| import android.preference.DialogPreference; | |||
| import android.preference.PreferenceManager; | |||
| import android.util.AttributeSet; | |||
| import android.view.View; | |||
| import android.widget.Button; | |||
| @@ -113,6 +115,8 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee | |||
| String text = Integer.toString(mProgress); | |||
| callChangeListener(text); | |||
| if (shouldCommit()) { | |||
| PreferenceManager preferenceManager = getPreferenceManager(); | |||
| preferenceManager.setStorageDeviceProtected (); | |||
| SharedPreferences.Editor editor = getEditor(); | |||
| editor.putString(getKey(), text); | |||
| editor.commit(); | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2013 Reece H. Dunn | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| @@ -20,6 +21,7 @@ import android.content.Context; | |||
| import android.content.DialogInterface; | |||
| import android.content.SharedPreferences; | |||
| import android.preference.DialogPreference; | |||
| import android.preference.PreferenceManager; | |||
| import android.text.Editable; | |||
| import android.util.AttributeSet; | |||
| import android.view.View; | |||
| @@ -128,6 +130,8 @@ public class SpeakPunctuationPreference extends DialogPreference { | |||
| onDataChanged(level, characters); | |||
| if (shouldCommit()) { | |||
| PreferenceManager preferenceManager = getPreferenceManager(); | |||
| preferenceManager.setStorageDeviceProtected(); | |||
| SharedPreferences.Editor editor = getEditor(); | |||
| if (editor != null) { | |||
| editor.putString(VoiceSettings.PREF_PUNCTUATION_CHARACTERS, characters); | |||
| @@ -1,4 +1,5 @@ | |||
| /* | |||
| * Copyright (C) 2022 Beka Gozalishvili | |||
| * Copyright (C) 2013 Reece H. Dunn | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| @@ -21,6 +22,7 @@ import android.content.Context; | |||
| import android.content.DialogInterface; | |||
| import android.content.SharedPreferences; | |||
| import android.preference.DialogPreference; | |||
| import android.preference.PreferenceManager; | |||
| import android.util.AttributeSet; | |||
| import android.view.LayoutInflater; | |||
| import android.view.View; | |||
| @@ -328,6 +330,8 @@ public class VoiceVariantPreference extends DialogPreference { | |||
| case DialogInterface.BUTTON_POSITIVE: | |||
| onDataChanged(); | |||
| if (shouldCommit()) { | |||
| PreferenceManager preferenceManager = getPreferenceManager(); | |||
| preferenceManager.setStorageDeviceProtected(); | |||
| SharedPreferences.Editor editor = getEditor(); | |||
| if (editor != null) { | |||
| VoiceVariant variant = variants[mCategoryIndex][mVariantIndex].getVariant(); | |||