android采用MediaPlayer监听EditText实现语音播报手机号码(阿拉伯数字)
项目中有语音播报手机号码的需求,以提高用户体验。我把这项工作放在最后,到今天基本实现,在这里总结如下:
android自带TTS语音组建,网上有相关的介绍;看过一些帖子,TTS支持英文的语音发音,但是中文支持还做的不是很好,特别是要朗读阿拉伯数字,操作方式不是很常见。所以我放弃了选用TTS组件实现的方式。
这里,我采用了通过MediaPlayer类播放语音文件的方式实现该功能。
思路:
1、准备0-9十个语音文件
【下载地址:http://download.csdn.net/detail/dignity568/4344108
推荐使用:http://download.csdn.net/detail/dignity568/6660783,文件更小,声音清晰短促】
2、通过对EditText添加addTextChangedListener监听器,对每次输入的数值捕捉进行语音播报;
3、语音MediaPlayer使用的朋友知道,语音文件可以放在SDcard根目录、项目的assets文件夹、或者res下的raw文件夹,总共三种方式;前两种不需要对资源文件进行编译,raw文件夹下会自动编译。
三种读取方式分别如下:
(1)sdcard读取:
1 package cn.itcast.mp3; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import android.app.Activity; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.media.MediaPlayer; 10 import android.os.Bundle; 11 import android.os.Environment; 12 import android.view.View; 13 import android.widget.Button; 14 import android.widget.EditText; 15 import android.widget.Toast; 16 17 public class MainActivity extends Activity { 18 private EditText filenameText; 19 private File audioFile; 20 private MediaPlayer mediaPlayer; 21 private int position; 22 private Context con; 23 24 @Override 25 public void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.main); 28 con = this; 29 filenameText = (EditText) this.findViewById(R.id.filename); 30 Button playbutton = (Button) this.findViewById(R.id.playbutton); 31 Button pausebutton = (Button) this.findViewById(R.id.pausebutton); 32 Button resetbutton = (Button) this.findViewById(R.id.resetbutton); 33 Button stopbutton = (Button) this.findViewById(R.id.stopbutton); 34 Button alterbutton = (Button) this.findViewById(R.id.alter); 35 ButtonClickListener listener = new ButtonClickListener(); 36 playbutton.setOnClickListener(listener); 37 pausebutton.setOnClickListener(listener); 38 resetbutton.setOnClickListener(listener); 39 stopbutton.setOnClickListener(listener); 40 alterbutton.setOnClickListener(listener); 41 42 mediaPlayer = new MediaPlayer(); 43 } 44 45 @Override 46 protected void onResume() { 47 if(audioFile!=null && position>0){ 48 try { 49 play(); 50 mediaPlayer.seekTo(position); 51 position = 0; 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 } 56 super.onResume(); 57 } 58 59 @Override 60 protected void onRestoreInstanceState(Bundle savedInstanceState) { 61 position = savedInstanceState.getInt("position"); 62 String path = savedInstanceState.getString("path"); 63 if(path!=null) { 64 audioFile = new File(path); 65 } 66 super.onRestoreInstanceState(savedInstanceState); 67 } 68 69 @Override 70 protected void onSaveInstanceState(Bundle outState) { 71 outState.putInt("position", position); 72 if(audioFile!=null) outState.putString("path", audioFile.getAbsolutePath()); 73 super.onSaveInstanceState(outState); 74 } 75 76 @Override 77 protected void onPause() { 78 if(mediaPlayer.isPlaying()){ 79 position = mediaPlayer.getCurrentPosition(); 80 mediaPlayer.stop(); 81 } 82 super.onPause(); 83 } 84 85 @Override 86 protected void onDestroy() { 87 mediaPlayer.release(); 88 super.onDestroy(); 89 } 90 91 private final class ButtonClickListener implements View.OnClickListener{ 92 private boolean pause; 93 94 public void onClick(View v) { 95 try { 96 switch (v.getId()) { 97 case R.id.playbutton: 98 String filename = filenameText.getText().toString(); 99 audioFile = new File(Environment.getExternalStorageDirectory(), "1.wav"); 100 if(!audioFile.exists()){ 101 Toast.makeText(getApplicationContext(), R.string.filenoexsit, 1).show(); 102 audioFile = null; 103 return; 104 } 105 play(); 106 break; 107 108 case R.id.pausebutton: 109 if(mediaPlayer.isPlaying()){ 110 mediaPlayer.pause(); 111 pause = true; 112 ((Button)v).setText(R.string.continuebutton); 113 }else{ 114 if(pause){ 115 mediaPlayer.start();//继续播放 116 pause = false; 117 ((Button)v).setText(R.string.pausebutton); 118 } 119 } 120 break; 121 case R.id.resetbutton: 122 if(mediaPlayer.isPlaying()){ 123 mediaPlayer.seekTo(0); 124 }else{ 125 if(audioFile!=null) play(); 126 } 127 break; 128 129 case R.id.stopbutton: 130 if(mediaPlayer.isPlaying()){ 131 mediaPlayer.stop(); 132 } 133 break; 134 case R.id.alter: 135 Intent inte = new Intent(); 136 inte.setClass(con, EditTextListenActivity.class); 137 startActivity(inte); 138 break; 139 } 140 } catch (Exception e) { 141 e.printStackTrace(); 142 } 143 } 144 145 } 146 147 private void play() throws IOException { 148 mediaPlayer.reset(); 149 mediaPlayer.setDataSource(audioFile.getAbsolutePath()); 150 mediaPlayer.prepare(); 151 mediaPlayer.start(); 152 } 153 }
(2)raw文件读取:
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.zero);
mediaPlayer.start();
(3)assert类似raw读取方式,自查;
4、addTextChangedListener监听器的使用,监听文本编辑框数值变化;这里要特别注意,EditText 的addTextChangedListener方法,很明显,是add,不是set,所以,这个Listener可被重复添加,容易导致问题出现;另外,我没有监听光标的移动,这是隐含的问题……
1 package cn.itcast.mp3; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.text.Editable; 6 import android.text.TextWatcher; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.EditText; 10 import android.widget.TextView; 11 12 public class EditTextListenActivity extends Activity { 13 private Button clearBtn; 14 private EditText et; 15 private TextView tv; 16 final int MAX_LENGTH = 20; 17 int Rest_Length = MAX_LENGTH; 18 19 @Override 20 public void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.edit); 23 tv = (TextView) findViewById(R.id.tv); 24 et = (EditText) findViewById(R.id.et); 25 clearBtn = (Button) findViewById(R.id.btn); 26 et.addTextChangedListener(new TextWatcher() { 27 @Override 28 public void beforeTextChanged(CharSequence s, int start, int count, 29 int after) { 30 tv.setText("还能输入" + Rest_Length + "个字"); 31 } 32 33 @Override 34 public void afterTextChanged(Editable s) { 35 tv.setText("还能输入" + Rest_Length + "个字"); 36 } 37 38 @Override 39 public void onTextChanged(CharSequence s, int start, int before, 40 int count) { 41 if (Rest_Length > 0) { 42 Rest_Length = MAX_LENGTH - et.getText().length(); 43 } 44 } 45 }); 46 clearBtn.setOnClickListener(new Button.OnClickListener() { 47 @Override 48 public void onClick(View v) { 49 et.setText(""); 50 Rest_Length = MAX_LENGTH; 51 } 52 }); 53 } 54 }
5、采用ToggleButton对语音播报功能进行控制切换,这里要熟悉ToggleButton的setOnCheckedChangeListener。两个监听器的使用,处理的时候问题百出,ToggleButton或是不能关闭语音播报,或者添加了多个addTextChangedListener,重复发音……一定要记得切换的时候关闭MediaPlayer,记得移除TextChangedListener——采用removeTextChangedListener。
最终实现代码如下:
1 package com.sohan.ui; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import android.app.Activity; 7 import android.app.ProgressDialog; 8 import android.content.Context; 9 import android.content.Intent; 10 import android.media.MediaPlayer; 11 import android.os.Bundle; 12 import android.text.Editable; 13 import android.text.TextWatcher; 14 import android.util.Log; 15 import android.view.View; 16 import android.view.View.OnClickListener; 17 import android.widget.Button; 18 import android.widget.CompoundButton; 19 import android.widget.CompoundButton.OnCheckedChangeListener; 20 import android.widget.EditText; 21 import android.widget.ImageView; 22 import android.widget.Toast; 23 import android.widget.ToggleButton; 24 25 public class PayTelActivity extends Activity implements OnClickListener, 26 TopActivity { 27 public ProgressDialog pd; 28 private Button nextbutton = null; 29 private EditText telnumb = null; 30 private String address; 31 private String tnum; 32 private Context con; 33 private ImageView telback1; 34 final String TAG = "PayTelActivity"; 35 CheckLogon check = new CheckLogon(); 36 private MediaPlayer mediaPlayer; 37 int Rest_Length = 0; 38 int lengthbefore = 0; 39 private File audioFile; 40 private ToggleButton audiobtn; 41 private ArrayList<TextWatcher> mListeners = null; 42 EditTextWatchTEL watch; 43 @Override 44 public void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 setContentView(R.layout.paytel); 47 con = this; 48 MainService.allActivity.add(this); 49 telnumb = (EditText) findViewById(R.id.telnum); 50 nextbutton = (Button) findViewById(R.id.telnextbutton1); 51 audiobtn = (ToggleButton) findViewById(R.id.audiobtn); 52 telback1 = (ImageView) findViewById(R.id.telback1); 53 telback1.setOnClickListener(new OnClickListener() { 54 @Override 55 public void onClick(View v) { 56 PayTelActivity.this.finish(); 57 } 58 }); 59 nextbutton.setOnClickListener(this); 60 audiobtn.setOnCheckedChangeListener(new OnCheckedChangeListener() { 61 62 public void onCheckedChanged(CompoundButton buttonView, 63 boolean isChecked) { 64 audiobtn.setChecked(isChecked); 65 if (audiobtn.isChecked()) {//mediaPlayer.isPlaying() 66 Log.d("sohan", "audiobtn isChecked!"); 67 watch = new EditTextWatchTEL(); 68 telnumb.addTextChangedListener(watch); 69 if (mListeners == null) { 70 mListeners = new ArrayList<TextWatcher>(); 71 } 72 mListeners.add(watch); 73 }else if(!audiobtn.isChecked()){ 74 Log.d("sohan", "audiobtn NOTChecked!"); 75 removeTextChangedListener(watch); 76 77 } 78 } 79 80 }); 81 } 82 public void removeTextChangedListener(TextWatcher watcher) { 83 if (mListeners != null) { 84 int i = mListeners.indexOf(watcher); 85 if (i >= 0) { 86 mListeners.remove(i); 87 } 88 } 89 telnumb.removeTextChangedListener(watcher); 90 } 91 @Override 92 public void onClick(View v) { 93 } 94 95 @Override 96 public void init() { 97 // TODO Auto-generated method stub 98 99 } 100 101 @Override 102 public void refresh(Object... param) { 103 // TODO Auto-generated method stub 104 105 } 106 107 private class EditTextWatchTEL implements TextWatcher { 108 @Override 109 public void beforeTextChanged(CharSequence s, 110 int start, int count, int after) { 111 // tv.setText("输入" + 112 // et.getText().toString().substring(Rest_Length )); 113 //telnumb.removeTextChangedListener(this); 114 } 115 116 @Override 117 public void afterTextChanged(Editable s) { 118 if (Rest_Length > 0) { 119 if (lengthbefore <= Rest_Length) { 120 121 lengthbefore = Rest_Length; 122 123 int value = Integer.parseInt(telnumb 124 .getText().toString() 125 .substring(lengthbefore - 1)); 126 127 switch (value) { 128 case 0: 129 mediaPlayer = MediaPlayer.create( 130 getApplicationContext(), 131 R.raw.zero); 132 mediaPlayer.start(); 133 break; 134 case 1: 135 mediaPlayer = MediaPlayer.create( 136 getApplicationContext(), 137 R.raw.one); 138 mediaPlayer.start(); 139 break; 140 case 2: 141 mediaPlayer = MediaPlayer.create( 142 getApplicationContext(), 143 R.raw.two); 144 mediaPlayer.start(); 145 break; 146 case 3: 147 mediaPlayer = MediaPlayer.create( 148 getApplicationContext(), 149 R.raw.three); 150 mediaPlayer.start(); 151 break; 152 case 4: 153 mediaPlayer = MediaPlayer.create( 154 getApplicationContext(), 155 R.raw.four); 156 mediaPlayer.start(); 157 break; 158 case 5: 159 mediaPlayer = MediaPlayer.create( 160 getApplicationContext(), 161 R.raw.five); 162 mediaPlayer.start(); 163 break; 164 case 6: 165 mediaPlayer = MediaPlayer.create( 166 getApplicationContext(), 167 R.raw.six); 168 mediaPlayer.start(); 169 break; 170 case 7: 171 mediaPlayer = MediaPlayer.create( 172 getApplicationContext(), 173 R.raw.seven); 174 mediaPlayer.start(); 175 break; 176 case 8: 177 mediaPlayer = MediaPlayer.create( 178 getApplicationContext(), 179 R.raw.eight); 180 mediaPlayer.start(); 181 break; 182 case 9: 183 mediaPlayer = MediaPlayer.create( 184 getApplicationContext(), 185 R.raw.nine); 186 mediaPlayer.start(); 187 break; 188 189 } 190 } else { 191 lengthbefore = Rest_Length; 192 193 } 194 } 195 } 196 197 @Override 198 public void onTextChanged(CharSequence s, int start, 199 int before, int count) { 200 Rest_Length = telnumb.getText().length(); 201 } 202 } 203 }
效果图:
posted on 2012-06-01 10:13 Brown Qin 阅读(2742) 评论(0) 编辑 收藏 举报