Android实现多媒体录音笔
作者:lijiao 时间:2022-03-26 17:25:00
记事本涉及到的仅仅是对string 的存储,而且在读取上并不存在什么难点,直接用textview显示便可以了。需要做的主要是使用SQLite对数据进行一个整理。
而录音笔需要考虑的就相对较多了:比如录音时中断,录音时用户点击播放按钮;未录音,用户点击停止按钮;在录音或者播放时关闭activity;listview的item中需要为button设置不同的点击效果等等。
为了便于新手学习,在此还是罗列一下涉及的主要知识点:
1、Baseadapter
2、JAVA的file
3、MediaRecorder
4、较多的AlertDialog
5、MediaPlayer
遇到的问题:
在listview item中的button控件可以获得焦点时,直接为listview设置item长按事件的监听。出现了listview的item长按事件无效的情况。
解决方法:
直接在Baseadapter中对该item的布局进行长按事件的监听(在笔者demo中是linearlayout),也就是说对item中button的父布局进行长按事件的监听。
效果:
MainActivity:
package com.example.recorder;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
public class MainActivity extends Activity implements OnClickListener {
private Button start;
private Button stop;
private ListView listView;
ShowRecorderAdpter showRecord;
// 录音文件播放
// 录音
// 音频文件保存地址
private MediaPlayer myPlayer;
private MediaRecorder myRecorder = null;
private String path;
private File saveFilePath;
// 所录音的文件名
String[] listFile = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
InitView();
}
private void InitView() {
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
listView = (ListView) findViewById(R.id.list);
myPlayer = new MediaPlayer();
showRecord = new ShowRecorderAdpter();
//如果手机有sd卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
try {
path = Environment.getExternalStorageDirectory()
.getCanonicalPath().toString()
+ "/MyRecorders";
File files = new File(path);
if (!files.exists()) {
//如果有没有文件夹就创建文件夹
files.mkdir();
}
listFile = files.list();
} catch (IOException e) {
e.printStackTrace();
}
}
start.setOnClickListener(this);
stop.setOnClickListener(this);
listView.setAdapter(showRecord);
}
//由于在item中涉及到了控件的点击效果,所以采用BaseAdapter
class ShowRecorderAdpter extends BaseAdapter {
@Override
public int getCount() {
return listFile.length;
}
@Override
public Object getItem(int arg0) {
return arg0;
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(final int postion, View arg1, ViewGroup arg2) {
View views = LayoutInflater.from(MainActivity.this).inflate(
R.layout.list_item, null);
LinearLayout parent = (LinearLayout) views.findViewById(R.id.list_parent);
TextView filename = (TextView) views.findViewById(R.id.show_file_name);
Button plays = (Button) views.findViewById(R.id.bt_list_play);
Button stop = (Button) views.findViewById(R.id.bt_list_stop);
//在textview中显示的时候把“.amr”去掉
filename.setText(listFile[postion].substring(0, listFile[postion].length() - 4));
parent.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
AlertDialog aler = new AlertDialog.Builder(MainActivity.this)
.setTitle("确定删除该录音?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog
, int which) {
File file = new File(path + "/" + listFile[postion]);
file.delete();
// 在删除文件后刷新文件名列表
File files = new File(path);
listFile = files.list();
// 当文件被删除刷新ListView
showRecord.notifyDataSetChanged();
}
})
.setNegativeButton("取消", null)
.create();
//设置不允许点击提示框之外的区域
aler.setCanceledOnTouchOutside(false);
aler.show();
return false;
}
});
// 播放录音
plays.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//确认不是在录音的过程中播放
if (myRecorder == null) {
try {
myPlayer.reset();
myPlayer.setDataSource(path + "/" + listFile[postion]);
if (!myPlayer.isPlaying()) {
myPlayer.prepare();
myPlayer.start();
} else {
myPlayer.pause();
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "请不要再录音的过程中播放!", Toast.LENGTH_SHORT).show();
}
}
});
// 停止播放
stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (myRecorder == null && myPlayer.isPlaying()) {
myPlayer.stop();
}
}
});
return views;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
final EditText filename = new EditText(this);
AlertDialog aler = new Builder(this)
.setTitle("请输入要保存的文件名")
.setView(filename)
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
String text = filename.getText().toString();
//如果文件名为空则跳出提示信息
if (text.equals("")) {
Toast.makeText(MainActivity.this,
"请不要输入空的文件名!", Toast.LENGTH_SHORT).show();
} else {
//开启录音
RecorderStart(text);
start.setText("正在录音中。。");
start.setEnabled(false);
stop.setEnabled(true);
// 在增添文件后刷新文件名列表
File files = new File(path);
listFile = files.list();
// 当文件增加刷新ListView
showRecord.notifyDataSetChanged();
}
}
})
.setNegativeButton("取消",null)
.create();
//设置不允许点击提示框之外的区域
aler.setCanceledOnTouchOutside(false);
aler.show();
break;
case R.id.stop:
myRecorder.stop();
myRecorder.release();
myRecorder = null;
// 判断是否保存 如果不保存则删除
aler = new AlertDialog.Builder(this)
.setTitle("是否保存该录音")
.setPositiveButton("确定", null)
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
saveFilePath.delete();
// 在删除文件后刷新文件名列表
File files = new File(path);
listFile = files.list();
// 当文件被删除刷新ListView
showRecord.notifyDataSetChanged();
}
}).create();
//设置不允许点击提示框之外的区域
aler.setCanceledOnTouchOutside(false);
aler.show();
start.setText("录音");
start.setEnabled(true);
stop.setEnabled(false);
default:
break;
}
}
private void RecorderStart(String text) {
try {
myRecorder = new MediaRecorder();
// 从麦克风源进行录音
myRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// 设置输出格式
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// 设置编码格式
myRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
String paths = path + "/" + text + ".amr";
saveFilePath = new File(paths);
myRecorder.setOutputFile(saveFilePath.getAbsolutePath());
myRecorder.prepare();
// 开始录音
myRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 如果myPlayer正在播放,那么就停止播放,并且释放资源
if (myPlayer.isPlaying()) {
myPlayer.stop();
myPlayer.release();
}
//如果myRecorder有内容(代表正在录音),那么就直接释放资源
if(myRecorder!=null) {
myRecorder.release();
myPlayer.release();
}
}
}
activity_main:
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000"
android:padding="13dp"
android:text="语音笔"
android:textColor="#fff"
android:textSize="22sp"
android:textStyle="bold" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
></ListView>
<LinearLayout
android:id="@+id/li1"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/start"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp"
android:text="开始录音" />
<Button
android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:textSize="20sp"
android:text="停止录音" />
</LinearLayout>
</LinearLayout>
list_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:id="@+id/list_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/show_file_name"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="文件名"
android:textColor="#000"
android:textSize="20sp"
/>
<Button
android:id="@+id/bt_list_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="播放" />
<Button
android:id="@+id/bt_list_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="停止" />
</LinearLayout>
标签:Android,多媒体,录音笔
0
投稿
猜你喜欢
Android开发中软键盘的显示和隐藏
2023-10-03 06:00:20
Android之listfragment的使用例子
2021-05-31 02:10:19
android 设置全屏的两种方法
2023-06-30 00:06:11
记一次公司JVM堆溢出抽丝剥茧定位的过程解析
2023-11-09 13:11:24
MFC程序设计常用技巧汇总
2023-11-02 20:37:12
C#将布尔类型转换成字节数组的方法
2023-06-21 15:30:16
C#套接字(Socket)通信之UDP组播详解
2022-06-11 05:49:52
SSH框架网上商城项目第8战之查询和删除商品类别功能实现
2023-02-12 05:54:39
深入解析C#中的泛型类与泛型接口
2023-04-30 02:35:39
C#使用winform简单导出Excel的方法
2022-06-11 06:58:49
Java生成10个1000以内的随机数并用消息框显示数组内容然后求和输出
2023-09-30 21:20:19
java中如何执行xshell命令
2021-10-06 16:22:18
Java使用DateTimeFormatter格式化输入的日期时间
2023-03-09 04:52:38
JDK10中的局部变量类型推断var
2022-06-16 20:32:48
RecylerView实现流布局StaggeredGridLayoutManager使用详解
2023-04-30 20:51:38
C++中的异常处理机制详解
2023-04-16 16:01:10
Java安全 ysoserial CommonsCollections3示例分析
2022-01-19 05:08:19
C#中通过Command模式实现Redo/Undo方案
2021-07-12 14:58:59
C# List引用类型克隆的3种方法
2023-04-19 14:20:44
gson对象序列化的示例
2023-11-25 08:54:28