团队-手机便签-开发文档
项目托管平台地址:https://github.com/Vcandoit/Notepad.git
由于我们是团队的开发,我们写完直接就把代码发给队员了,我们有人负责的代码的合并,所以我们直接把代码进行合并去处理了
所以我就没写自己的托管平台,我们团队都发布在一个人的托管平台中了。
我负责的是录音功能木块的开发,
首先,我先设计了一下录音ui把需要的什么的编写搭建完成
下面我说一下用法:
首先我们点击按住说话,注意说话的时间要超过三秒,因为我在程序中进行了判断,低于三秒的语音我们不进行保存,会提示你录音失败,
然后当你按下按住说话的按钮后,你会发现字变成正在录音的字,那么你就可以进行录制了,当你录制完成后会提示你录音成功,多少秒。
最后点击播放按钮你就可以听到你的录音了。
开发功能实现过程:
首先我要对权限进行获取,添加麦克风的权限,6.0以上的版本要使用程序获得麦克风的使用权限
然后我进行录音机的编写,首先我要对音频进行获取,然后将录取的音频文件保存到本地的私有目录中,然后点击播放按钮在从私有目录中获取音频文件进行播放。
package com.example.apple.tuandui; import android.Manifest;import android.content.Intent;import android.content.pm.PackageManager;import android.media.MediaPlayer;import android.media.MediaRecorder;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.ImageButton;import android.widget.TextView;import android.widget.Toast;import java.io.File;import java.io.IOException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick; /** * Created by Apple on 2017/10/25. */ public class RadioActivity extends AppCompatActivity { @BindView(R.id.anjian_btn) Button anjian_btn; @BindView(R.id.text) TextView text; //多线程后台处理 private ExecutorService mExecutorService; private MediaRecorder mMediaRecorder; private File mAudioFile; private long mStartRecordTime, mStopRecordTime; private Handler mMainThreadHandler;//主线程 //主线程和后台播放线程数据同步 private volatile boolean mIsPlaying; private MediaPlayer mMediaPlayer; private ImageButton back_btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_radio); back_btn = (ImageButton)findViewById(R.id.fanhui); if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1); } ButterKnife.bind(this); //录音jni函数不具备线程安全性,所以调用单线程 mExecutorService = Executors.newSingleThreadExecutor(); mMainThreadHandler = new Handler(Looper.getMainLooper()); //按下说话,释放发送所以我们不要onClickListener anjian_btn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { //根据不同的touch action,执行不同的逻辑 switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: startRecord(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: stopRecord(); break; default: break; } //处理了touch事件,返回true return true; } }); } //利用butterknife简化代码 @OnClick(R.id.play_btn) public void play(){ //检查当前状态,防止重复播放 if(mAudioFile!=null&&!mIsPlaying){ //设置当前播放状态 mIsPlaying = true; //提交后台任务,开始播放 mExecutorService.submit(new Runnable() { @Override public void run() { doPlay(mAudioFile); } }); } } @Override protected void onDestroy() { super.onDestroy(); //activity销毁时,停止后台任务,避免内存泄漏 mExecutorService.shutdownNow(); releaseRecorder(); stopPlay(); } /*** * * 开始录音 */ private void startRecord() { //改变UI状态 anjian_btn.setText("正在说话"); //anjian_btn.setBackgroundResource(); //提交后台任务,执行录音逻辑 mExecutorService.submit(new Runnable() { @Override public void run() { //释放之前录音的MediaRecorder releaseRecorder(); //执行录音逻辑,如果失败提示用户 if (!doStart()) { recordFail(); } } }); } /*** * * 停止录音 */ private void stopRecord() { //改变UI状态 anjian_btn.setText("按住说话"); //anjian_btn.setBackgroundResource(); //提交后台任务,执行停止逻辑 mExecutorService.submit(new Runnable() { @Override public void run() { //执行停止录音逻辑,失败需要提醒用户 if (!doStop()) { recordFail(); } //释放MediaRecorder releaseRecorder(); } }); } /** * 启动录音逻辑 */ private boolean doStart() { try { //创建MediaRecorder mMediaRecorder = new MediaRecorder(); //创建录音文件 //获取绝对路径 mAudioFile = new File(getExternalFilesDir(null).getAbsolutePath() + "/liuming/" + System.currentTimeMillis() + ".m4a"); // mAudioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +alStorageDirectory().getAbsolutePath() +// "/liuming/" + System.currentTimeMillis() + ".m4a"); mAudioFile.getParentFile().mkdirs(); mAudioFile.createNewFile(); //配置MediaRecorder //(1)//从麦克风采集 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //(2)保存文件为MP4格式 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); //(3)所有android系统都支持的采样频率 mMediaRecorder.setAudioSamplingRate(44100); //通用的AAC编码格式 mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //音质比较好的一个频率 mMediaRecorder.setAudioEncodingBitRate(96000); //设为文件保存位置 mMediaRecorder.setOutputFile(mAudioFile.getAbsolutePath()); //开始录音 mMediaRecorder.prepare();//准备 mMediaRecorder.start();//开始 //记录开始录音的时间,用于统计时长 mStartRecordTime = System.currentTimeMillis(); } catch (IOException | RuntimeException e) { e.printStackTrace(); //捕获异常,避免闪退,返回false提醒用户失败 return false; } //录音成功 return true; } /** * 停止录音逻辑 */ private boolean doStop() { try { //停止录音 mMediaRecorder.stop(); //记录停止时间,统计时长 mStopRecordTime = System.currentTimeMillis(); //只接受超过三秒的录音,在ui上显示出来 final int second = (int) ((mStopRecordTime - mStartRecordTime) / 1000); if (second > 3) { //text.setText(text.getText() + "\n录音成功" + second + "秒"); //在主线程改ui,显示出来 mMainThreadHandler. post(new Runnable() { @Override public void run() { text.setText(text.getText()+"\n录音成功"+second+"秒"); } }); } } catch (RuntimeException e) { e.printStackTrace(); //捕获异常,避免闪退,返回false提醒用户失败 return false; } //停止成功 return true; } /** * 释放MediaRecorder */ private void releaseRecorder() { //检查MediaRecorder不为null, if (mMediaRecorder != null) { mMediaRecorder.release(); mMediaRecorder = null; } } /** * 录音错误处理 */ private void recordFail() { mAudioFile = null; //给用户Toast提示失败,要在主线程执行 mMainThreadHandler.post(new Runnable() { @Override public void run() { Toast.makeText(RadioActivity.this, "录音失败", Toast.LENGTH_SHORT).show(); } }); } /** * 实现播放逻辑 * @param audioFile */ private void doPlay(File audioFile) { //配置播放器MediaPlayer mMediaPlayer = new MediaPlayer(); try { //设置声音文件 mMediaPlayer.setDataSource(audioFile.getAbsolutePath()); //设置监听回调。 mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { //播放结束,释放播放器 stopPlay(); } }); mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { //提示用户 playFail(); //释放播放器 stopPlay(); //错误已经处理,返回true return true; } }); //设置音量,是否循环 mMediaPlayer.setVolume(1,1);//,1,1左右声道 mMediaPlayer.setLooping(false);//不需要重复播放 // 准备,开始 mMediaPlayer.prepare(); mMediaPlayer.start(); }catch (RuntimeException | IOException e){ //异常处理,防止闪退 e.printStackTrace(); //提醒用户 playFail(); //释放播放器 stopPlay(); } } /** * * 停止播放逻辑 */ private void stopPlay() { //重置播放状态 mIsPlaying = false; //释放播放器 if(mMediaPlayer!=null){ //设置监听器,防止内存泄漏 mMediaPlayer.setOnCompletionListener(null); mMediaPlayer.setOnErrorListener(null); mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; } } /** * *提醒用户播放失败 */ private void playFail() { //在主线程Toast提示用户失败 mMainThreadHandler.post(new Runnable() { @Override public void run() { Toast.makeText(RadioActivity.this,"播放失败",Toast.LENGTH_LONG).show(); } }); } public void back(View view){ startActivity(new Intent(this,MainActivity.class)); } }
转载于:https://www.cnblogs.com/liuming123/p/7765679.html
团队-手机便签-开发文档相关推荐
- github java排课系统_团队-排课系统-开发文档
项目GitHub地址:https://github.com/hkbdegithub/paike 主要开发前台界面,以及其它部分相关内容 供他人维护类名: class Mainwindow//主窗口 { ...
- 《团队-排课软件-开发文档》
项目GitHub地址:https://github.com/hkbdegithub/paike 前台界面设计及优化,部分后台功能. 转载于:https://www.cnblogs.com/degc/p ...
- vs 如何将源文件转换成可执行文件_如何将手机便签转换成word文本文档
如何将手机便签转换成word文本文档?实际上,很多手机自带的便签,虽然可以将单条便签内容,以文字或者图片的形式分享到xxx云文档,但却很少有支持直接转换成Word文档的.一般情况下,他们需要将手机便签 ...
- 手机淘宝商品详情API接口开发文档
应用场景: 通过该手机淘宝商品详情API接口开发文档可绕过登录滑块获取获标题.价格.SKU.主图.店铺名称等信息,方便电商平台.系统使用. 应用框架: 采用负载均衡的架构,提供手机淘宝商品详情API接 ...
- autojs 开发文档集合
加入我们的QQ群553908361,和各作者同群交流 教程会优先发布于收费脚本v群. 该代码选自于aj开发者的文档,群里有人反馈开发文档打开慢.所以做了这个.方便搜索.如有侵权,请私信我进行删除 同时 ...
- 社区疫情管理信息系统开发文档
此为大三小组课程作业,基于社区疫情的管理信息系统的开发文档,此为记录. 1.系统概述 1.1项目背景 本小组设计的社区疫情管理系统是计算机技术与疫情管理相结合的产物,通过使用社区疫情管理系统,可以实现 ...
- 企业门户网站设计开发文档模板
案卷号 201304 日期 2013/4/1 企业门户网站设计开发文档 作 者: xx 完成日期: 2013/04/01 签 收 ...
- 【校招VIP】“推电影”第一期电影详情模块Java开发文档作业评审1
前言:关于[推电影]免费在线实习项目 一.本项目是基于年轻人的喜好,更个性的电影推荐网站.筛选各分类的知名电影,并给出推荐理由和下载链接.另外,通过标签功能匹配个人喜好,实现个性化推送. 二.项目表现 ...
- 【IT基础】常见的开发文档
Perface 随着技术的进步,小作坊式的软件开发年代已经过去.目前的软件开发能力在不断提升,用户对软件的功能和性能要求也越来越高,软件开发质量受到关注. 在软件开发过程中,各种数据和代码的管理需要经 ...
最新文章
- linux驱动开发要知道的那些知识(三)------container_of,定时器 及系统调用
- Java IO流之转换流
- [HNOI2003]操作系统
- DCMTK:测试DICOM RT类的读写方法
- 存储知识课堂(二):磁盘读写磁头揭秘
- 一个毕业生对大学爱情和奋斗的思考!
- ubuntu16.04 离线安装docker ce
- Comparable 与 Comparator
- linux安装curl扩展
- 不格式化U盘的情况下部署WinPE
- pdf文件展示盖章及下载
- p坚持csma协议 仿真‘_签了“三方协议”,还算应届毕业生吗!?
- 写给程序员的 2018 新年计划清单
- C++:endl的作用
- win11怎么关闭自动更新系统
- 【202106小白训练营】day03-java数据结构
- 插件中的chalk的用法
- border-radius 使用技巧
- elementUI Form中 勾选框设置必选不提示问题
- 序列化:Protobuf 与 JSON、XML 的对比
热门文章
- 苹果App Icon的问题
- 深度学习系列:深度学习在腾讯的平台化和应用实践
- 关于Swift4.0 Method Swizzling(iOS的hook机制)使用
- timestamp with local time zone类型和timestamp with time zone
- Java学习|先定一个小目标比如让行为聚焦
- codeigniter 中使用 phpexcel
- ReactJS学习笔记——npm、JSX、webpack
- Android 通过反射让SQlite建表
- MySQL5.6开启慢查询
- Java程序结合Aapche Ant进行远程服务器文件备份