Android:如何将录制的音频存储在 SD 卡中
Posted
技术标签:
【中文标题】Android:如何将录制的音频存储在 SD 卡中【英文标题】:Android : How to store recorded audio inside SD-card 【发布时间】:2014-01-31 09:30:08 【问题描述】:我正在尝试使用以下代码录制音频。
public static final int CAPTURE_AUDIO = 0;
....
....
点击按钮我有以下代码。
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent,CAPTURE_AUDIO);
所以它正在打开默认音频播放器并录制音频并存储在 SD 卡默认录制文件夹中。
所以一切都很好,但问题是我只想将此录音存储在 SD 卡中,但使用其他名称和其他文件夹,如
文件夹的名称是 AudioRecording,录音的名称是 audio.mp3,我该怎么做。
我尝试了一些解决方案,但它对我不起作用。我知道这是一项简单的任务,但有些我无法弄清楚。任何建议都将受到高度赞赏.. 提前谢谢您。
【问题讨论】:
请上传录音代码。 您知道创建的文件吗?您是否尝试过将文件复制到您想要的位置,并使用您想要的名称? 我正在通过意图打开默认的 android 记录器。所以它会自动打开默认录音。所以没有录制代码 @Gusdor,是的,它正在 SD 卡内创建文件管理器,文件夹名称为“正在录制”。 然后,只需将文件添加到您希望它在记录器活动退出时的位置。看到这个问题***.com/questions/4178168/… 【参考方案1】:这里我添加了通话记录器示例源代码。请尝试告诉我。
RecordService.java
import java.io.File;
import java.io.IOException;
import java.lang.Exception;
import java.util.Date;
import java.text.SimpleDateFormat;
import android.os.IBinder;
import android.app.Service;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.preference.PreferenceManager;
import android.content.SharedPreferences;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.widget.Toast;
import android.util.Log;
import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Iterator;
public class RecordService
extends Service
implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener
private static final String TAG = "CallRecorder";
public static final String DEFAULT_STORAGE_LOCATION = "/sdcard/AudioRecording";
private static final int RECORDING_NOTIFICATION_ID = 1;
private MediaRecorder recorder = null;
private boolean isRecording = false;
private File recording = null;;
private final int audioformat = 3;
private File makeOutputFile (SharedPreferences prefs)
File dir = new File(DEFAULT_STORAGE_LOCATION);
// test dir for existence and writeability
if (!dir.exists())
try
dir.mkdirs();
catch (Exception e)
Log.e("CallRecorder", "RecordService::makeOutputFile unable to create directory " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create the directory " + dir + " to store recordings: " + e, Toast.LENGTH_LONG);
t.show();
return null;
else
if (!dir.canWrite())
Log.e(TAG, "RecordService::makeOutputFile does not have write permission for directory: " + dir);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder does not have write permission for the directory directory " + dir + " to store recordings", Toast.LENGTH_LONG);
t.show();
return null;
// test size
// create filename based on call data
String prefix = "call";
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd_HH:MM:SS");
//prefix = sdf.format(new Date()) + "-callrecording";
// add info to file name about what audio channel we were recording
prefix += "-channel" + 1 + "-";
// create suffix based on format
String suffix = "";
switch (audioformat)
case MediaRecorder.OutputFormat.THREE_GPP:
suffix = ".3gpp";
break;
case MediaRecorder.OutputFormat.MPEG_4:
suffix = ".mpg";
break;
case MediaRecorder.OutputFormat.RAW_AMR:
suffix = ".amr";
break;
try
return File.createTempFile(prefix, suffix, dir);
catch (IOException e)
Log.e("CallRecorder", "RecordService::makeOutputFile unable to create temp file in " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create temp file in " + dir + ": " + e, Toast.LENGTH_LONG);
t.show();
return null;
public void onCreate()
super.onCreate();
recorder = new MediaRecorder();
Log.i("CallRecorder", "onCreate created MediaRecorder object");
public void onStart(Intent intent, int startId)
Log.i("CallRecorder", "RecordService::onStartCommand called while isRecording:" + isRecording);
if (isRecording) return;
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
Boolean shouldRecord = prefs.getBoolean(Preferences.PREF_RECORD_CALLS, false);
if (!shouldRecord)
Log.i("CallRecord", "RecordService::onStartCommand with PREF_RECORD_CALLS false, not recording");
//return START_STICKY;
return;
recording = makeOutputFile(prefs);
if (recording == null)
recorder = null;
return; //return 0;
try
// These calls will throw exceptions unless you set the
// android.permission.RECORD_AUDIO permission for your app
recorder.reset();
recorder.setAudiosource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(audioformat);
Log.d("CallRecorder", "set output " + audioformat);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
Log.d("CallRecorder", "set encoder default");
recorder.setOutputFile(recording.getAbsolutePath());
Log.d("CallRecorder", "set file: " + recording);
//recorder.setMaxDuration(msDuration); //1000); // 1 seconds
//recorder.setMaxFileSize(bytesMax); //1024*1024); // 1KB
recorder.setOnInfoListener(this);
recorder.setOnErrorListener(this);
try
recorder.prepare();
catch (java.io.IOException e)
Log.e("CallRecorder", "RecordService::onStart() IOException attempting recorder.prepare()\n");
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
recorder = null;
return; //return 0; //START_STICKY;
Log.d("CallRecorder", "recorder.prepare() returned");
recorder.start();
isRecording = true;
Log.i("CallRecorder", "recorder.start() returned");
updateNotification(true);
catch (java.lang.Exception e)
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
Log.e("CallRecorder", "RecordService::onStart caught unexpected exception", e);
recorder = null;
return; //return 0; //return START_STICKY;
public void onDestroy()
super.onDestroy();
if (null != recorder)
Log.i("CallRecorder", "RecordService::onDestroy calling recorder.release()");
isRecording = false;
recorder.release();
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder finished recording call to " + recording, Toast.LENGTH_LONG);
t.show();
updateNotification(false);
// methods to handle binding the service
public IBinder onBind(Intent intent)
return null;
public boolean onUnbind(Intent intent)
return false;
public void onRebind(Intent intent)
private void updateNotification(Boolean status)
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
if (status)
int icon = R.drawable.rec;
CharSequence tickerText = "Recording call from channel " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "CallRecorder Status";
CharSequence contentText = "Recording call from channel...";
Intent notificationIntent = new Intent(this, RecordService.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(RECORDING_NOTIFICATION_ID, notification);
else
mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
// MediaRecorder.OnInfoListener
public void onInfo(MediaRecorder mr, int what, int extra)
Log.i("CallRecorder", "RecordService got MediaRecorder onInfo callback with what: " + what + " extra: " + extra);
isRecording = false;
// MediaRecorder.OnErrorListener
public void onError(MediaRecorder mr, int what, int extra)
Log.e("CallRecorder", "RecordService got MediaRecorder onError callback with what: " + what + " extra: " + extra);
isRecording = false;
mr.release();
PhoneListener.java
import android.content.Intent;
import android.content.Context;
import android.content.ComponentName;
import android.telephony.TelephonyManager;
import android.telephony.PhoneStateListener;
import android.util.Log;
public class PhoneListener extends PhoneStateListener
private Context context;
public PhoneListener(Context c)
Log.i("CallRecorder", "PhoneListener constructor");
context = c;
public void onCallStateChanged (int state, String incomingNumber)
Log.d("CallRecorder", "PhoneListener::onCallStateChanged state:" + state + " incomingNumber:" + incomingNumber);
switch (state)
case TelephonyManager.CALL_STATE_IDLE:
Log.d("CallRecorder", "CALL_STATE_IDLE, stoping recording");
Boolean stopped = context.stopService(new Intent(context, RecordService.class));
Log.i("CallRecorder", "stopService for RecordService returned " + stopped);
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("CallRecorder", "CALL_STATE_RINGING");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("CallRecorder", "CALL_STATE_OFFHOOK starting recording");
Intent callIntent = new Intent(context, RecordService.class);
ComponentName name = context.startService(callIntent);
if (null == name)
Log.e("CallRecorder", "startService for RecordService returned null ComponentName");
else
Log.i("CallRecorder", "startService returned " + name.flattenToString());
break;
希望它对你有帮助。它对我来说很好用。请尝试让我知道。更多信息请下载示例代码表格
Call Recorder
【讨论】:
感谢您的回复,但我只想用 Intent 开始录制,我不想使用MediaRecorder
。【参考方案2】:
我认为实现此目的的最佳方法是将音频转换为 byte[]
数组。假设您已经这样做了,这应该可以:
final File soundFile = new File("/sdcard/AudioRecording/");
soundFile.mkdirs();
final File outFile = new File(soundFile, 'audiofile.mp3');
try
final FileOutputStream output = new FileOutputStream(outFile);
output.write(yourByteArrayWithYourAudioFileConverted);
output.close();
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
可能不是您的情况,但mkdirs()
方法将尝试构建所有缺少的父目录。在您的情况下,您可能正在确保用户拥有外部卡,这不是必需的(因为根目录是 /sdcard
),但是如果您打算将文件存储在更高的目录深度中,那么它将自动创建所有层次结构。
【讨论】:
以上是关于Android:如何将录制的音频存储在 SD 卡中的主要内容,如果未能解决你的问题,请参考以下文章
Android:使用 audiorecord 类录制音频播放快进