`

2011.10.19——— android 显示一行内容并录制其音频

阅读更多
2011.10.19——— android 显示一行内容并录制其音频

一个小工具

同事作语音识别 需要其他人帮他录制音频,台式机没有麦克 所以希望用手机来录,就需要一个小程序

需求:
1、装载一个txt文本,每次读取一行
2、根据这个文本进行录音
3、将pcm文件与每行文字 的对应关系 写入一个txt文本当中

思路:

1、录制pcm
2、选着文本 一个简易的文件管理器

代码:

录制:

package com.lp.read;



import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
 * AudioRecord录制PCM AudioTrack播放
 * @author Administrator
 *
 */
public class MainActivity2 extends Activity implements OnClickListener{
	
	
	private Button btnStart,btnCheck;
//	private Button btnPlay2;
	
	private RecordTask recorder;
	private PlayTask player;
	
	private String mFileName;
	private String mDirName;
    private String sdcard;
	
	private boolean isRecording=true, isPlaying=false, mStartRecording = true;; 
	
	private int frequence = 16000; 
	private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
	
	private AudioManager am;
	
	private int mode;
	
	private TextView tv;
    
    private List<String> texts = new ArrayList<String>();
    private int index = 1;
    
    private boolean isWrite = true;
    private String writeFileName;
    private WriteThread thread;
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_pcm);
		
		sdcard = Environment.getExternalStorageDirectory().getAbsolutePath();
        mDirName = sdcard +  "/read";
    	File f = new File(mDirName);
    	if(!f.exists()){
			f.mkdir();
    	}
		
		am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
		
		btnStart = (Button)this.findViewById(R.id.btn_start);
//		btnPlay2 = (Button)this.findViewById(R.id.btn_play2);
		btnStart.setOnClickListener(this);
//		btnPlay2.setOnClickListener(this);
		btnStart.setEnabled(false);
//		btnPlay2.setEnabled(false);
		
		btnCheck = (Button)findViewById(R.id.btn_check);
		btnCheck.setOnClickListener(this);
		
		tv = (TextView)findViewById(R.id.tv);
		
		thread = new WriteThread();
		thread.start();
	}
	
	
	public void onClick(View v){
		int id = v.getId();
		switch(id){
		case R.id.btn_start:
			if (mStartRecording) {
				this.isRecording = true;
				mFileName = mDirName + "/"+new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss").format( new Date().getTime())+".pcm";
    			recorder = new RecordTask();
    			recorder.execute();
    			
                ((Button)v).setText("录音停止");
            } else {
            	this.isRecording = false;
            	((Button)v).setText("录音开始");
            	changeText();
            	thread.setfName(mFileName);
            	thread.setText(tv.getText().toString());
//            	btnPlay2.setEnabled(true);
            }
            mStartRecording = !mStartRecording;
			
			break;
//		case R.id.btn_play2:
//			this.isPlaying = true;
//			btnPlay2.setEnabled(false);
//			mode = AudioManager.STREAM_MUSIC;
//			
//			if(!am.isSpeakerphoneOn()){
//				am.setSpeakerphoneOn(true);
//			}
//			setVolumeControlStream(AudioManager.STREAM_MUSIC);
//			am.setMode(AudioManager.MODE_NORMAL);
//			am.setStreamVolume(AudioManager.STREAM_MUSIC, am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0); 
//			
//			player = new PlayTask();
//			player.execute();
//			break;
		case R.id.btn_check:
			
			Intent intent = new Intent(this,FileOSActivity.class);
			startActivityForResult(intent, 100);
			break;
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if(data!=null ){
			String path = data.getStringExtra("path");
			String name = path.substring(path.lastIndexOf("/")+1).toLowerCase().replace(".txt", "");
			//清空数据
			texts.clear();
			index = 1;
			writeFileName = mDirName + "/"+name+"_"+new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss").format( new Date().getTime())+".txt";
			new ReadTextAsyncTask().execute(path);
			btnStart.setEnabled(true);
		}
	}


	private void changeText(){
    	System.out.println(texts.size());
    	if(index < texts.size()){
	    	tv.setText(texts.get(index));
	    	index++;
    	}else{
    		texts.clear();
    		index = 1;
    		btnStart.setEnabled(false);
    		tv.setText("");
    		Toast.makeText(this, "此文件已读完。", 1).show();
    	}
    }
	
	class RecordTask extends AsyncTask<Void, Integer, Void>{
		@Override
		protected Void doInBackground(Void... arg0) {
			AudioRecord record = null;
			DataOutputStream dos = null;
			//FileOutputStream fos = null;
			//isRecording = true;
			try {
				//开通输出流到指定的文件
				dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(mFileName)));
				//fos = new FileOutputStream(audioFile);
				//根据定义好的几个配置,来获取合适的缓冲大小
				int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
				//实例化AudioRecord
				record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, channelConfig, audioEncoding, bufferSize);
				//定义缓冲
				short[] buffer = new short[bufferSize];
				//byte[] buffer = new byte[bufferSize];
				
				//开始录制
				record.startRecording();
				
				//定义循环,根据isRecording的值来判断是否继续录制
				while(isRecording){
					//从bufferSize中读取字节,返回读取的short个数
					int bufferReadResult = record.read(buffer, 0, buffer.length);
					//循环将buffer中的音频数据写入到OutputStream中
					for(int i=0; i<bufferReadResult; i++){
						dos.writeShort(buffer[i]);
					}
					
//					byte[] tmpBuf = new byte[bufferReadResult];  
//                    System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult); 
//                    fos.write(tmpBuf, 0, bufferReadResult);
//                    fos.flush();
				}
				//录制结束
				record.stop();
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				record.release();
				try {
					dos.close();
					//fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			return null;
		}
	}
	
	class PlayTask extends AsyncTask<Void, Integer, Void>{
		@Override
		protected Void doInBackground(Void... arg0) {
			AudioTrack track = null;
			DataInputStream dis = null;
			int bufferSize = AudioTrack.getMinBufferSize(frequence, channelConfig, audioEncoding);
			short[] buffer = new short[bufferSize];
			//byte[] buffer = new byte[bufferSize];
			try {
				//定义输入流,将音频写入到AudioTrack类中,实现播放
				dis = new DataInputStream(new BufferedInputStream(new FileInputStream(mFileName)));
				//FileInputStream fis = new FileInputStream(audioFile);
				//实例AudioTrack
				//AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM);
				track = new AudioTrack(mode, frequence, AudioFormat.CHANNEL_OUT_MONO, audioEncoding, bufferSize, AudioTrack.MODE_STREAM);
				//开始播放
				track.play();
				//由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
				while(isPlaying && dis.available()>0){
					int i = 0;
					while(dis.available()>0 && i<buffer.length){
						buffer[i] = dis.readShort();
						i++;
					}
					//然后将数据写入到AudioTrack中
					track.write(buffer, 0, buffer.length);
					
				}
				
				//播放结束
				track.stop();
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				track.release();
				try {
					dis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
//			btnPlay2.setEnabled(true);
		}
		
	}
	
	
	private class ReadTextAsyncTask extends AsyncTask<String, Void, Void>{

		@Override
		protected Void doInBackground(String... params) {
			String path = params[0];
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(new FileInputStream(path),"GB2312"));
				String readStr = null;
				while((readStr = br.readLine()) != null){
					texts.add(readStr);
					
					//第一次的时候  改变一下textview
					if(texts.size()==1){
						publishProgress();
					}
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try{
					br.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);
			tv.setText(texts.get(0));
		}
    }
	
	private class WriteThread extends Thread{

		String fName = null;
		String text = null;
		
		@Override
		public void run() {
			
			while(isWrite){
				
				if(fName!=null && text!=null && !fName.equals("") && !text.equals("")){
					write();
					fName = null;
					text = null;
				}
			}
			
		}
		
		private void write(){
			BufferedWriter bw = null;
			try {
				bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(writeFileName,true)));
				bw.write(text+"---------------->>"+fName);
				bw.write("\r\n");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try{
					bw.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
		
		public void setfName(String fName){
			this.fName = fName;
		}
		
		public void setText(String text){
			this.text = text;
		}
		
	}

	@Override
	protected void onPause() {
		super.onPause();
//		isWrite = false;
//		isRecording = false;
	}
	
	
	
}



文件管理器:

package com.lp.read;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class FileOSActivity extends ListActivity {

	static final int REQUEST_CODE = 1;

	private static String SDpath;

	// 显示模式
	private enum DISPLAYMODE {
		ABSOLUTE, RELATIVE;
	}

	private final DISPLAYMODE displayMode = DISPLAYMODE.RELATIVE;

	private List<IconifiedText> directoryEntries = new ArrayList<IconifiedText>();

	public File currentDirectory = new File("/");// 当前目录

	public boolean TCardExist;

	// private File currentDirectory = new File(filePath);

	/** Called when the activity is first created. */
	/** Activity被创建时调用 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		TCardExist = judgeSDcard();
		if (TCardExist) {
			SDpath = getSDPath();
			Log.e("yangw getSDPath", SDpath);

			EnterFolder(new File(SDpath));
			// browseTo(new File("/"));
			this.setSelection(0);
		} else {
			Log.e("yangw", "SDcard is not exist");
			setContentView(R.layout.nosdcard);
		}
		// this.setSelection(0);
	}

	// 判断sd卡是否存在
	public boolean judgeSDcard() {

		boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
		return sdCardExist;
	}

	// 获取sd卡路径 Environment
	public String getSDPath() {
		File sdDir = null;
		sdDir = Environment.getExternalStorageDirectory();// 获取跟目录

		return sdDir.toString();
	}

	/**
	 * This function browses up one level according to the field: currentDirectory
	 */
	private void upOneLevel() {
		if (this.currentDirectory.getParent() != null)
			this.EnterFolder(this.currentDirectory.getParentFile());
	}

	private void EnterFolder(final File aDirectory) {
		if (this.displayMode == DISPLAYMODE.RELATIVE)

			// getAbsolutePath 得到一个文件的绝对路径
			this.setTitle(aDirectory.getAbsolutePath());
		Log.e("open folder aDirectory.getAbsolutePath()", aDirectory.getAbsolutePath());

		this.currentDirectory = aDirectory;
		Log.e("Fill 路径", aDirectory.getPath());
		FillList(aDirectory.listFiles());
	}

	private void openFile(File f) {
		Log.e("yangw mark", f.getAbsolutePath());
		String fName = f.getName();
		String end = fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase();
		if(end.equals("txt")){
			Intent intent = new Intent();
			intent.putExtra("path", f.getAbsolutePath());
			setResult(100, intent);
			finish();
		}else{
			Toast.makeText(this, "请选择txt文本结构!", 0).show();
		}

	}

	private void FillList(File[] files) {

		this.directoryEntries.clear();// 清空列表

		String momentpath = GetCurDirectory();
		Log.e("GetCurDirectory momentpath", momentpath);
		Log.e("getSDPath sdpath", SDpath);
		Log.e("this.currentDirectory.getParent()", this.currentDirectory.getParent());
		// and the ".." == 'Up one level'
		
		for (File currentFile : files) {
			// 显示模式?
			switch (this.displayMode) {
				case ABSOLUTE:

					/* On absolute Mode, we show the full path */
					this.directoryEntries.add(new IconifiedText(currentFile.getAbsolutePath(), null));

					break;
				case RELATIVE:
					/*
					 * On relative Mode, we have to cut the current-path at the beginning
					 */
					int currentPathStringLenght = this.currentDirectory.getAbsolutePath().length();

					if (this.currentDirectory.getParent() != null) {
						this.directoryEntries.add(new IconifiedText(currentFile.getAbsolutePath().substring(currentPathStringLenght + 1), null));
					} else {
						this.directoryEntries.add(new IconifiedText(currentFile.getAbsolutePath().substring(currentPathStringLenght), null));
					}

					break;
			}
		}

		Collections.sort(this.directoryEntries);// 排序
		
		// 如果不是根目录则添加上一级目录
		if (this.currentDirectory.getParent() != null && momentpath != SDpath)
			if (!momentpath.equals(SDpath)) {
				this.directoryEntries.add(0,new IconifiedText(getString(R.string.up_one_level), null));
			}

		IconifiedTextListAdapter itla = new IconifiedTextListAdapter(this);
		itla.setListItems(this.directoryEntries);
		this.setListAdapter(itla);
	}

	// mark
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Log.e("yangw", "short click listview: onListItemClick");
		super.onListItemClick(l, v, position, id);

		String selectedFileString = this.directoryEntries.get(position).getText();

		Log.e("onListItemClick Item named", selectedFileString);

		if (selectedFileString.equals(getString(R.string.current_dir))) {
			// Refresh 刷新
			Log.e("选择Items", "刷新");
			this.EnterFolder(this.currentDirectory);
		} else if (selectedFileString.equals(getString(R.string.up_one_level))) {
			// 到上一阶目录
			Log.e("选择Items", "返回上级");
			this.upOneLevel();
		} else {

			File clickedFile = null;
			switch (this.displayMode) {
				case RELATIVE:
					clickedFile = new File(this.currentDirectory.getAbsolutePath() + "/" + this.directoryEntries.get(position).getText());
					break;
				case ABSOLUTE:
					clickedFile = new File(this.directoryEntries.get(position).getText());
					break;
			}
			if (clickedFile.isDirectory()) {
				Log.e("打开文件夹", clickedFile.getName());
				this.EnterFolder(clickedFile);
			} else {
				Log.e("打开文件", clickedFile.getName());
				openFile(clickedFile);
			}

		}
	}

	// 得到当前目录的绝对路径
	public String GetCurDirectory() {
		return this.currentDirectory.getAbsolutePath();
	}

}



效果如图所示:





代码见附件



  • 大小: 122.6 KB
分享到:
评论

相关推荐

    2011.10.09——— android ImageView放大缩小(2)

    标题中的“2011.10.09——— android ImageView放大缩小(2)”指的是一个关于Android平台中ImageView组件的优化技术,特别是如何处理图片的缩放问题。在Android应用开发中,ImageView是用于显示图像的常见组件,但...

    Android经典项目——AndroidStudio版本.zip

    Android经典项目——AndroidStudio版本.zip。 经典项目——AndroidStudio版本.zip经典项目——AndroidStudio版本.zip Android 经典项目 源码

    微信小程序——人脸检测(截图+源码).zip

    微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip ...

    基于因子分析的我国A股上市...争力评价——以医药企业为例_张澳.caj

    基于因子分析的我国A股上市...争力评价——以医药企业为例_张澳.caj

    微信小程序——新闻客户端(截图+源码).zip

    微信小程序——新闻客户端(截图+源码).zip 微信小程序——新闻客户端(截图+源码).zip 微信小程序——新闻客户端(截图+源码).zip 微信小程序——新闻客户端(截图+源码).zip 微信小程序——新闻客户端(截图+...

    嵌入式成品项目-无线接收时钟.zip

    嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟...

    python项目——Word助手.zip

    python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目...

    微信小程序——移动端商城(截图+源码).zip

    微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+...

    微信小程序——图书管理系统(截图+源码).zip

    微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理...

    微信小程序——手势解锁(截图+源码).zip

    微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip ...

    数据库大作业-学校人事信息管理系统.zip

    数据库大作业——学校人事信息管理系统.zip数据库大作业——学校人事信息管理系统.zip数据库大作业——学校人事信息管理系统.zip数据库大作业——学校人事信息管理系统.zip数据库大作业——学校人事信息管理系统.zip...

    微信小程序——全屏动画滚动(截图+源码).zip

    微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画...

    C语言项目——MP3音乐播放器.zip

    C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——...

    python项目——DIY字符画.zip

    python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip ...

    微信小程序——图片自适应 ,富文本解析(截图+源码).zip

    微信小程序——图片自适应 ,富文本解析(截图+源码).zip 微信小程序——图片自适应 ,富文本解析(截图+源码).zip 微信小程序——图片自适应 ,富文本解析(截图+源码).zip 微信小程序——图片自适应 ,富文本...

    微信小程序——小游戏-别踩白块(截图+源码).zip

    微信小程序——小游戏-别踩白块(截图+源码).zip 微信小程序——小游戏-别踩白块(截图+源码).zip 微信小程序——小游戏-别踩白块(截图+源码).zip 微信小程序——小游戏-别踩白块(截图+源码).zip 微信小程序...

    java毕业设计——基于ssm的房屋租赁系统设计与实现(源码+数据库).zip

    java毕业设计——基于ssm的房屋租赁系统设计与实现(源码+数据库).zip java毕业设计——基于ssm的房屋租赁系统设计与实现(源码+数据库).zip java毕业设计——基于ssm的房屋租赁系统设计与实现(源码+数据库).zip java...

    java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip

    java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip ...

Global site tag (gtag.js) - Google Analytics