<?xml version="1.0" encoding="utf-8"?> | |||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:orientation="vertical" > | |||||
<Spinner | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:id="@+id/dictionaries" | |||||
android:gravity="bottom" | |||||
android:layout_gravity="center_vertical" /> | |||||
</LinearLayout> |
<string name="variant_old">Old</string> | <string name="variant_old">Old</string> | ||||
<string name="variant_croak">Croak</string> | <string name="variant_croak">Croak</string> | ||||
<string name="variant_whisper">Whisper</string> | <string name="variant_whisper">Whisper</string> | ||||
<string name="import_voice_title">Import eSpeak dictionary</string> | |||||
<string name="import_voice_description">Import an eSpeak voice dictionary file from the SD card.</string> | |||||
</resources> | </resources> |
/* | |||||
* Copyright (C) 2013 Reece H. Dunn | |||||
* | |||||
* 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.Activity; | |||||
import android.view.LayoutInflater; | |||||
import android.view.View; | |||||
import android.view.ViewGroup; | |||||
import android.widget.ArrayAdapter; | |||||
import android.widget.TextView; | |||||
import java.io.File; | |||||
public class FileListAdapter extends ArrayAdapter<File> | |||||
{ | |||||
private final LayoutInflater mInflater; | |||||
static class ViewHolder | |||||
{ | |||||
public TextView text; | |||||
} | |||||
public FileListAdapter(Activity context, File[] resources) | |||||
{ | |||||
super(context, android.R.layout.simple_list_item_1, resources); | |||||
mInflater = context.getLayoutInflater(); | |||||
} | |||||
@Override | |||||
public View getView(int position, View convertView, ViewGroup parent) | |||||
{ | |||||
ViewHolder holder; | |||||
if (convertView == null) | |||||
{ | |||||
convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); | |||||
holder = new ViewHolder(); | |||||
holder.text = (TextView)convertView.findViewById(android.R.id.text1); | |||||
convertView.setTag(holder); | |||||
} | |||||
else | |||||
{ | |||||
holder = (ViewHolder)convertView.getTag(); | |||||
} | |||||
File file = getItem(position); | |||||
holder.text.setText(file.getName()); | |||||
return convertView; | |||||
} | |||||
@Override | |||||
public View getDropDownView(int position, View convertView, ViewGroup parent) | |||||
{ | |||||
return getView(position, convertView, parent); | |||||
} | |||||
} |
public class FileUtils { | public class FileUtils { | ||||
public static String read(File file) throws IOException { | public static String read(File file) throws IOException { | ||||
return read(new FileInputStream(file), (int)file.length()); | |||||
return readByteArray(new FileInputStream(file), (int)file.length()).toString(); | |||||
} | } | ||||
public static String read(InputStream stream) throws IOException { | public static String read(InputStream stream) throws IOException { | ||||
return read(stream, stream.available()); | |||||
return readByteArray(stream, stream.available()).toString(); | |||||
} | } | ||||
public static String read(InputStream stream, int length) throws IOException { | public static String read(InputStream stream, int length) throws IOException { | ||||
return readByteArray(stream, length).toString(); | |||||
} | |||||
public static byte[] readBinary(File file) throws IOException { | |||||
return readByteArray(new FileInputStream(file), (int)file.length()).toByteArray(); | |||||
} | |||||
public static byte[] readBinary(InputStream stream) throws IOException { | |||||
return readByteArray(stream, stream.available()).toByteArray(); | |||||
} | |||||
public static byte[] readBinary(InputStream stream, int length) throws IOException { | |||||
return readByteArray(stream, length).toByteArray(); | |||||
} | |||||
private static ByteArrayOutputStream readByteArray(InputStream stream, int length) throws IOException { | |||||
ByteArrayOutputStream content = new ByteArrayOutputStream(length); | ByteArrayOutputStream content = new ByteArrayOutputStream(length); | ||||
int c = stream.read(); | int c = stream.read(); | ||||
while (c != -1) | while (c != -1) | ||||
content.write((byte)c); | content.write((byte)c); | ||||
c = stream.read(); | c = stream.read(); | ||||
} | } | ||||
return content.toString(); | |||||
return content; | |||||
} | } | ||||
public static void write(File outputFile, String contents) throws IOException { | public static void write(File outputFile, String contents) throws IOException { | ||||
write(outputFile, contents.getBytes()); | |||||
} | |||||
public static void write(File outputFile, byte[] contents) throws IOException { | |||||
FileOutputStream outputStream = new FileOutputStream(outputFile); | FileOutputStream outputStream = new FileOutputStream(outputFile); | ||||
try { | try { | ||||
outputStream.write(contents.getBytes(), 0, contents.length()); | |||||
outputStream.write(contents, 0, contents.length); | |||||
} finally { | } finally { | ||||
outputStream.close(); | outputStream.close(); | ||||
} | } |
import android.preference.PreferenceGroup; | import android.preference.PreferenceGroup; | ||||
import android.preference.PreferenceManager; | import android.preference.PreferenceManager; | ||||
import com.reecedunn.espeak.preference.ImportVoicePreference; | |||||
import com.reecedunn.espeak.preference.SeekBarPreference; | import com.reecedunn.espeak.preference.SeekBarPreference; | ||||
import com.reecedunn.espeak.preference.SpeakPunctuationPreference; | import com.reecedunn.espeak.preference.SpeakPunctuationPreference; | ||||
import com.reecedunn.espeak.preference.VoiceVariantPreference; | import com.reecedunn.espeak.preference.VoiceVariantPreference; | ||||
} | } | ||||
} | } | ||||
private static Preference createImportVoicePreference(Context context) { | |||||
final String title = context.getString(R.string.import_voice_title); | |||||
final ImportVoicePreference pref = new ImportVoicePreference(context); | |||||
pref.setTitle(title); | |||||
pref.setDialogTitle(title); | |||||
pref.setOnPreferenceChangeListener(mOnPreferenceChanged); | |||||
pref.setDescription(R.string.import_voice_description); | |||||
return pref; | |||||
} | |||||
private static Preference createVoiceVariantPreference(Context context, VoiceSettings settings, int titleRes) { | private static Preference createVoiceVariantPreference(Context context, VoiceSettings settings, int titleRes) { | ||||
final String title = context.getString(titleRes); | final String title = context.getString(titleRes); | ||||
SpeechSynthesis engine = new SpeechSynthesis(context, null); | SpeechSynthesis engine = new SpeechSynthesis(context, null); | ||||
VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(context), engine); | VoiceSettings settings = new VoiceSettings(PreferenceManager.getDefaultSharedPreferences(context), engine); | ||||
group.addPreference(createImportVoicePreference(context)); | |||||
group.addPreference(createVoiceVariantPreference(context, settings, R.string.espeak_variant)); | group.addPreference(createVoiceVariantPreference(context, settings, R.string.espeak_variant)); | ||||
group.addPreference(createSpeakPunctuationPreference(context, settings, R.string.espeak_speak_punctuation)); | group.addPreference(createSpeakPunctuationPreference(context, settings, R.string.espeak_speak_punctuation)); | ||||
group.addPreference(createSeekBarPreference(context, engine.Rate, VoiceSettings.PREF_RATE, R.string.setting_default_rate)); | group.addPreference(createSeekBarPreference(context, engine.Rate, VoiceSettings.PREF_RATE, R.string.setting_default_rate)); |
/* | |||||
* Copyright (C) 2013 Reece H. Dunn | |||||
* | |||||
* 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.preference; | |||||
import android.app.Activity; | |||||
import android.app.DownloadManager; | |||||
import android.content.Context; | |||||
import android.content.DialogInterface; | |||||
import android.content.Intent; | |||||
import android.os.AsyncTask; | |||||
import android.os.Environment; | |||||
import android.preference.DialogPreference; | |||||
import android.util.AttributeSet; | |||||
import android.view.View; | |||||
import android.widget.Spinner; | |||||
import com.reecedunn.espeak.CheckVoiceData; | |||||
import com.reecedunn.espeak.DownloadVoiceData; | |||||
import com.reecedunn.espeak.FileListAdapter; | |||||
import com.reecedunn.espeak.FileUtils; | |||||
import com.reecedunn.espeak.R; | |||||
import java.io.File; | |||||
import java.io.FileFilter; | |||||
import java.io.FileInputStream; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.IOException; | |||||
import java.util.Arrays; | |||||
public class ImportVoicePreference extends DialogPreference { | |||||
private File mRoot; | |||||
private Spinner mDictionaries; | |||||
public ImportVoicePreference(Context context, AttributeSet attrs, int defStyle) { | |||||
super(context, attrs, defStyle); | |||||
setDialogLayoutResource(R.layout.import_voice_preference); | |||||
setLayoutResource(R.layout.information_view); | |||||
setPositiveButtonText(android.R.string.ok); | |||||
setNegativeButtonText(android.R.string.cancel); | |||||
mRoot = Environment.getExternalStorageDirectory(); | |||||
} | |||||
public ImportVoicePreference(Context context, AttributeSet attrs) { | |||||
this(context, attrs, 0); | |||||
} | |||||
public ImportVoicePreference(Context context) { | |||||
this(context, null); | |||||
} | |||||
public void setDescription(int resId) { | |||||
callChangeListener(getContext().getString(resId)); | |||||
} | |||||
@Override | |||||
protected View onCreateDialogView() { | |||||
View root = super.onCreateDialogView(); | |||||
mDictionaries = (Spinner)root.findViewById(R.id.dictionaries); | |||||
return root; | |||||
} | |||||
@Override | |||||
protected void onBindDialogView(View view) { | |||||
super.onBindDialogView(view); | |||||
File[] dictionaries = mRoot.listFiles(new FileFilter() { | |||||
@Override | |||||
public boolean accept(File file) { | |||||
return !file.isDirectory() && file.getName().endsWith("_dict"); | |||||
} | |||||
}); | |||||
Arrays.sort(dictionaries); | |||||
mDictionaries.setAdapter(new FileListAdapter((Activity)getContext(), dictionaries)); | |||||
} | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
switch (which) { | |||||
case DialogInterface.BUTTON_POSITIVE: | |||||
new AsyncTask<Object,Object,Object>() { | |||||
@Override | |||||
protected Object doInBackground(Object... objects) { | |||||
File source = (File)mDictionaries.getSelectedItem(); | |||||
File destination = new File(CheckVoiceData.getDataPath(getContext()), source.getName()); | |||||
try { | |||||
byte[] data = FileUtils.readBinary(source); | |||||
FileUtils.write(destination, data); | |||||
} catch (IOException e) { | |||||
} | |||||
return null; | |||||
} | |||||
@Override | |||||
protected void onPostExecute(Object object) { | |||||
final Intent intent = new Intent(DownloadVoiceData.BROADCAST_LANGUAGES_UPDATED); | |||||
getContext().sendBroadcast(intent); | |||||
} | |||||
}.execute(); | |||||
break; | |||||
} | |||||
super.onClick(dialog, which); | |||||
} | |||||
} |