Android實(shí)現(xiàn)多媒體錄音筆
記事本涉及到的僅僅是對(duì)string 的存儲(chǔ),而且在讀取上并不存在什么難點(diǎn),直接用textview顯示便可以了。需要做的主要是使用SQLite對(duì)數(shù)據(jù)進(jìn)行一個(gè)整理。
而錄音筆需要考慮的就相對(duì)較多了:比如錄音時(shí)中斷,錄音時(shí)用戶點(diǎn)擊播放按鈕;未錄音,用戶點(diǎn)擊停止按鈕;在錄音或者播放時(shí)關(guān)閉activity;listview的item中需要為button設(shè)置不同的點(diǎn)擊效果等等。
為了便于新手學(xué)習(xí),在此還是羅列一下涉及的主要知識(shí)點(diǎn):
- 1、Baseadapter
- 2、JAVA的file
- 3、MediaRecorder
- 4、較多的AlertDialog
- 5、MediaPlayer
遇到的問題:
在listview item中的button控件可以獲得焦點(diǎn)時(shí),直接為listview設(shè)置item長(zhǎng)按事件的監(jiān)聽。出現(xiàn)了listview的item長(zhǎng)按事件無(wú)效的情況。
解決方法:
直接在Baseadapter中對(duì)該item的布局進(jìn)行長(zhǎng)按事件的監(jiān)聽(在筆者demo中是linearlayout),也就是說(shuō)對(duì)item中button的父布局進(jìn)行長(zhǎng)按事件的監(jiān)聽。
效果:
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();
//如果手機(jī)有sd卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
try {
path = Environment.getExternalStorageDirectory()
.getCanonicalPath().toString()
+ "/MyRecorders";
File files = new File(path);
if (!files.exists()) {
//如果有沒有文件夾就創(chuàng)建文件夾
files.mkdir();
}
listFile = files.list();
} catch (IOException e) {
e.printStackTrace();
}
}
start.setOnClickListener(this);
stop.setOnClickListener(this);
listView.setAdapter(showRecord);
}
//由于在item中涉及到了控件的點(diǎn)擊效果,所以采用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中顯示的時(shí)候把“.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();
// 當(dāng)文件被刪除刷新ListView
showRecord.notifyDataSetChanged();
}
})
.setNegativeButton("取消", null)
.create();
//設(shè)置不允許點(diǎn)擊提示框之外的區(qū)域
aler.setCanceledOnTouchOutside(false);
aler.show();
return false;
}
});
// 播放錄音
plays.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//確認(rèn)不是在錄音的過程中播放
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, "請(qǐng)不要再錄音的過程中播放!", 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("請(qǐng)輸入要保存的文件名")
.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,
"請(qǐng)不要輸入空的文件名!", Toast.LENGTH_SHORT).show();
} else {
//開啟錄音
RecorderStart(text);
start.setText("正在錄音中。。");
start.setEnabled(false);
stop.setEnabled(true);
// 在增添文件后刷新文件名列表
File files = new File(path);
listFile = files.list();
// 當(dāng)文件增加刷新ListView
showRecord.notifyDataSetChanged();
}
}
})
.setNegativeButton("取消",null)
.create();
//設(shè)置不允許點(diǎn)擊提示框之外的區(qū)域
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();
// 當(dāng)文件被刪除刷新ListView
showRecord.notifyDataSetChanged();
}
}).create();
//設(shè)置不允許點(diǎn)擊提示框之外的區(qū)域
aler.setCanceledOnTouchOutside(false);
aler.show();
start.setText("錄音");
start.setEnabled(true);
stop.setEnabled(false);
default:
break;
}
}
private void RecorderStart(String text) {
try {
myRecorder = new MediaRecorder();
// 從麥克風(fēng)源進(jìn)行錄音
myRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// 設(shè)置輸出格式
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// 設(shè)置編碼格式
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有內(nèi)容(代表正在錄音),那么就直接釋放資源
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="語(yǔ)音筆"
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>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家實(shí)現(xiàn)Android軟件編程有所幫助。
- Android音頻錄制MediaRecorder之簡(jiǎn)易的錄音軟件實(shí)現(xiàn)代碼
- Android簡(jiǎn)單的利用MediaRecorder進(jìn)行錄音的實(shí)例代碼
- Android錄音應(yīng)用實(shí)例教程
- android編程實(shí)現(xiàn)電話錄音的方法
- Android 實(shí)現(xiàn)電話來(lái)去自動(dòng)錄音的功能
- Android編程開發(fā)錄音和播放錄音簡(jiǎn)單示例
- Android中簡(jiǎn)單調(diào)用圖片、視頻、音頻、錄音和拍照的方法
- Android錄音播放管理工具
- android 通過MediaRecorder實(shí)現(xiàn)簡(jiǎn)單的錄音示例
- 利用libmp3lame實(shí)現(xiàn)在Android上錄音MP3文件示例
相關(guān)文章
3種Android隱藏頂部狀態(tài)欄及標(biāo)題欄的方法
這篇文章主要為大家詳細(xì)介紹了3種Android隱藏頂部狀態(tài)欄及標(biāo)題欄的方法,還涉及一種隱藏Android 4.0平板底部狀態(tài)欄的方法,感興趣的小伙伴們可以參考一下2016-02-02
Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能實(shí)例
大家好,本篇文章主要講的是Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2021-12-12
Android SQLite數(shù)據(jù)庫(kù)中的表詳解
這篇文章主要介紹了Android SQLite數(shù)據(jù)庫(kù)中的表詳解的相關(guān)資料,這里附有實(shí)例代碼,需要的朋友可以參考下2017-01-01
Android編程實(shí)現(xiàn)通話錄音功能的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)通話錄音功能的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android廣播接收機(jī)制實(shí)現(xiàn)錄音功能的操作技巧,需要的朋友可以參考下2017-06-06
Android Build類的詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android Build類的詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,希望通過本文大家能夠理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-08-08
Android style的繼承方式 點(diǎn)(.)和parent詳解及實(shí)例
這篇文章主要介紹了Android style的繼承方式 點(diǎn)(.)和parent詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
Android 實(shí)現(xiàn)切圓圖作為頭像使用實(shí)例
這篇文章主要介紹了Android 實(shí)現(xiàn)切圓圖作為頭像使用實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-12-12

