一個BUTTON,實現點選播放錄音,長按錄音
因為畢業設計裡有需要用到錄音的功能,但是又要求介面比較小巧,所以思考了許久,相出個這麼辦法,讓一個BUTTON把播放和錄音的功能全部實現(當然,其他的也可以——。——~)
1.點選的話則播放/停止播放錄音
2.長按則開始錄音,手指離開則停止錄音
為了實現上面的效果,我們首先需要識別是點選還是長按,並且得知長按模式下按下和離開的時間。用設定setOnTouchListener的方式的話,自然可以實現,只要在按下後設定計時器就OK了,但是安卓裡GestureDetector這個類提供了onSingleTapUp()和onLongPress()這兩個方法幫助我們獲取到簡單的點選和長按事件,下面我們就測試如何利用這兩個方法來分辨點選和長按模式吧
不懂GestureDetector請手搓使用者手勢檢測-GestureDetector使用詳解
兩個模式的判斷
好了,請看關鍵程式碼和結果
首先繼承SimpleOnGestureListener並重寫上面提到的兩個方法
class RecordGesture extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.v("RecordGesture","onSingleTapUp");
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
Log.v("RecordGesture","onLongPress");
super.onLongPress(e);
}
}
然後用它來設定觸控監聽,同時省略一堆東西
private RecordGesture gesture;
private GestureDetector detector;
省略。。。
gesture = new RecordGesture();
detector = new GestureDetector(context, gesture);
setOnTouchListener(this);
省略。。。
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.v("RecordGesture","ACTION_UP");
}
return true;
}
下面附上結果圖
點選
長按並得知手指離開的時間
很輕易的辨別出了兩種模式,並且得知何時結束錄音,那麼就可以像這麼寫了,在函式內直接新增錄音相關的內容即可
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP && isRecording) {
stopSoundRecord();
}
return true;
}
class RecordGesture extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.v("RecordGesture","onSingleTapUp");
if (isPlaying) {
stopPlayRecord();
} else {
startPlayRecord();
}
return super.onSingleTapUp(e);
}
@Override public void onLongPress(MotionEvent e) { Log.v("RecordGesture","onLongPress"); startSoundRecord(); super.onLongPress(e); } }
有人可能會問,上面的這部分程式碼為什麼不把判斷ACTION_UP放在前面呢?
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.v("RecordGesture","ACTION_UP");
}
讓我們在重寫的onTouch裡新增這句程式碼,然後觸發點選事件看看
Log.v("RecordGesture",event.getAction()+" "+System.currentTimeMillis());
0=ACTION_DOWN 1=ACTION_UP 2=ACTION_MOVE
可以看到在傳遞過來了幾次ACTION_MOVE後才觸發的onSingleTapUp,所以我不贊成把判斷寫在前面,因為有時會有意料之外的結果,尤其是你打算在if判斷句裡return的時候
專案關鍵程式碼
這章部落格我是準備寫錄音來著吧。。。。好像是,不過網上錄音的部落格太多了,就不多講了,還是直接貼程式碼吧,100多行簡單了事
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import static android.content.Context.VIBRATOR_SERVICE;
import static android.media.MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED;
import static android.media.MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED;
import static com.sy.audiorecord.audiorecord.RecordUtils.durationToStr;
import static com.sy.audiorecord.audiorecord.RecordUtils.getRecordDuration;
public class SoundRecord extends Button implements View.OnTouchListener {
private RecordGesture gesture;
private GestureDetector detector;
private Vibrator vibrator;//振動器
private boolean isRecording = false;//是否正在錄音
private boolean isPlaying = false;//是否正在播放錄音
private MediaPlayer player = null;//媒體播放器
private MediaRecorder recorder = null;//媒體錄音器
private String filePath;//檔案路徑
private int maxDuration = 0;//錄音最大時間限制
private long max_filesize_bytes = 0;//錄音檔案最大大小限制
public void setMaxDuration(int maxDuration) {
this.maxDuration = maxDuration;
}
public void setMax_filesize_bytes(long max_filesize_bytes) {
this.max_filesize_bytes = max_filesize_bytes;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
setText(durationToStr(getRecordDuration(this.filePath)));
}
public SoundRecord(Context context) {
super(context, null);
}
public SoundRecord(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
vibrator = (Vibrator) context.getSystemService(VIBRATOR_SERVICE);
gesture = new RecordGesture();
detector = new GestureDetector(context, gesture);
setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP && isRecording) {
stopSoundRecord();
}
return true;
}
class RecordGesture extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (isPlaying) {
stopPlayRecord();
} else {
startPlayRecord();
}
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
startSoundRecord();
super.onLongPress(e);
}
}
private void beforePlayStart() {
vibrator.vibrate(100);
}
private void afterPlayEnd() {
vibrator.vibrate(100);
}
private void startPlayRecord() {
try {
player = new MediaPlayer();
player.setDataSource(filePath);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stopPlayRecord();
}
});
player.prepare();
beforePlayStart();
player.start();
isPlaying = true;
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void stopPlayRecord() {
player.stop();
player.release();
player = null;
isPlaying = false;
afterPlayEnd();
}
private void beforeRecordStart() {
vibrator.vibrate(100);
}
private void afterRecordEnd() {
vibrator.vibrate(100);
setText(durationToStr(getRecordDuration(filePath)));
}
private void startSoundRecord() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(filePath);
recorder.setMaxDuration(maxDuration);
recorder.setMaxFileSize(max_filesize_bytes);
recorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (MEDIA_RECORDER_INFO_MAX_DURATION_REACHED == what || MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED == what) {stopSoundRecord();
} } }); try { recorder.prepare(); beforeRecordStart(); recorder.start(); isRecording = true; } catch (IOException e1) { e1.printStackTrace(); } } private void stopSoundRecord() { recorder.release(); recorder = null; isRecording = false; afterRecordEnd(); }}
RecordUtils類
public class RecordUtils {
public static int getRecordDuration(String filePath) {
int duration = -1;
//如果檔案不存在就返回-1
File file = new File(filePath);
if (!file.exists())
return duration;
//如果檔案存在但是是流媒體直播的內容則也會返回-1
MediaPlayer player = new MediaPlayer();
try {
player.setDataSource(filePath);
player.prepare();
duration = player.getDuration();
player.reset();
player.release();
} catch (IOException e) {
e.printStackTrace();
}
return duration;
}
public static String durationToStr(int duration) {
//如果傳進來的時長為-1則返回代表沒有內容的字串"..:.."
if (-1 == duration)
return "..:..";
//時長不為1的話,則按"分:秒"的字串形式組合字串傳出
StringBuilder builder = new StringBuilder();
float sumSecond = duration / 1000;
int minute = (int) (sumSecond / 60);
int second = (int) (sumSecond % 60);
builder.append(minute).append(":").append(second);
return builder.toString();
}
}
用的話,就這麼用
record= (SoundRecord) findViewById(R.id.record);
record.setFilePath(Environment.getExternalStorageDirectory().getPath()+
File.separatorChar+"123"+".mp3");
也不要忘了新增許可權
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.VIBRATE" />這個是振動器的許可權
相關文章
- iOS開發:音訊播放、錄音、視訊播放、拍照、視訊錄製iOS音訊
- 呼叫API實現錄音API
- iOS開發系列--音訊播放、錄音、視訊播放、拍照、視訊錄製(轉)iOS音訊
- AVFoundation 文字轉語音和音訊錄製 播放音訊
- 如何實現前端錄音功能前端
- C#實現錄音錄影錄屏原始碼C#原始碼
- Android WebView 實現檔案選擇、拍照、錄製視訊、錄音AndroidWebView
- 音訊_錄音音訊
- Flutter 敲一個靈動的錄音按鈕動畫 - Speed CodeFlutter動畫
- vue實現錄音功能(pc端)Vue
- TouchEvent實現前端錄音打分功能前端
- python實現播放音訊和錄音功能示例程式碼Python音訊
- Android 音樂播放器開發實錄(MediaSession)Android播放器Session
- vue——一個頁面實現音樂播放器Vue播放器
- 如何實現遊戲陪玩系統中語音的錄製與播放?遊戲
- 仿QQ錄音以及振幅動畫實現動畫
- js實現網頁端錄音功能JS網頁
- 電腦錄音軟體哪個好 內部聲音如何錄
- Android音訊開發之AudioRecord錄音實現Android音訊
- Android多媒體之認識聲音、錄音與播放(PCM)Android
- 如何點選一個按鈕實現列印
- uniapp 實現打電話錄音功能APP
- web技術支援| Web 客戶端實現錄音、錄影Web客戶端
- Win7如何錄製內部聲音 電腦錄音軟體線上錄音Win7
- 音訊開發之錄製播放pcm檔案音訊
- 直播原始碼,直接在動態介面播放錄音原始碼
- 做一個虛擬現實的音樂播放軟體 (轉)
- 語音交友app開發,點選按鈕出現彈窗的實現方式APP
- 使用Windows自帶“錄音機”錄製音樂(轉)Windows
- Android中實現錄製內建聲音Android
- Android AudioRecord錄音 並websocket實時傳輸,AudioTrack 播放wav 音訊,Speex加密AndroidWeb音訊加密
- Mac錄音軟體哪個好 怎麼錄製系統內部聲音Mac
- html5錄音功能實戰HTML
- 怎麼錄製QQ語音通話 QQ通話錄音軟體哪個好?
- MP3格式音訊如何線上錄製,錄音軟體哪個好?音訊
- MacBook 如何錄屏和錄音訊Mac音訊
- win10 如何錄音_win10錄音裝置在哪Win10
- 音訊錄製:三星電腦如何錄製音訊?音訊