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

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;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startTime=intent.getStringExtra("startTime");
        saleID=intent.getStringExtra("saleID");
        startRecording();
        return START_STICKY;
    }

    @Override
    public 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;
    @Override
    protected 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);

    }

    @Override
    protected 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 {
        @Override
        public void onReceive(Context context, Intent intent) {
            isRecording=false;
            String recordPath=intent.getExtras().getString("filePath");
            UpdateRecord(recordPath);
        }
    }
    // 使用handler处理接收到的消息
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what ==GET_OK)
            {
                ShowToast("文件保存成功");
                deleteRecord(msg.obj.toString());
            }
        }
    };


    // 显示Toast消息
        public void ShowToast(final String message){
            runOnUiThread(new Runnable() {
                @Override
                public 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(){
            @Override
            public 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();
            }
        }
    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值