android 上传 音频

2014-08-08 17:29:14 b275518834 阅读数 9101

下载地址:http://download.csdn.net/detail/b275518834/7731671
工程编码:GBK
调通需要设置 RecordDialog类中的参数---
服务器上传地址 uploadServerUrl
服务器下载播放地址 downloadServerUrl---
FileHelper 文件下载工具类
OnStateListener 接口-状态回调
RecordDialog 录音对话框
RecordManger 录音功能类
TalkNetManager 网络会话对话框
UploadUtil 文件上传工具类

效果图:客服端


录音上传核心代码

package com.im.util;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.SoundPool;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.format.DateFormat;

public class TalkNetManager {
	/** 录音管理类 */
	private RecordManger recordManger = new RecordManger();
	private Context context;
	/** 下载文件服务器地址 */
	private String downloadFileServerUrl;
	/** 下载文件服务器地址 */
	private String uploadFileServerUrl;

	private OnStateListener uploadFileStateListener;
	private OnStateListener downloadFileFileStateListener;

	/** 启动录音不进行网络上传 */
	public void startRecord() {
		try {
			recordManger.startRecordCreateFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/** 停止录音 */
	public File stopRecord() {
		return recordManger.stopRecord();// 停止录音
	}

	/** 停止录音后上传 */
	public File stopRecordAndUpload() {
		File file = recordManger.stopRecord();// 停止录音
		if (file == null || !file.exists() || file.length() == 0) {
			if (uploadFileStateListener != null)
				uploadFileStateListener.onState(-1, "文件不存在或已经损坏");
			return null;
		}

		new UpLoadecordFile().execute();// 调用异步任务
		return recordManger.getFile();
	}

	/** 异步任务-录音上传 */
	public class UpLoadecordFile extends AsyncTask<String, Integer, String> {

		@Override
		protected String doInBackground(String... parameters) {
			// TODO Auto-generated method stub11
			return UploadUtil.uploadFile(recordManger.getFile(),
					uploadFileServerUrl);

		}

		@Override
		protected void onPostExecute(String result) {
			if (result == null) {
				if (uploadFileStateListener != null)
					uploadFileStateListener.onState(-2, "上传文件失败");
				return;
			}

			if (result != null)
				if (uploadFileStateListener != null)
					uploadFileStateListener.onState(0, "上传文件成功");
		}

	}

	/** 下载后播放 */
	public void downloadFileAndPlay(String uploadFilename) {
		new DownloadRecordFile().execute(uploadFilename);
	}

	/** 异步任务-下载后播放 */
	public class DownloadRecordFile extends AsyncTask<String, Integer, File> {

		@Override
		protected File doInBackground(String... parameters) {
			// TODO Auto-generated method stub11
			try {
				String filename = new DateFormat().format("yyyyMMdd_HHmmss",
						Calendar.getInstance(Locale.CHINA)) + ".amr";
				return FileHelper.DownloadFromUrlToData(downloadFileServerUrl
						+ parameters[0], filename, context);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;

		}

		@Override
		protected void onPostExecute(File result) {

			if (result == null || !result.exists() || result.length() == 0) {
				if (downloadFileFileStateListener != null) {
					downloadFileFileStateListener.onState(-1, "下载文件失败");
					return;
				}
			}
			MediaPlayer mediaPlayer = new MediaPlayer();
			mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

				@Override
				public void onCompletion(MediaPlayer mediaPlayer) {
					// TODO Auto-generated method stub
					mediaPlayer.release();
				}
			});
			try {
				mediaPlayer.setDataSource(result.getPath());
				mediaPlayer.prepare();
				mediaPlayer.start();
				if (downloadFileFileStateListener != null) {
					downloadFileFileStateListener.onState(0, "成功");
					return;
				}

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

	public RecordManger getRecordManger() {
		return recordManger;
	}

	public void setRecordManger(RecordManger recordManger) {
		this.recordManger = recordManger;
	}

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	public void setDownloadFileServerUrl(String downloadFileServerUrl) {
		this.downloadFileServerUrl = downloadFileServerUrl;
	}

	public String getUploadFileServerUrl() {
		return uploadFileServerUrl;
	}

	public void setUploadFileServerUrl(String uploadFileServerUrl) {
		this.uploadFileServerUrl = uploadFileServerUrl;
	}

	public OnStateListener getUploadFileStateListener() {
		return uploadFileStateListener;
	}

	public void setUploadFileStateListener(
			OnStateListener uploadFileStateListener) {
		this.uploadFileStateListener = uploadFileStateListener;
	}

	public OnStateListener getDownloadFileFileStateListener() {
		return downloadFileFileStateListener;
	}

	public void setDownloadFileFileStateListener(
			OnStateListener downloadFileFileStateListener) {
		this.downloadFileFileStateListener = downloadFileFileStateListener;
	}

	public String getDownloadFileServerUrl() {
		return downloadFileServerUrl;
	}
}




服务器端







服务器端上传代码

package com.project3gabs.action;



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet
{
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException
	{
		
		System.out.println("服务器发现上传文件");
		

		request.setCharacterEncoding("UTF-8");
		
		if(request.getHeader("user-agent")!=null&&(request.getHeader("user-agent").toLowerCase().indexOf("mozilla")!=-1)) 
		{ 
			System.out.println("访问端-PC");
		}else 
		{ 
			System.out.println("访问端-手机");
		
		}

		
		
//		try {
//			request.setCharacterEncoding("UTF-8"); // 设置处理请求参数的编码格式
//			response.setContentType("text/html;charset=UTF-8"); // 设置Content-Type字段值
//			PrintWriter out = response.getWriter();
//			System.out.println("附加信息"+URLEncoder.encode(request.getParameter("msg"),"UTF-8"));
//
//		} catch (Exception e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
		try
		{
			
			
			// 下面的代码开始使用Commons-UploadFile组件处理上传的文件数据
			FileItemFactory factory = new DiskFileItemFactory(); // 建立FileItemFactory对象
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 分析请求,并得到上传文件的FileItem对象
			List<FileItem> items = upload.parseRequest(request);
			// 从web.xml文件中的参数中得到上传文件的路径
			String uploadPath = this.getServletContext().getRealPath("/")+"\\uploadfile\\";
			
			System.out.println(uploadPath);
			
			File file = new File(uploadPath);
			if (!file.exists())
			{
				file.mkdir();
			}
			String filename = null; // 上传文件保存到服务器的文件名
			InputStream is = null; // 当前上传文件的InputStream对象
			// 循环处理上传文件
			
		
			
			for (FileItem item : items)
			{
				
				// 处理普通的表单域
				if (item.isFormField())
				{
					try {
						System.out.println(item.getFieldName()+item.getString());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if (item.getFieldName().equals("filename"))
					{
						// 如果新文件不为空,将其保存在filename中
						if (!item.getString().equals(""))
							filename = item.getString("UTF-8");
						System.out.println("filename="+filename.replace("\\\\", "\\"));
					}

					
				}
				// 处理上传文件
				else if (item.getName() != null && !item.getName().equals(""))
				{
					// 从客户端发送过来的上传文件路径中截取文件名
					filename = item.getName().substring(
							item.getName().lastIndexOf("\\") + 1);
					
					is = item.getInputStream(); // 得到上传文件的InputStream对象
				
				}
			}
			// 将路径和上传文件名组合成完整的服务端路径
			filename = uploadPath + filename;
			System.out.println("filename="+filename);
			// 如果服务器已经存在和上传文件同名的文件,则输出提示信息
			if (new File(filename).exists())
			{
				new File(filename).delete();
			}
			// 开始上传文件
			if (!filename.equals(""))
			{
				// 用FileOutputStream打开服务端的上传文件
				FileOutputStream fos = new FileOutputStream(filename);
				byte[] buffer = new byte[8192]; // 每次读8K字节
				int count = 0;
				// 开始读取上传文件的字节,并将其输出到服务端的上传文件输出流中
				while ((count = is.read(buffer)) > 0)
				{
					fos.write(buffer, 0, count); // 向服务端文件写入字节流
					
				}
				fos.close(); // 关闭FileOutputStream对象
				is.close(); // InputStream对象
				
				System.out.println("文件上传成功!");
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}


服务器端下载代码

package com.project3gabs.action;


import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;

public class DownloadFile extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");
		javax.servlet.ServletOutputStream out = response.getOutputStream();
		String filepath = request.getRealPath("/") + "uploadfile/";
		String filename = new String(request.getParameter("filename").getBytes(
				"ISO8859-1"), "UTF-8").toString();
		//String filename = java.net.URLDecoder.decode(request.getParameter("filename"));
		System.out.println("DownloadFile filepath:" + filepath);
		System.out.println("DownloadFile filename:" + filename);
		java.io.File file = new java.io.File(filepath + filename);
		if (!file.exists()) {
			System.out.println(file.getAbsolutePath() + " 文件不存在!");
			return;
		}
		// 读取文件流
		java.io.FileInputStream fileInputStream = new java.io.FileInputStream(
				file);
		// 下载文件
		// 设置响应头和下载保存的文件名
		if (filename != null && filename.length() > 0) {
			response.setContentType("application/x-msdownload");
			response
					.setHeader("Content-Disposition", "attachment; filename="
							+ new String(filename.getBytes("gb2312"),
									"iso8859-1") + "");
			if (fileInputStream != null) {
				int filelen = fileInputStream.available();
				// 文件太大时内存不能一次读出,要循环
				byte a[] = new byte[filelen];
				fileInputStream.read(a);
				out.write(a);
			}
			fileInputStream.close();
			out.close();
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out
				.println("<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>");
		out.println("<HTML>");
		out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println(" <BODY>");
		out.print(" This is ");
		out.print(this.getClass().getName());
		out.println(", using the POST method");
		out.println(" </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
}


下载地址:http://download.csdn.net/detail/b275518834/7731671











2015-04-27 16:21:09 wlaizff 阅读数 2240

关于android上传图片,视频,音频到rails后台服务器


android客户端实现图片,视频,音频采集

我在项目中主要是调用系统接口,获取图片,拍照,录像,录制音频时使用MediaRecorder进行录制。

获取相册图片

调用系统相册:

Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT"
galleryIntent.setType("image/*"); 
//查看类型 String IMAGE_UNSPECIFIED = "image/*" ;
Intent wrapperGalleryIntent = Intent.createChooser(galleryIntent, null);
startActivityForResult(wrapperGalleryIntent, REQUEST_CODE_TAKE_GALLERY); 

拍照

调用系统相机拍照:

if (isHasSdcard()) 
{
//指定输出的文件
uploadGalleryFile = new File(file, imagePrefix + format.format(new Date()) + ".jpg");
}
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //"android.media.action.IMAGE_CAPTURE";
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(uploadGalleryFile));
startActivityForResult(cameraIntent, REQUEST_CODE_TAKE_CAMERA);

录像

调用系统相机录像:

if (isHasSdcard()) 
{
uploadVideoFile = new File(file, videoPrefix + format.format(new Date()) + ".3gp");
}
Intent videoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
videoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(uploadVideoFile));
startActivityForResult(videoIntent, REQUEST_CODE_TAKE_VIDEO);

录制音频

使用MediaRecorder录制音频:

private void startRecord() {
        if (hasSdcard()) {
            sdcardPath = new File(dir);
            try {
                recordPath = File.createTempFile(prefix, ".amr", sdcardPath); //三个参数分别为前缀、后缀、目录
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(activity, "未找到存储卡,无法存储", Toast.LENGTH_SHORT).show();
            return;
        }
        initRecorder();
        try {
            recorder.prepare();
            recorder.start();
            stateView.setText("正在录音...");
            btnStartRecord.setVisibility(View.GONE);
            btnStopRecord.setVisibility(View.VISIBLE);
            btnPlayRecord.setVisibility(View.GONE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        btnStartRecord.setClickable(false);
        btnPlayRecord.setClickable(false);
        btnStopRecord.setClickable(true);
    }

将图片等文件上传

  • 这里提供一个根据uri找到指定文件的方法
    点击查看
  • 使用AsyncHttpClient请求将文件上传到服务器
    //    /*
    //    * 上传文件
    //    */
    @SuppressLint("ShowToast")
    public void upload(File file, Integer type) {
        RequestParams params = new RequestParams();
        try {
            params.put("doctor_id", UserInfo.user.getDoctor_id().toString());
            params.put("suffer_id", patientInfo.getId().toString());
            params.put("resource_type", type.toString());
            params.put("resource_size", UsedTools.generateFileSize(file));
            params.put("resource_category", category);
            params.put("resource_url", file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String url = Configuration.newResourceUrl;
        AsyncHttpClient client = new AsyncHttpClient();
        client.post(url, params, new JsonHttpResponseHandler() {
            @SuppressLint("ShowToast")
            @Override
            public void onSuccess(JSONObject response) {
                try {
                    successResponse = response.get("success").toString();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                if (successResponse.equals("1")) {
                    Toast.makeText(UploadRecord.this, "上传成功", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(UploadRecord.this, "上传失败", Toast.LENGTH_LONG).show();
                }
            }

            @SuppressLint("ShowToast")
            @Override
            public void onFailure(int statusCode, Header[] headers,
                                  byte[] responseBody, Throwable error) {
                Toast.makeText(UploadRecord.this, "网络访问异常,请重试", Toast.LENGTH_LONG).show();

            }
        });
    }

rails后台接收文件

  • 使用rails开发框架,能够加快开发进度,省去很多麻烦。

  • 利用carrierwave插件能够实现图片等文件的上传。具体方法

rails后台如何接收数据

  • 首先,确保carrierwave的相关准备都完成,特别注意要在model中加入一下代码:
mount_uploader :doctor_url, DoctorUrlUploader
  • 然后,在controller中加入方法,实现图片的接收。例如更新用户头像:
#更新用户头像
def update_userPictureUrl
  @user = User.find(params[:doctor_id])
  @user.update_attributes(:doctor_url => params[:doctor_url])
  if @user.save
    doctor_url = @user.doctor_url.url
    json_str = "{'doctor_url':'#{IP}#{doctor_url}'}" #返回用户头像路径
    render json: json_str
  else
    render json: @user.errors
  end
end
  • 视频和音频的处理都可以通过同样的方法接收

总结

app客户端项目地址

rails后台项目地址

参考资料

2015-08-20 21:01:23 wanglj7525 阅读数 2696

实现长按按钮开始录音,结束后在gridview中显示,点击播放。

    @AbIocView(id = R.id.addVoice)
    Button addVoice;
    @AbIocView(id = R.id.addvoicegridview)
    GridView addvoicegridview;
    @AbIocView(id = R.id.horizontalScrollView_addvoice)
    HorizontalScrollView horizontalScrollView_addvoice;
    /** 语音列表适配器 */
    private MyGridAdapter mAdapter;
    /** 语音列表 */
    private ArrayList<String> mVoicesList;
    /** 语音名称列表 */
    private List<String> mVoicesListname;
    /** 录音存储路径 */
    private static final String PATH = "/sdcard/MyVoiceForder/Record/";
    /** 用于语音播放 */
    private MediaPlayer mPlayer = null;
    /** 用于完成录音 */
    private MediaRecorder mRecorder = null;
    /** 语音文件保存路径 */
    private String mFileName = null;
    /** 语音文件显示名称 */
    private String mFileNameShow = null;
    /**
     * 列宽
     */
    private int cWidth = 500;
    /**
     * 水平间距
     */
    private int hSpacing = 10;

    /** 初始化数据 */
    private void initData() {
        mVoicesList = new ArrayList<String>();
        mVoicesListname = new ArrayList<String>();
        mPlayer = new MediaPlayer();
    }
    private void initGridView() {
        MyGridAdapter mAdapter = new MyGridAdapter(context);
        addvoicegridview.setAdapter(mAdapter);
        LayoutParams params = new LayoutParams(mAdapter.getCount()
                * (cWidth + hSpacing), LayoutParams.WRAP_CONTENT);
        addvoicegridview.setLayoutParams(params);
        addvoicegridview.setColumnWidth(cWidth);
        addvoicegridview.setHorizontalSpacing(hSpacing);
        addvoicegridview.setStretchMode(GridView.NO_STRETCH);
        addvoicegridview.setNumColumns(mAdapter.getCount());

        addvoicegridview.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                try {
                    mPlayer.reset();
                    mPlayer.setDataSource(mVoicesList.get(position));
                    mPlayer.prepare();
                    mPlayer.start();
                } catch (IOException e) {
                    Log.e(TAG, "播放失败");
                }
            }
        });
        addvoicegridview
                .setOnItemLongClickListener(new OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> arg0,
                            View arg1, int arg2, long arg3) {
                        mVoicesList.remove(arg2);
                        mVoicesListname.remove(arg2);
                        initGridView();
                        return false;
                    }
                });
    }
private void initUi() {
        horizontalScrollView_addvoice.setHorizontalScrollBarEnabled(true);
        initGridView();

        addVoice.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (commitId.equals("0")) {
                    Toast.makeText(getApplicationContext(), "请先保存上面的信息", 0)
                    .show();
                }else{
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if (mVoicesList.size() >= 1) {
                            Toast.makeText(getApplicationContext(), "只能上传一个录音", 0)
                            .show();
                        } else {
                            startVoice();
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (mVoicesList.size() >= 1) {
                        } else {
                            stopVoice();
                        }
                        break;
                    default:
                        break;
                    }
                }
                return false;
            }
        });

        OnClickListener keyboard_hide = new OnClickListener() {

            @Override
            public void onClick(View v) {
                InputMethodManager imm = (InputMethodManager) AddZhiliangSendActivity.this
                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }

        };
        addxiapai_full.setClickable(true);
        addxiapai_full.setOnClickListener(keyboard_hide);
    }
    /** 开始录音 */
    private void startVoice() {
        // 设置录音保存路径
        mFileNameShow = UUID.randomUUID().toString();
        mFileName = PATH + mFileNameShow + ".amr";
        String state = android.os.Environment.getExternalStorageState();
        if (!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
            Log.i(TAG, "SD Card is not mounted,It is  " + state + ".");
        }
        File directory = new File(mFileName).getParentFile();
        if (!directory.exists() && !directory.mkdirs()) {
            Log.i(TAG, "Path to file could not be created");
        }
        Toast.makeText(getApplicationContext(), "开始录音", 0).show();
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        try {
            mRecorder.prepare();
        } catch (IOException e) {
            Log.e(TAG, "prepare() failed");
        }
        mRecorder.start();
    }

    /** 停止录音 */
    @SuppressLint("NewApi")
    private void stopVoice() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
        mVoicesList.add(mFileName);
        mVoicesListname.add(mFileNameShow);
        mAdapter = new MyGridAdapter(AddZhiliangSendActivity.this);
        addvoicegridview.setAdapter(mAdapter);
        initGridView();
//      new FileHelper().submitUploadFile(mVoicesList, loginKey,commitId,"2");
        Toast.makeText(getApplicationContext(), "保存录音" + mFileName, 0).show();
    }

    class MyGridAdapter extends BaseAdapter {
        Context mContext;
        LayoutInflater mInflater;

        public MyGridAdapter(Context c) {
            mContext = c;
            mInflater = LayoutInflater.from(mContext);
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mVoicesList.size();
        }

        @Override
        public Object getItem(int arg0) {
            // TODO Auto-generated method stub
            return arg0;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return arg0;
        }

        @Override
        public View getView(int position, View contentView, ViewGroup arg2) {
            contentView = mInflater.inflate(R.layout.item_voicelist, null);
            TextView tv = (TextView) contentView.findViewById(R.id.tv_armName);
            tv.setText(mVoicesListname.get(position) + ".amr");
            return contentView;
        }

    }

item_voicelist.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/widget28"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/tv_armName"
        android:layout_width="fill_parent"
        android:layout_height="70dp"
        android:background="@drawable/chat_button_fillet_shape"
        android:gravity="center"
        android:text="123.arm" >

    </TextView>
</RelativeLayout>
<LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >

                <HorizontalScrollView
                    android:id="@+id/horizontalScrollView_addvoice"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:background="#FFFFFF"
                    android:orientation="horizontal" >

                    <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal" >

                        <GridView
                            android:id="@+id/addvoicegridview"
                            android:layout_width="match_parent"
                            android:layout_height="70dp" >
                        </GridView>
                    </LinearLayout>
                </HorizontalScrollView>
            </LinearLayout>
2016-04-07 22:53:14 qq_26296197 阅读数 8951

最近研究了下录音上传,各位有需要可参考下,如有不妥欢迎指出


<pre name="code" class="html">package com.kingtone.www.record;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.UnsupportedEncodingException;
import java.net.Socket;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.kingtone.www.record.util.EnvironmentShare;

/**
 * 本类主要实现 录音至SD卡上,并且可以实现录音的播放
 */
public class Main extends Activity implements OnClickListener {

	// 多媒体播放器
	private MediaPlayer mediaPlayer;
	// 多媒体录制器
	private MediaRecorder mediaRecorder = new MediaRecorder();
	// 音频文件
	private File audioFile;

	// 传给Socket服务器端的上传和下载标志
	private final int UP_LOAD = 1;
	private final int DOWN_LOAD = 2;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获得三个按钮的UI控件
		Button btnStart = (Button) findViewById(R.id.btnStart);
		Button btnStop = (Button) findViewById(R.id.btnStop);
		Button btnPlay = (Button) findViewById(R.id.btnPlay);
		Button btnUpLoad = (Button) findViewById(R.id.btnUpLoad);
		Button btnDownLoad = (Button) findViewById(R.id.btnDownLoad);
		btnStart.setOnClickListener(this);
		btnStop.setOnClickListener(this);
		btnPlay.setOnClickListener(this);
		btnUpLoad.setOnClickListener(this);
		btnDownLoad.setOnClickListener(this);
	}

	@Override
	public void onClick(View view) {
		try {
			String msg = "";
			switch (view.getId()) {
			// 开始录音
			case R.id.btnStart:
				if (!EnvironmentShare.haveSdCard()) {
					Toast.makeText(this, "SD不存在,不正常录音!!", Toast.LENGTH_LONG).show();
				} else {
					// 设置音频来源(一般为麦克风)
					mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
					// 设置音频输出格式(默认的输出格式)
					mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
					// 设置音频编码方式(默认的编码方式)
					mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
					// 创建一个临时的音频输出文件.record_是文件的前缀名 .amr是后缀名
					audioFile = File.createTempFile("record_", ".amr", EnvironmentShare.getAudioRecordDir());
					// audioFile =new
					// File(Environment.getExternalStorageDirectory().getCanonicalPath()+"/sound.amr");
					// 设置录制器的文件保留路径
					mediaRecorder.setOutputFile(audioFile.getAbsolutePath());

					// 准备并且开始启动录制器
					mediaRecorder.prepare();
					mediaRecorder.start();
					msg = "正在录音...";
				}
				break;
			// 停止录音
			case R.id.btnStop:
				if (audioFile != null && audioFile.exists()) {
					// mediaRecorder.stop();
					mediaRecorder.reset();
				}
				msg = "已经停止录音.";
				break;
			// 录音文件的播放
			case R.id.btnPlay:

				if (mediaRecorder != null) {
					// mediaRecorder.stop();
					mediaRecorder.reset();
				}

				if (audioFile != null && audioFile.exists()) {
					Log.i("com.kingtone.www.record", ">>>>>>>>>" + audioFile);
					mediaPlayer = new MediaPlayer();
					// 为播放器设置数据文件
					mediaPlayer.setDataSource(audioFile.getAbsolutePath());
					// 准备并且启动播放器
					mediaPlayer.prepare();
					mediaPlayer.start();
					mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
						@Override
						public void onCompletion(MediaPlayer mp) {
							setTitle("录音播放完毕.");

						}
					});
					msg = "正在播放录音...";
				}
				break;
			// 上传录音文件
			case R.id.btnUpLoad:
				// 开始上传录音文件
				if (audioFile != null) {
					msg = "正在上传录音文件...";
					audioUpLoad();
				}
				break;
			// 下载录音文件
			case R.id.btnDownLoad:
				// 开始下载录音文件
				msg = "正在下载录音文件...";
				downLoadDFile();
				break;
			}
			// 更新标题栏 并用 Toast弹出信息提示用户
			if (!msg.equals("")) {
				setTitle(msg);
				Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
			}
		} catch (Exception e) {
			setTitle(e.getMessage());
		}

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		if (mediaPlayer != null) {
			mediaPlayer.stop();
			mediaPlayer.release();

		}
		if (mediaRecorder != null) {
//			mediaRecorder.reset();
			
			mediaRecorder.release();
			mediaRecorder=null;
		}
	}

	/**
	 * 上传 录音文件
	 */
	private void audioUpLoad() {
		new Thread() {
			public void run() {
				// DataInputStream reader = null;
				// DataOutputStream out = null;
				// Socket socket = null;
				// byte[] buf = null;
				// try {
				// // 连接Socket
				// socket = new Socket("192.168.42.219", 9999);
				// // 1. 读取文件输入流
				// reader = new DataInputStream(new BufferedInputStream(new
				// FileInputStream(audioFile)));
				// // 2. 将文件内容写到Socket的输出流中
				// out = new DataOutputStream(socket.getOutputStream());
				// out.writeInt(UP_LOAD);
				// out.writeUTF(audioFile.getName()); // 附带文件名
				//
				// int bufferSize = 2048; // 2K
				// buf = new byte[bufferSize];
				// int read = 0;
				// // 将文件输入流 循环 读入 Socket的输出流中
				// while ((read = reader.read(buf)) != -1) {
				// out.write(buf, 0, read);
				// }
				// handler.sendEmptyMessage(UPLOAD_SUCCESS);
				// } catch (Exception e) {
				// handler.sendEmptyMessage(UPLOAD_FAIL);
				// } finally {
				// try {
				// // 善后处理
				// buf = null;
				// out.close();
				// reader.close();
				// socket.close();
				// } catch (Exception e) {
				//
				// }
				// }

				// post请求上传
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost post = new HttpPost("http://localhost:8080/action.jsp");
				FileBody fileBody = new FileBody(audioFile);
				try {
					StringBody stringBody = new StringBody("文件的描述");
					MultipartEntity entity = new MultipartEntity();
					entity.addPart("file", fileBody);
					entity.addPart("desc", stringBody);
					post.setEntity(entity);
					HttpResponse response = httpclient.execute(post);
					if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {

						HttpEntity entitys = response.getEntity();
						if (entity != null) {
							System.out.println(entity.getContentLength());
							System.out.println(EntityUtils.toString(entitys));
						}
					}
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ClientProtocolException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				httpclient.getConnectionManager().shutdown();

			};
		}.start();

	}

	/**
	 * 下载录音文件
	 */
	private void downLoadDFile() {
		new Thread() {
			public void run() {
				DataOutputStream writer = null;
				DataOutputStream socketOut = null;

				DataInputStream inPutStream = null;
				Socket socket = null;
				byte[] buf = null;
				try {
					// 连接Socket
					socket = new Socket("192.168.42.219", 9999);
					// 向服务端发送请求及数据
					socketOut = new DataOutputStream(socket.getOutputStream());
					socketOut.writeInt(DOWN_LOAD);
					socketOut.writeUTF(audioFile.getName());

					// 1. 读取Socket的输入流
					inPutStream = new DataInputStream(socket.getInputStream());
					File downLoadFile = new File(
							EnvironmentShare.getDownAudioRecordDir().getAbsolutePath() + "/" + audioFile.getName());
					downLoadFile.createNewFile();
					// File downLoadFile = File.createTempFile( fileName,
					// ".amr", EnvironmentShare.getDownAudioRecordDir());
					// 2. 获得文件的输出流
					writer = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(downLoadFile)));

					int bufferSize = 2048; // 2K
					buf = new byte[bufferSize];
					int read = 0;
					// 将文件输入流 循环 读入 Socket的输出流中
					while ((read = inPutStream.read(buf)) != -1) {
						writer.write(buf, 0, read);
					}
					handler.sendEmptyMessage(DOWNLOAD_SUCCESS);
				} catch (Exception e) {
					handler.sendEmptyMessage(DOWNLOAD_FAIL);
				} finally {
					try {
						// 善后处理
						buf = null;
						inPutStream.close();
						writer.close();
						socket.close();
					} catch (Exception e) {

					}
				}
			};
		}.start();

	}

	// Socket上传下载 结果标志
	private final int UPLOAD_SUCCESS = 1;
	private final int UPLOAD_FAIL = 2;
	private final int DOWNLOAD_SUCCESS = 3;
	private final int DOWNLOAD_FAIL = 4;

	// Socket 上传下载 结果 Handler处理类
	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			String showMessage = "";
			switch (msg.what) {
			case UPLOAD_SUCCESS:
				showMessage = "录音文件上传成功!";
				break;
			case UPLOAD_FAIL:
				showMessage = "录音文件上传失败!";
				break;
			case DOWNLOAD_SUCCESS:
				showMessage = "录音文件下载成功!";
				break;
			case DOWNLOAD_FAIL:
				showMessage = "录音文件下载失败!";
				break;

			default:
				break;
			}
			// 显示提示信息并 设置标题
			EnvironmentShare.showToastAndTitle(Main.this, showMessage, true);
		};
	};

}







package com.kingtone.www.record.util;

import java.io.File;

import android.app.Activity;
import android.os.Environment;
import android.widget.Toast;

/**
 * 
 *
 *  该类为 硬件检测的 公共类
 */
public class EnvironmentShare {
	
	// 存放录音文件夹的名称
	static String AUDIO_RECORD = "/AudioRecord";
	// 存放下载而来的录音文件夹名称
	static String DOWNLOAD_AUDIO_RECORD = "/AudioRecord/downLoad";

	/**
	 *  检测当前设备SD是否可用
	 *  
	 * @return  返回"true"表示可用,否则不可用
	 */
	public static boolean haveSdCard(){
		return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ;
	}
	
	/**
	 *  获得SD卡根目录路径 
	 *  
	 * @return String类型  SD卡根目录路径
	 */
	public static String getSdCardAbsolutePath(){
			return Environment.getExternalStorageDirectory().getAbsolutePath();
	}
	
	/**
	 * 获得存储 录音文件的文件夹
	 * 
	 * @return File类型 
	 * 存储 录音文件的文件夹 .AUDIO_RECORD是一个文件夹
	 */
	public static File getAudioRecordDir(){
		//把String再转换为一个file对象
		File audioRecordFile = new File(EnvironmentShare.getSdCardAbsolutePath() + AUDIO_RECORD);
		if (!audioRecordFile.exists()) {
			// 此处可能会创建失败,暂不考虑
			audioRecordFile.mkdir();
		}
		return audioRecordFile;
	}
	
	/**
	 * 获得存储 下载而来的录音文件的文件夹
	 * 
	 * @return File类型     
	 *         存储 下载而来的 录音文件的文件夹
	 */
	public static File getDownAudioRecordDir(){
		File audioRecordFile = new File(EnvironmentShare.getSdCardAbsolutePath() + DOWNLOAD_AUDIO_RECORD);
		if (!audioRecordFile.exists()) {
			// 此处可能会创建失败,暂不考虑
			audioRecordFile.mkdir();
		}
		return audioRecordFile;
	}
	
	/**
	 *  用Toast显示指定信息
	 * 
	 * @param activity   Activity类型       要显示提示信息的页面上下文
	 * @param message    String类型            将显示的提示信息内容
	 * @param isLong     boolean类型         如果为"true"表示长时间显示,否则为短时间显示
	 */
	public static void showToast(Activity activity,String message,boolean isLong){
		if (message == null ||message.equals("")) 
			return ;
		int showTime = Toast.LENGTH_SHORT;
		if (isLong) {
			showTime = Toast.LENGTH_LONG;
		}
		
		Toast.makeText(activity, message, showTime).show();
	}
	
	
	/**
	 *  用Toast显示指定信息 并设置标题显示 信息
	 * 
	 * @param activity   Activity类型       要显示提示信息的页面上下文
	 * @param message    String类型            将显示的提示信息内容
	 * @param isLong     boolean类型         如果为"true"表示长时间显示,否则为短时间显示
	 */
	public static void showToastAndTitle(Activity activity,String message,boolean isLong){
		activity.setTitle(message);
		showToast(activity, message, isLong);
	}
	
}



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.titletest.MainActivity" >

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    <Button
        android:id="@+id/btn1"
        android:layout_marginTop="15dp"
        android:layout_below="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    
    

</RelativeLayout>