Demo下载链接:https://download.csdn.net/download/a8856621/10911209

一、  首先实现android原生的录音功能,这里使用Android的Service服务,可保证unity切换到后台仍然录音。我将上传录音文件时所需要附带的信息全部保存在文件名中,这样即使上传文件的过程因为退出程序而导致本次上传失败,在下次进入程序后,可以通过读取文件名来获取相应的信息,再次上传服务器。


/*** 录音的 Service** */public class RecordingService extends Service {private static final String LOG_TAG = "RecordingService";//录音开始时间private String startTime=null;  //录音结束时间  private String endTime=null;//文件保存路径public String mFilePath = null;private MediaRecorder mRecorder = null;private TimerTask mIncrementTimerTask = null;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {startTime=intent.getStringExtra("startTime");saleID=intent.getStringExtra("saleID");startRecording();return START_STICKY;}@Overridepublic void onDestroy() {if (mRecorder != null) {//Toast.makeText(getApplicationContext(), "结束录音", Toast.LENGTH_LONG).show();stopRecording();}super.onDestroy();}public void startRecording() {mFilePath= Tools.getAudioFilePath()+"/"+System.currentTimeMillis() + ".aac";mRecorder = new MediaRecorder();mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);mRecorder.setOutputFile(mFilePath);mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//保存成aac格式mRecorder.setAudioChannels(1);//录音通道数mRecorder.setAudioSamplingRate(8000);//录音质量 8000即可,可减少产生文件的大小mRecorder.setAudioEncodingBitRate(192000);try {mRecorder.prepare();mRecorder.start();} catch (IOException e) {Log.e(LOG_TAG, "prepare() failed");}}public void stopRecording() {if(mRecorder!=null){try {endTime=Tools.DateFormat("yyyy-MM-dd HH:mm:ss");mRecorder.stop();mRecorder.release();mRecorder = null;//修改文件名,并将文件路径广播出去String fileName=Tools.getAudioFilePath()+"/"+saleID+"_"+startTime+"_"+endTime+"_video"+".aac";File file=new File(mFilePath);file.renameTo(new File(fileName));//发送广播Intent intent=new Intent();intent.putExtra("filePath", fileName);intent.setAction("com.ideepwise.zhztbusiness.RecordingService");sendBroadcast(intent);} catch (IllegalStateException e) {// TODO 如果当前java状态和jni里面的状态不一致,//e.printStackTrace();mRecorder = null;mRecorder = new MediaRecorder();}if (mIncrementTimerTask != null) {mIncrementTimerTask.cancel();mIncrementTimerTask = null;}}}}

二、在MainActivity界面添加服务侦听,用来处理文件的读取和上传功能

三、记得在Android配置文件中配置相应的权限和Service服务

<service android:name=".RecordingService"
             android:enabled="true"
             android:exported="true"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />

public class MainActivity extends UnityPlayerActivity {public static final int GET_OK = 1,GET_ERROR = 2;private MyReceiver receiver=null;private  boolean isRecording=false;private String postURL=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//注册广播接收器receiver=new MyReceiver();IntentFilter filter=new IntentFilter();filter.addAction("com.ideepwise.zhztbusiness.RecordingService");MainActivity.this.registerReceiver(receiver,filter);}@Overrideprotected void onDestroy(){super.onDestroy();}//在Unity端调用,用来检查上传失败的文件,并重新上传(此处我是将文件删除了,你们可自行修改)public void CheckLoaclRecord(){File file=new  File(Tools.getAudioFilePath());if(file.isDirectory()){File[] files= file.listFiles();if(files.length>0){try {for (int i = 0; i < files.length; i++) {files[i].delete();}}catch (Exception e){}}}}//unity端调用开始录音功能,传入需要上传的参数和上传的地址public void StartRecord(String saleID,String postURL){if(isRecording)return;isRecording=true;this.postURL=postURL;String startTime=Tools.DateFormat("yyyy-MM-dd HH:mm:ss");Intent intent = new Intent(MainActivity.this, RecordingService.class);intent.putExtra("saleID",saleID);intent.putExtra("startTime",startTime);startService(intent);}//unity端调用停止露营并上传public void StopRecord(){Intent intent = new Intent(MainActivity.this, RecordingService.class);stopService(intent);}/*** 广播接受录音文件存储完后才能*/public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {isRecording=false;String recordPath=intent.getExtras().getString("filePath");UpdateRecord(recordPath);}}// 使用handler处理接收到的消息private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what ==GET_OK){ShowToast("文件保存成功");deleteRecord(msg.obj.toString());}}};// 显示Toast消息public void ShowToast(final String message){runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();}});}//上传文件public void UpdateRecord(String data){try{String fileName= data.substring(data.lastIndexOf("/")+1);String[] record= fileName.split("_");Map<String, String> map = new HashMap();map.put("salerId", record[0]);map.put("startTime", record[1]);map.put("endTime", record[2]);Map<String, File> mapFile = new HashMap();mapFile.put("file", new File(data));req_multi_form form=new req_multi_form();form.setFileField(mapFile);form.setNormalField(map);form.setAction(postURL);UploadFile(form,data);}catch (Exception e){ShowToast("上传出问题啦");}}/*** android上传文件到服务器** @param form 需要上传的文件* @return 返回响应的内容*/public void UploadFile(final req_multi_form form,final String data){new Thread(){@Overridepublic void run() {super.run();String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成String PREFIX = "--", LINE_END = "\r\n";String CONTENT_TYPE = "multipart/form-data"; // 内容类型Map<String, File> files = form.getFileField();String RequestURL = form.getAction();Map<String, String> param = form.getNormalField();try {URL url = new URL(RequestURL);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(10000);conn.setConnectTimeout(10000);conn.setDoInput(true); // 允许输入流conn.setDoOutput(true); // 允许输出流conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST"); // 请求方式conn.setRequestProperty("Charset", "utf-8"); // 设置编码conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);if (files != null) {/*** 当文件不为空,把文件包装并且上传*/DataOutputStream dos = new DataOutputStream(conn.getOutputStream());StringBuffer sb = new StringBuffer();String params = "";if (param != null && param.size() > 0) {Iterator<String> it = param.keySet().iterator();while (it.hasNext()) {sb = null;sb = new StringBuffer();String key = it.next();String value = param.get(key);sb.append(PREFIX).append(BOUNDARY).append(LINE_END);sb.append("Content-Disposition: form-data; name=\"").append(key).append("\"").append(LINE_END).append(LINE_END);sb.append(value).append(LINE_END);params = sb.toString();dos.write(params.getBytes());// dos.flush();}}/*** 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件* filename是文件的名字,包含后缀名的 比如:abc.png*/if( files != null && files.size() > 0){Iterator<String> it = files.keySet().iterator();while (it.hasNext()){sb = new StringBuffer();sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINE_END);String key = it.next();File file = files.get(key);sb.append("Content-Disposition: form-data; name=\""+key+"\";filename=\"" + file.getName() + "\"" + LINE_END);if (file.getName().contains("mp4")) {sb.append("Content-Type: video/mpeg4; charset=" + "utf-8" + LINE_END);}sb.append(LINE_END);dos.write(sb.toString().getBytes());InputStream is = new FileInputStream(file);byte[] bytes = new byte[1024];int len = 0;while ((len = is.read(bytes)) != -1) {dos.write(bytes, 0, len);}is.close();dos.write(LINE_END.getBytes());}}byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();dos.write(end_data);dos.flush();/*** 获取响应码 200=成功 当响应成功,获取响应的流*/int res = conn.getResponseCode();if (res == 200) {Message msg = new Message();msg.what = GET_OK;msg.obj=data;mHandler.sendMessage(msg);} else {mHandler.sendEmptyMessage(GET_ERROR);}}} catch (MalformedURLException e) {e.printStackTrace();mHandler.sendEmptyMessage(GET_ERROR);} catch (IOException e) {e.printStackTrace();mHandler.sendEmptyMessage(GET_ERROR);}}}.start();}private void deleteRecord(String filePath) {if(filePath!=null&&filePath!="") {File file = new File(filePath);// 路径为文件且不为空则进行删除if (file.isFile() && file.exists()) {file.delete();}}}

unity集成android原生录音(可后台)并实现上传相关推荐

  1. uniapp android原生,在uni-app项目中集成Android原生工程

    [TOC] # 在uni-app项目中集成Android原生工程 按照官方的方案,我们如果进行本地打包的话,需要重新创建一个Android原生工程,于是就会导致我们管理多个项目,切来切去的也麻烦. 经 ...

  2. (0081)iOS开发之无限后台定位并上传数据到服务器

    关键词:ios 后台持续定位 iOS 后台的理解 // http://blog.csdn.net/u013773524/article/details/52153917 // http://blog. ...

  3. Android 本地tomcat服务器接收处理手机上传的数据之案例演示

    上一篇:Android 本地tomcat服务器接收处理手机上传的数据之环境搭建     本篇基于上一篇搭建的服务器端环境,具体介绍Android真机上传数据到tomcat服务器的交互过程   场景:A ...

  4. 后台接收datetime_input上传date日期时间数据到后台报400怎么办?

    前端上传日期时间数据到后台时,上传失败 我这里是用里存放时间,上传到后台的controller方法时,参数类型是java.util.Date,发现没有到controller方法里面.报错:不能将Str ...

  5. android com.mylhyl,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. photopicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  6. Spring Boot项目集成AWS SDK连接到AWS S3,实现上传下载功能

    本文主要描写在Spring Boot项目里集成AWS SDK连接到AWS S3,实现上传下载功能的具体代码和注意事项.如有不足和错误之处,欢迎指正. AWS S3相关介绍 AWS S3(官网): ht ...

  7. android 微信高仿,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  8. SSM整合之企业级后台管理系统(18) - 上传头像前端部分

    前面一篇博客<SSM整合之企业级后台管理系统(17) - 上传头像后端部分>介绍了上传头像实现的思路和后端代码,由于篇幅原因呢,把前后端分开介绍. 所以,这篇博客我们来学习一下上传头像的前 ...

  9. android一键发布,Android apk项目如何一键打包并上传到蒲公英

    Android apk项目如何一键打包并上传到蒲公英 发布时间:2020-07-18 15:13:44 来源:亿速云 阅读:107 作者:小猪 这篇文章主要为大家展示了Android apk项目如何一 ...

最新文章

  1. linux异机拷贝,rman恢复异机数据库
  2. iOS 去除导航栏下的黑线
  3. Docker介绍与安装使用(一)
  4. Linux minicom串口通讯
  5. 计算机能力提升研修总结ppt,信息技术能力提升研修总结
  6. 通过jQuery给select元素的option标签添加自定义属性
  7. gradle命令无法识别
  8. Java推断文本文件编码格式以及读取
  9. 记一次线上Zabbix对Redis监控实录
  10. Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (高级)
  11. 《计算机科学导论》学习笔记
  12. 电子元器件简介——电容与电感篇
  13. 分位数回归 Quantile Regression,python 代码
  14. php制作国旗头像图片,不要再@微信官方了,自己动手一秒制作国旗头像
  15. 计算机无法访问指定设备路径或文件怎么回事,window无法访问指定设备 路径或文件是怎么回事...
  16. java基础--狂神
  17. 从一个商业产品设计学习oCPC核心知识点
  18. Android蓝牙搜索连接通信
  19. 软件的创新:分析网易云音乐的成功创新
  20. 外观模式:书生的家书是谁送的?书童到底是个什么角色?

热门文章

  1. python系列教程-python前世今生以及windows下环境的安装
  2. 文件权限管理 -- u+s、g+s、o+t/三种用户权限
  3. 解决mac item2 sz rz命令失效问题
  4. 江西省餐饮油烟治理在线监测平台的研究与应用 油烟监测系统 油烟监测云平台 (安科瑞-须静燕)
  5. 【回炉再造】C++学习笔记(一)
  6. 企业微信常见问题及使用技巧
  7. Android AOSP VTS环境搭建
  8. 一文一点 | 康威定律和单一职责原则的关系
  9. 基于卷积神经网络VGG实现水果分类识别
  10. 如何安装torch_geometric?