Recording Audio using Android's MediaRecorder Framework
Sometimes your app needs the ability to record and store audio files. As most devices come with a microphone it's no surprise that Android offers app developers the possibility to do so. This post deals with the two most common ways to record audio on Android.
Recording audio using an Intent
As usual that's by far the easiest option. You simply create the Intent
Intent intent =
new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
if (isAvailable(getApplicationContext(), intent)) {
startActivityForResult(intent,
REQUESTCODE_RECORDING);
}
You have to use startActivityForResult()
onActivityResult()
method. REQUESTCODE_RECORDING
is a final static int variable that you have to create. You can give it any name you like. The value of this field must be unique among all startActivityForResult()
calls that you might want to use.You need this int field again when checking for the result:
protected void onActivityResult(int requestCode,
int resultCode, Intent intent) {
if (requestCode == REQUESTCODE_RECORDING) {
if (resultCode == RESULT_OK) {
Uri audioUri = intent.getData();
// make use of this MediaStore uri
// e.g. store it somewhere
}
else {
// react meaningful to problems
}
}
else {
super.onActivityResult(requestCode,
resultCode, intent);
}
}
The standard activity to record audio looks like this:
Alas using an intent has the usual drawback: The intent might not be available. And, indeed, on my old LG Optimus One (P500) it doesn't work ðŸ™
A problem with this solution is the location, that Android uses to store the recorded file. Android puts the file directly to the root of the SD card - something that often annoys users.
Doing it yourself
If you want to have more control over audio recording you could use the MediaRecorder.
But first you have to cover the basics - permissions. As usual you have to state that your app wants to record audio in the mainfest file. Add these lines to your AndroidManifest.xml
:
<uses-permission
android:name="android.permission.RECORD_AUDIO" />
For the intent-based solution above you do not need this permission. But for using the MediaRecorder
framework, you do. Without the correct permission you get an exception that is very misleading:
java.lang.RuntimeException: setAudioSource failed.
This is Android's strange way to tell us, that we forgot to ask for this permission 🙂
Using the MediaRecorder
Recording audio with the MediaRecorder
requires you to adhere to the MediaRecorder's
state transitions, so you have to be strict with the ordering of your operations. To start a recording you have to do the following steps:
- Create a MediaRecorder object
- State the source to use
- Set the file format
- Set the Encoding
- Prepare a file
- Start recording
And here it is in code:
MediaRecorder recorder = null;
private void startRecording(File file) {
if (recorder != null) {
recorder.release();
}
recorder = new MediaRecorder();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(OutputFormat.THREE_GPP);
recorder.setAudioEncoder(AudioEncoder.AMR_WB);
recorder.setOutputFile(file.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
Log.e("giftlist", "io problems while preparing [" +
file.getAbsolutePath() + "]: " + e.getMessage());
}
}
You need the MediaRecorder
object later on to stop the recording and to clean up, so you have to use an instance variable for it.
Please follow Android's best practices about storing files. In most cases your app-specific folder is the best choice for recorded files.
What could go wrong?
Now the order in which you call the methods of the MediaRecorder
object is very important. If you stick with the order of the code snippet above, all is fine. If not you will see one of the following exceptions or messages in your log file:
- java.lang.IllegalStateException
Happens when you do not follow the order above, miss some important steps or whenprepare()
failed, but you continue anyway. The latter is where it is most likely to go wrong. You should only callstart()
whenprepare()
did exit without exceptions. Otherwise you will get anIllegalStateException
. Since it is aRuntimeException
you might not catch it and your app will force close. That's where the documentation sample code is misleading. - mediarecorder went away with unhandled events
Happens when you release the Mediarecorder object while events were still being processed or queued. No need to worry, though. Everything went fine anyway - this message is just to notify you about this. - Fatal signal 11 (SIGSEGV)
That's a really bad one. Not a Force close, but your app simply vanishes and then restarts. This segmentation fault can occur when you callrelease()
and still use the object afterwards.
Can also happen if you callreset()
on aMediaRecorder
object that hasn't even been prepared. The next method call on theMediaRecorder
object will cause the segmentation fault to occur.
An example of what could go wrong: I tried to optimize above code by just calling reset()
at the start of the method when the recorder object already exists. All nice and dandy if never ever anything goes wrong. But if for example the prepare stage goes wrong, this optimization fails miserably (segmentation fault again). That's why I got rid of it and now simply call release()
before creating a new MediaRecorder
object.
Stopping the recording
With stopping you have to follow the ordering of the state chart in MediaRecorder's documentation again. But since there are only two steps, this is easy:
private void stopRecording() {
if (recorder != null) {
recorder.stop();
recorder.release();
recorder = null;
}
}
Releasing resources
When everything is done, you have to release resources. You should do so in the onPause()
method of your activity, as you can see in the next snippet:
protected void onPause() {
super.onPause();
if (recorder != null) {
recorder.release();
recorder = null;
}
}
Summary
You have seen how to leverage the RECORD_SOUND_ACTION
action to use an intent for recording. Since this intent is not always available, or because you might want to present another UI, you can also use the MediaRecorder
framework directly.
There is an even more fine-grained way to record audio in Android by using AudioRecord. This class allows you to deal with raw audio data. I will not go into this since it should be of interest only to few developers.
相關推薦
Recording Audio using Android's MediaRecorder Framework
Sometimes your app needs the ability to record and store audio files. As most devices come with a microphone it's no
How We Do Automatic Token Refreshing using Android’s New Work Manager
Just before all hope was lost, Evernote’s wonderful engineering team came up with a solution to this gap that has been created. Their Android-Job library b
Adding Files to Android's Media Library Using the MediaScanner
When you add files to Android's filesystem these files are not picked up by the MedaScanner automatically. But often
Using Let’s Encrypt for free SSL Certs with Netscaler
module putty rar perl 4th com via pac services Using Let’s Encrypt for free SSL Certs with Netscaler If you haven’t heard, Let’s Encryp
Error處理: android.media.MediaRecorder.start(Native Method) 報錯:start failed: -19
bsp RM hand apt zygote utf use failed 解決方法 spydroid-android測試在android4.0系統上報錯 [html] view plain copy start failed: -19 而且也發現,在
ionic打包報錯:You have not accepted the license agreements of the following SDK components: [Android S
錯誤資訊: ...... You have been opted out of telemetry. To change this, run: cordova telemetry on. Android Studio project detected ANDROID_HOME=C:\User
Qt's Undo Framework筆記
QUndoCommand 是儲存在undo堆疊中的所有命令的基類。它可以重做或撤消當前文件中的單個更改。 QUndoStack是儲存了QUndoCommand命令物件的連結串列。它包含在文件上執行的所有命令,可以通過撤消或重做來前後滾動文件的狀態。 QUndoGroup 是 undo stacks的一組集
Some tips about using google’s TPU
About one month ago, I submit a request to Google Research Cloud for using TPU for free. Fortunately, I received the approvement yesterday. The appro
Some tips about using google’s TPU (Cont.)
Sometimes I get this error from TPUEstimator: ... File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/s
Using Sketch’s grid in React
Using Sketch’s grid in ReactI design in Sketch, and I use grids pretty heavily. I know there are some fancy grid plugins out there, but I find that 90% of
Using TypeScript’s singleton types in practice
Part two: The practical gotchas“To know a thing well, know its limits; Only when pushed beyond its tolerance will its true nature be seen.”― Frank Herbert,
Ask HN: Creative people of HN, what’s your framework for “scheduled” creativity?
Knowing lots of developers and designers I’m observing various different ways they come up with systems to be "creative on time". Some people are good at “
Opinionated and open machine learning: The nuances of using Facebook's PyTorch ZDNet
Chintala's take is that some people would have to be assigned on something like this anyway. If PyTorch had not been created, the other option would be to
Everything every Android Developer must know about new Android's Runtime Permission
Android M's name was just announced officially days ago. The final version is almost there and would be released not so long. Although A
Some Thoughts on Android's new ConstraintLayout and Android Studio's new Design Editor
At this year's IO Google introduced a new layout - the ConstraintLayout - and also presented it's totally revamped la
Android's ConstraintLayout: Align One View's Edge to Another View's Center
As you can see from the following excerpt of ConstraintLayout's supported attributes, there is no layout_constraintSt
Fast Order Search Using Yelp’s Data Pipeline and Elasticsearch
Since its inception in 2013, Yelp has grown its transactions platform to tens of millions of orders. With this growth, it’s become slow and cumberso
Configuring your server to provide HTTPS using Let's Encrypt and Nginx
OK, let's start with some definitions and then we start with the magic steps:Let's encrypt: is a certificate authority (CA) that provides free digital cert
Wal-Mart Still Using SAP's HANA in Business Intelligence
AI is increasingly being used in business intelligence applications. Companies can now use machine learning algorithms to identify
Using Amazon’s Mechanical Turk for Machine Learning Data
How to build a model from Mechanical Turk resultsAmazon Mechanical Turk will notify you when your results are ready and you will finally have a labelled da