Android TTS实现简单阅读器
简单的Txt文本阅读器,主要用于介绍Google Android的TTS接口。
一、
TTS
在package android.speech.tts内,主要阅读下TextToSpeech.OnInitListener、TextToSpeech. OnUtteranceCompletedListener两个接口和TextToSpeech、TextToSpeech.Engine两个类。
具体还是自己去看下SDK文档吧。(我也是完整阅读过了的^^)
二、
TTS
引擎
以前在网上的例子,或者就我《
Android基础样例》里的中文TTS例子,都是eSpeak引擎实现的。这种方式是要用其封装的TTS接口,再通过下载TTS数据使用。
而Android的SDK中还提供了TTS服务的接口,用于供应商提供服务的。也就是语音合成服务商只管提供它的服务,开发者只管使用Android的TTS接口,用户自己安装想要的服务自己进行选择。
总之呢,我用的是讯飞语音TTS v1.0。有两个文件,一个是Service程序,一个是语音数据。下载网址:http://soft.shouji.com.cn/down/22160.html
1
)关于讯飞(貌似广告?)
好吧,少说点了,它也提供了个开发者平台。如下:
有试了下它那语音分析,话说,弹出的框框能不能好看点啊。(做个小话筒就好了么T^T)
恩,还有,现在讯飞是要开始宣传了么?貌似3月22日什么开发者大会-_-!(又广告了?)
2
)其他中文引擎
参见文章:Android中文语音合成(TTS)各家引擎对比。(原网址打不开==,另外的网址就不贴了,搜下吧)
三、阅读器工程
现在学乖了,直接贴些代码得了==。代码中注释应该满清晰详细了^^。
1
)界面布局
布局由main.xml includes header.xml & footer.xml组成,并写有了定时收起等。
TtsFatherActivity.java
-
-
-
-
- public abstract class TtsFatherActivity extends Activity {
-
- private GestureDetector gd;
- private GlobalUtil globalUtil;
-
- private ScrollView scrollView;
- private LinearLayout headerLayout, footerLayout;
- private TextView textView;
-
- private static final long ANIM_DURATION = 500;
-
- private static final int DIALOG_TEXT_LIST = 0;
- private final String[] textPaths = new String[] { "one.txt", "two.txt",
- "浏览..." };
-
- protected String textTitle;
- protected String textContent;
-
- private Timer timer;
- private static final long TIMEOUT = 2000;
- private static final int TIMER_LAYOUT_OUT = 1;
-
- private boolean isLayoutOut = false;
-
-
- public Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case TIMER_LAYOUT_OUT:
-
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_OUT, ANIM_DURATION);
- headerLayout.setVisibility(View.GONE);
-
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_OUT, ANIM_DURATION);
- footerLayout.setVisibility(View.GONE);
- isLayoutOut = true;
- break;
- }
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- gd = new GestureDetector(new MySimpleGesture());
- globalUtil = GlobalUtil.getInstance();
-
- scrollView = (ScrollView) findViewById(R.id.scrollView);
- headerLayout = (LinearLayout) findViewById(R.id.headerLayout);
- footerLayout = (LinearLayout) findViewById(R.id.footerLayout);
- textView = (TextView) findViewById(R.id.textView);
-
- setText(0);
- newTimerLayoutOut();
- }
-
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- gd.onTouchEvent(ev);
- scrollView.onTouchEvent(ev);
- return super.dispatchTouchEvent(ev);
- }
-
-
- @Override
- protected Dialog onCreateDialog(int id) {
- switch (id) {
- case DIALOG_TEXT_LIST:
- return new AlertDialog.Builder(this).setItems(textPaths,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (2 == which) {
-
- startActivityForResult(new Intent(
- TtsFatherActivity.this,
- FileBrowserActivity.class),
- FileBrowserActivity.CODE_FILE_BROWSER);
- } else {
- setText(which);
- }
- }
- }).create();
- }
- return super.onCreateDialog(id);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == FileBrowserActivity.CODE_FILE_BROWSER) {
- if (resultCode == RESULT_OK) {
-
- String filename = data.getExtras().getString(
- FileBrowserActivity.KEY_FILENAME);
- this.textTitle = filename;
- try {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- textContent = globalUtil.is2Str(new FileInputStream(
- new File(filename)));
-
-
- textView.setText(textContent);
-
-
- } catch (Exception e) {
- textView.setText(R.string.text_error);
- textContent = "";
- }
- }
- }
- }
-
-
- private void setText(int textIndex) {
- this.textTitle = textPaths[textIndex];
- try {
- textContent = globalUtil.is2Str(getAssets().open(textTitle),
- "UTF-8");
- textView.setText(textContent);
- } catch (IOException e) {
- textView.setText(R.string.text_error);
- textContent = "";
- }
- }
-
-
- protected void newTimerLayoutOut() {
- if (null != timer) {
- timer.cancel();
- }
- timer = new Timer();
-
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- mHandler.sendEmptyMessage(TIMER_LAYOUT_OUT);
- }
- }, TIMEOUT);
- }
-
-
- private class MySimpleGesture extends SimpleOnGestureListener {
-
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- if (isLayoutOut) {
-
- headerLayout.setVisibility(View.VISIBLE);
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_IN, ANIM_DURATION);
-
- footerLayout.setVisibility(View.VISIBLE);
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_IN, ANIM_DURATION);
- newTimerLayoutOut();
- isLayoutOut = false;
- } else {
-
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_OUT, ANIM_DURATION);
- headerLayout.setVisibility(View.GONE);
-
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_OUT, ANIM_DURATION);
- footerLayout.setVisibility(View.GONE);
-
- if (null != timer) {
- timer.cancel();
- }
- isLayoutOut = true;
- }
- return false;
- }
-
-
- @Override
- public void onLongPress(MotionEvent e) {
-
- showDialog(DIALOG_TEXT_LIST);
- }
- }
-
- }
2
)TTS
控制
音量&语速控制也写了的^^。
TtsSampleActivity.java
- public class TtsSampleActivity extends TtsFatherActivity implements
- OnSeekBarChangeListener, TextToSpeech.OnInitListener,
- TextToSpeech.OnUtteranceCompletedListener {
-
-
-
- private AudioManager audioManager;
-
-
- private static final int STREAM_TTS = AudioManager.STREAM_MUSIC;
-
- private TextToSpeech mTts;
- private static final int REQ_CHECK_TTS_DATA = 110;
- private boolean isSetting = false;
- private boolean isRateChanged = false;
- private boolean isStopped = false;
- private float mSpeechRate = 1.0f;
-
- private SeekBar volumeBar, speedBar;
-
-
- private static final String SAVE_DIR_PATH = "/sdcard/AndroidTTS/";
- private static final String SAVE_FILE_PATH = SAVE_DIR_PATH + "sound.wav";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
-
- audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-
-
- volumeBar = (SeekBar) findViewById(R.id.volumeBar);
- volumeBar.setOnSeekBarChangeListener(this);
-
- volumeBar.setProgress(audioManager.getStreamVolume(STREAM_TTS));
-
-
- speedBar = (SeekBar) findViewById(R.id.speedBar);
- speedBar.setOnSeekBarChangeListener(this);
-
- initDirs(SAVE_DIR_PATH);
- }
-
-
- public void saveFile(View v) {
-
- int resId = TextToSpeech.SUCCESS == ttsSaveFile(textContent,
- SAVE_FILE_PATH) ? R.string.synt_success : R.string.synt_fail;
- Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
- newTimerLayoutOut();
- }
-
-
- public void playFile(View v) {
- ttsPlayFile(SAVE_FILE_PATH);
- newTimerLayoutOut();
- }
-
-
- public void stop(View v) {
- ttsStop();
- newTimerLayoutOut();
- }
-
-
- public void play(View v) {
- ttsPlay();
- newTimerLayoutOut();
- }
-
-
- public void setting(View v) {
-
- isSetting = toTtsSettings();
- newTimerLayoutOut();
- }
-
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- switch (seekBar.getId()) {
- case R.id.volumeBar:
-
- audioManager.setStreamVolume(STREAM_TTS, progress, 0);
- break;
- case R.id.speedBar:
-
- isRateChanged = true;
-
- mSpeechRate = (progress >= 10) ? (progress / 10f)
- : (0.5f + progress / 20f);
-
- checkTtsData();
- break;
- }
- newTimerLayoutOut();
- }
-
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
-
-
-
-
-
-
-
-
- @Override
- public void onInit(int status) {
- if (status == TextToSpeech.SUCCESS) {
- mTts.setSpeechRate(mSpeechRate);
-
- mTts.setOnUtteranceCompletedListener(this);
- if (isRateChanged) {
- ttsPlay();
- isRateChanged = false;
- }
- }
- }
-
-
-
-
-
-
-
-
-
- @Override
- public void onUtteranceCompleted(final String utteranceId) {
-
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- int resId = isStopped ? R.string.utte_stopped
- : R.string.utte_completed;
-
- Toast.makeText(getApplicationContext(),
- getString(resId, utteranceId), Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
-
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQ_CHECK_TTS_DATA) {
- switch (resultCode) {
- case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
-
- if (null != mTts) {
- ttsStop();
- ttsShutDown();
- }
- mTts = new TextToSpeech(this, this);
- break;
- case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
- case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
- case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
- notifyReinstallDialog();
- break;
- case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
- default:
- break;
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
-
- private boolean checkTtsData() {
- try {
- Intent checkIntent = new Intent();
- checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
- startActivityForResult(checkIntent, REQ_CHECK_TTS_DATA);
- return true;
- } catch (ActivityNotFoundException e) {
- return false;
- }
- }
-
-
- private void notifyReinstallDialog() {
- new AlertDialog.Builder(this).setTitle("TTS引擎数据错误")
- .setMessage("是否尝试重装TTS引擎数据到设备上?")
- .setPositiveButton("是", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- Intent dataIntent = new Intent();
- dataIntent
- .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
- startActivity(dataIntent);
- }
- }).setNegativeButton("否", null).show();
- }
-
-
- private boolean toTtsSettings() {
- try {
- startActivity(new Intent("com.android.settings.TTS_SETTINGS"));
- return true;
- } catch (ActivityNotFoundException e) {
- return false;
- }
- }
-
- @Override
- protected void onStart() {
- checkTtsData();
- super.onStart();
- }
-
- @Override
- protected void onResume() {
-
- if (isSetting) {
- checkTtsData();
- isSetting = false;
- }
- super.onResume();
- }
-
- @Override
- protected void onStop() {
-
- ttsStop();
- super.onStop();
- }
-
- @Override
- public void onBackPressed() {
-
- ttsStop();
- ttsShutDown();
- super.onBackPressed();
- }
-
-
- private int ttsPlay() {
- if (null != mTts) {
- isStopped = false;
-
-
-
-
-
-
-
-
-
-
- HashMap<String, String> params = new HashMap<String, String>();
- params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, textTitle);
- return mTts.speak(textContent, TextToSpeech.QUEUE_FLUSH, params);
- }
- return TextToSpeech.ERROR;
- }
-
-
-
-
-
-
-
-
- private int ttsStop() {
- isStopped = true;
- return (null == mTts) ? TextToSpeech.ERROR : mTts.stop();
- }
-
-
- private void ttsShutDown() {
- if (null != mTts) {
- mTts.shutdown();
- }
- }
-
-
- private void initDirs(final String dirpath) {
- File file = new File(dirpath);
- if (!file.exists()) {
- file.mkdirs();
- }
- }
-
-
- private int ttsSaveFile(String text, final String filename) {
- return (null == mTts) ? TextToSpeech.ERROR : mTts.synthesizeToFile(
- text, null, filename);
- }
-
-
- private int ttsPlayFile(final String filename) {
-
- if (new File(filename).exists()) {
- try {
-
- MediaPlayer player = new MediaPlayer();
- player.setDataSource(filename);
- player.prepare();
- player.start();
- return TextToSpeech.SUCCESS;
- } catch (Exception e) {
- e.printStackTrace();
- return TextToSpeech.ERROR;
- }
- }
- return TextToSpeech.ERROR;
- }
-
- }
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/809873,如需转载请自行联系原作者