### 1.52 (In Development) | ### 1.52 (In Development) | ||||
android: | |||||
* Added directBoot support -- beqabeqa473 | |||||
updated languages: | updated languages: | ||||
* ba (Bashkir) -- Andiv06 | * ba (Bashkir) -- Andiv06 | ||||
* be (Belarusian) -- Andiv06, bespsm, Alaksiej Stankievič | * be (Belarusian) -- Andiv06, bespsm, Alaksiej Stankievič |
android:required="false" /> | android:required="false" /> | ||||
<application | <application | ||||
android:name="com.reecedunn.espeak.EspeakApp" | |||||
android:icon="@drawable/icon" | android:icon="@drawable/icon" | ||||
android:theme="@style/AppTheme" | android:theme="@style/AppTheme" | ||||
android:label="@string/app_name" > | android:label="@string/app_name" > | ||||
<service | <service | ||||
android:name=".TtsService" | android:name=".TtsService" | ||||
android:label="@string/app_name" > | |||||
android:label="@string/app_name" | |||||
android:directBootAware="true"> | |||||
<intent-filter> | <intent-filter> | ||||
<action android:name="android.intent.action.TTS_SERVICE" /> | <action android:name="android.intent.action.TTS_SERVICE" /> | ||||
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2012-2013 Reece H. Dunn | * Copyright (C) 2012-2013 Reece H. Dunn | ||||
* Copyright (C) 2009 The Android Open Source Project | * Copyright (C) 2009 The Android Open Source Project | ||||
* | * | ||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
Context storageContext = EspeakApp.getStorageContext(); | |||||
ArrayList<String> availableLanguages = new ArrayList<String>(); | ArrayList<String> availableLanguages = new ArrayList<String>(); | ||||
ArrayList<String> unavailableLanguages = 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) { | if (!haveBaseResources) { | ||||
unavailableLanguages.add(Locale.ENGLISH.toString()); | unavailableLanguages.add(Locale.ENGLISH.toString()); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
final SpeechSynthesis engine = new SpeechSynthesis(this, mSynthReadyCallback); | |||||
final SpeechSynthesis engine = new SpeechSynthesis(storageContext, mSynthReadyCallback); | |||||
final List<Voice> voices = engine.getAvailableVoices(); | final List<Voice> voices = engine.getAvailableVoices(); | ||||
for (Voice voice : voices) { | for (Voice voice : voices) { |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2012-2013 Reece H. Dunn | * Copyright (C) 2012-2013 Reece H. Dunn | ||||
* Copyright (C) 2009 The Android Open Source Project | * Copyright (C) 2009 The Android Open Source Project | ||||
* | * | ||||
setContentView(R.layout.download_voice_data); | setContentView(R.layout.download_voice_data); | ||||
mProgress = (ProgressBar)findViewById(R.id.progress); | 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 | @Override | ||||
protected void onPostExecute(Integer result) { | protected void onPostExecute(Integer result) { | ||||
switch (result) { | switch (result) { |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2012-2015 Reece H. Dunn | * Copyright (C) 2012-2015 Reece H. Dunn | ||||
* Copyright (C) 2011 Google Inc. | * Copyright (C) 2011 Google Inc. | ||||
* | * | ||||
public static final String ESPEAK_INITIALIZED = "com.reecedunn.espeak.ESPEAK_INITIALIZED"; | public static final String ESPEAK_INITIALIZED = "com.reecedunn.espeak.ESPEAK_INITIALIZED"; | ||||
private static final String TAG = TtsService.class.getSimpleName(); | private static final String TAG = TtsService.class.getSimpleName(); | ||||
private static Context storageContext; | |||||
private static final boolean DEBUG = false; | private static final boolean DEBUG = false; | ||||
private SpeechSynthesis mEngine; | private SpeechSynthesis mEngine; | ||||
@Override | @Override | ||||
public void onCreate() { | public void onCreate() { | ||||
storageContext = EspeakApp.getStorageContext(); | |||||
storageContext.moveSharedPreferencesFrom(this, this.getPackageName() + "_preferences"); | |||||
initializeTtsEngine(); | initializeTtsEngine(); | ||||
super.onCreate(); | super.onCreate(); | ||||
} | } | ||||
mEngine = null; | mEngine = null; | ||||
} | } | ||||
mEngine = new SpeechSynthesis(this, mSynthCallback); | |||||
mEngine = new SpeechSynthesis(storageContext, mSynthCallback); | |||||
mAvailableVoices.clear(); | mAvailableVoices.clear(); | ||||
for (Voice voice : mEngine.getAvailableVoices()) { | for (Voice voice : mEngine.getAvailableVoices()) { | ||||
mAvailableVoices.put(voice.name, voice); | mAvailableVoices.put(voice.name, voice); | ||||
} | } | ||||
private Pair<Voice, Integer> findVoice(String language, String country, String variant) { | 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) { | if (mOnLanguagesDownloaded == null) { | ||||
mOnLanguagesDownloaded = new BroadcastReceiver() { | mOnLanguagesDownloaded = new BroadcastReceiver() { | ||||
@Override | @Override | ||||
registerReceiver(mOnLanguagesDownloaded, filter); | 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); | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||||
startActivity(intent); | startActivity(intent); | ||||
mCallback = callback; | mCallback = callback; | ||||
mCallback.start(mEngine.getSampleRate(), mEngine.getAudioFormat(), mEngine.getChannelCount()); | 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.setVoice(mMatchingVoice, settings.getVoiceVariant()); | ||||
mEngine.Rate.setValue(settings.getRate(), request.getSpeechRate()); | mEngine.Rate.setValue(settings.getRate(), request.getSpeechRate()); | ||||
mEngine.Pitch.setValue(settings.getPitch(), request.getPitch()); | mEngine.Pitch.setValue(settings.getPitch(), request.getPitch()); |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2013 Reece H. Dunn | * Copyright (C) 2013 Reece H. Dunn | ||||
* Copyright (C) 2011 The Android Open Source Project | * Copyright (C) 2011 The Android Open Source Project | ||||
* | * | ||||
import com.reecedunn.espeak.preference.VoiceVariantPreference; | import com.reecedunn.espeak.preference.VoiceVariantPreference; | ||||
public class TtsSettingsActivity extends PreferenceActivity { | public class TtsSettingsActivity extends PreferenceActivity { | ||||
private static Context storageContext; | |||||
@Override | @Override | ||||
@SuppressWarnings("deprecation") | @SuppressWarnings("deprecation") | ||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
PreferenceManager preferenceManager = getPreferenceManager(); | |||||
preferenceManager.setStorageDeviceProtected (); | |||||
// Migrate old eyes-free settings to the new settings: | // 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(); | final SharedPreferences.Editor editor = prefs.edit(); | ||||
String pitch = prefs.getString(VoiceSettings.PREF_PITCH, null); | String pitch = prefs.getString(VoiceSettings.PREF_PITCH, null); | ||||
String rate = prefs.getString(VoiceSettings.PREF_RATE, null); | String rate = prefs.getString(VoiceSettings.PREF_RATE, null); | ||||
if (rate == null) { | if (rate == null) { | ||||
// Try the old eyes-free setting: | // Try the old eyes-free setting: | ||||
SpeechSynthesis engine = new SpeechSynthesis(this, null); | |||||
SpeechSynthesis engine = new SpeechSynthesis(storageContext, null); | |||||
int defaultValue = engine.Rate.getDefaultValue(); | int defaultValue = engine.Rate.getDefaultValue(); | ||||
int maxValue = engine.Rate.getMaxValue(); | int maxValue = engine.Rate.getMaxValue(); | ||||
pref.setMax(parameter.getMaxValue()); | pref.setMax(parameter.getMaxValue()); | ||||
pref.setDefaultValue(defaultValue); | pref.setDefaultValue(defaultValue); | ||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(storageContext); | |||||
final String prefString = prefs.getString(key, null); | final String prefString = prefs.getString(key, null); | ||||
if (prefString == null) { | if (prefString == null) { | ||||
pref.setProgress(defaultValue); | pref.setProgress(defaultValue); | ||||
* summary with the current entry value. | * summary with the current entry value. | ||||
*/ | */ | ||||
private static void createPreferences(Context context, PreferenceGroup group) { | 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(createImportVoicePreference(context)); | ||||
group.addPreference(createVoiceVariantPreference(context, settings, R.string.espeak_variant)); | group.addPreference(createVoiceVariantPreference(context, settings, R.string.espeak_variant)); |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2013 Reece H. Dunn | * Copyright (C) 2013 Reece H. Dunn | ||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||
import android.preference.DialogPreference; | import android.preference.DialogPreference; | ||||
import android.preference.PreferenceManager; | |||||
import android.util.AttributeSet; | import android.util.AttributeSet; | ||||
import android.view.View; | import android.view.View; | ||||
import android.widget.Button; | import android.widget.Button; | ||||
String text = Integer.toString(mProgress); | String text = Integer.toString(mProgress); | ||||
callChangeListener(text); | callChangeListener(text); | ||||
if (shouldCommit()) { | if (shouldCommit()) { | ||||
PreferenceManager preferenceManager = getPreferenceManager(); | |||||
preferenceManager.setStorageDeviceProtected (); | |||||
SharedPreferences.Editor editor = getEditor(); | SharedPreferences.Editor editor = getEditor(); | ||||
editor.putString(getKey(), text); | editor.putString(getKey(), text); | ||||
editor.commit(); | editor.commit(); |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2013 Reece H. Dunn | * Copyright (C) 2013 Reece H. Dunn | ||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||
import android.preference.DialogPreference; | import android.preference.DialogPreference; | ||||
import android.preference.PreferenceManager; | |||||
import android.text.Editable; | import android.text.Editable; | ||||
import android.util.AttributeSet; | import android.util.AttributeSet; | ||||
import android.view.View; | import android.view.View; | ||||
onDataChanged(level, characters); | onDataChanged(level, characters); | ||||
if (shouldCommit()) { | if (shouldCommit()) { | ||||
PreferenceManager preferenceManager = getPreferenceManager(); | |||||
preferenceManager.setStorageDeviceProtected(); | |||||
SharedPreferences.Editor editor = getEditor(); | SharedPreferences.Editor editor = getEditor(); | ||||
if (editor != null) { | if (editor != null) { | ||||
editor.putString(VoiceSettings.PREF_PUNCTUATION_CHARACTERS, characters); | editor.putString(VoiceSettings.PREF_PUNCTUATION_CHARACTERS, characters); |
/* | /* | ||||
* Copyright (C) 2022 Beka Gozalishvili | |||||
* Copyright (C) 2013 Reece H. Dunn | * Copyright (C) 2013 Reece H. Dunn | ||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||
import android.preference.DialogPreference; | import android.preference.DialogPreference; | ||||
import android.preference.PreferenceManager; | |||||
import android.util.AttributeSet; | import android.util.AttributeSet; | ||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
import android.view.View; | import android.view.View; | ||||
case DialogInterface.BUTTON_POSITIVE: | case DialogInterface.BUTTON_POSITIVE: | ||||
onDataChanged(); | onDataChanged(); | ||||
if (shouldCommit()) { | if (shouldCommit()) { | ||||
PreferenceManager preferenceManager = getPreferenceManager(); | |||||
preferenceManager.setStorageDeviceProtected(); | |||||
SharedPreferences.Editor editor = getEditor(); | SharedPreferences.Editor editor = getEditor(); | ||||
if (editor != null) { | if (editor != null) { | ||||
VoiceVariant variant = variants[mCategoryIndex][mVariantIndex].getVariant(); | VoiceVariant variant = variants[mCategoryIndex][mVariantIndex].getVariant(); |