android - quitar - El objeto AudioRecord no se está inicializando
tag editor para pc (12)
En el siguiente código, mi objeto audioRecord
no se está inicializando. Intenté moverlo al método onCreate
y lo hice global. He registrado el estado y eso devuelve un valor de 1
que significa que está listo para usar. El depurador dice que se está llamando a startRecording
en un objeto no inicializado. También dice que no pudo obtener la fuente de audio.
¿Por qué recibo estos errores?
package com.tecmark;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class recorder extends Activity {
private Thread thread;
private boolean isRecording;
private AudioRecord recorder;
private FileOutputStream os;
private BufferedOutputStream bos;
private DataOutputStream dos;
private TextView text;
private int audioSource = MediaRecorder.AudioSource.MIC;
private int sampleRate = 22050;
private int channel = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int encoding = AudioFormat.ENCODING_PCM_16BIT;
private int result = 0;
private int bufferSize;
private byte[] buffer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("onCreate", "layout set, about to init audiorec obj");
text = (TextView)findViewById(R.id.TextView01);
bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding);
buffer = new byte[bufferSize];
recorder = new AudioRecord(audioSource, sampleRate,channel,encoding,
AudioRecord.getMinBufferSize(sampleRate, channel,encoding));
Log.i("recorder obj state",""+recorder.getRecordingState());
}
public void onClickPlay(View v){
}
public void record(){
Log.i("inside record method", "******");
File path = Environment.getExternalStorageDirectory();
Log.v("file path", ""+path.getAbsolutePath());
File file = new File(path, "test.wav");
if(file.exists()){
file.delete();
}
path.mkdirs();
Log.v("file path", ""+file.getAbsolutePath());
try {
os = new FileOutputStream(file);
bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
} catch (Exception e1) {
e1.printStackTrace();
}
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding);
byte[] buffer = new byte[bufferSize];
recorder.startRecording();
isRecording = true;
try{
while (isRecording){
result = recorder.read(buffer, 0, bufferSize);
for(int a=0; a<result;a++){
dos.write(buffer[a]);
if(!isRecording){
recorder.stop();
break;
}
}
}
dos.flush();
dos.close();
}catch(Exception e){
e.printStackTrace();
}
}// end of record method
public void onClickStop(View v){
Log.v("onClickStop", "stop clicked");
isRecording=false;
}
public void onClickReverse(View v){
Log.v("onClickReverse", "reverse clicked");
}
public void onClickRecord(View v){
Log.v("onClickRecourd", "record clicked, thread gona start");
text.setText("recording");
thread = new Thread(new Runnable() {
public void run() {
isRecording = true;
record();
}
});
thread.start();
isRecording = false;
}
}//end of class
Logcat
01-30 15:23:16.724: ERROR/AudioRecord(12817): Could not get audio input for record source 1 01-30 15:23:16.729:
ERROR/AudioRecord-JNI(12817): Error creating AudioRecord instance: initialization check failed. 01-30 15:23:16.729:
ERROR/AudioRecord-Java(12817): [ android.media.AudioRecord ] Error code
-20 when initializing native AudioRecord object. 01-30 15:23:16.729: INFO/recorder obj state(12817): 1 01-30 15:23:16.729:
WARN/dalvikvm(12817): threadid=13: thread exiting with uncaught exception (group=0x4001b180) 01-30 15:23:16.729:
ERROR/AndroidRuntime(12817): Uncaught handler: thread Thread-7 exiting due to uncaught exception 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord. 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at android.media.AudioRecord.startRecording(AudioRecord.java:495) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at com.tecmark.recorder.record(recorder.java:114) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at com.tecmark.recorder$1.run(recorder.java:175) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at java.lang.Thread.run(Thread.java:1096)
Ahora, con lollipop, debe pedirle específicamente al usuario cada permiso. Asegúrate de que el permiso sea otorgado.
Creo que esto tiene que ver con el hilo sin saber que has pausado la actividad principal y aún intentas grabar después de que hayas detenido la grabadora.
Lo resolví cambiando mis métodos onResume () y onPause () para modificar el booleano isRecording.
public void onResume() {
...
isRecording = true;
}
public void onPause() {
...
isRecording = false;
}
Luego, en su hilo, rodee su startRecording()
y stop()
con if-statements buscando isRecording:
if(isRecording)
recorder.startRecording();
...
if(isRecording)
recorder.stop(); // which you''ve done
El problema con la inicialización de algunos objetos AudioRecord podría ser corregido utilizando audioRecord.release();
antes de crear el siguiente objeto ... Más aquí: Android AudioRecord - No iniciará la segunda vez
El truco con el uso de AudioRecord es que cada dispositivo puede tener diferentes configuraciones de inicialización, por lo que tendrá que crear un método que recorra todas las combinaciones posibles de tasas de bits, codificación, etc.
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
try {
Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
return recorder;
}
} catch (Exception e) {
Log.e(C.TAG, rate + "Exception, keep trying.",e);
}
}
}
}
return null;
}
AudioRecord recorder = findAudioRecord();
recorder.release();
Incluso después de hacer todos los pasos anteriores estaba teniendo el mismo problema, lo que funcionó para mí fue que mi sistema operativo era malvavisco y tuve que pedirle permiso .
Me di cuenta de que cuando la tarjeta SD en el avd estoy ejecutando se llena, el constructor AudioRecord devuelve nulo. ¿Has intentado borrar la tarjeta SD?
Reescribí la respuesta de @DustinB para cualquiera que esté usando Xamarin Android AudioRecord con C #.
int[] sampleRates = new int[] { 44100, 22050, 11025, 8000 };
Encoding[] encodings = new Encoding[] { Encoding.Pcm8bit, Encoding.Pcm16bit };
ChannelIn[] channelConfigs = new ChannelIn[]{ ChannelIn.Mono, ChannelIn.Stereo };
//Not all of the formats are supported on each device
foreach (int sampleRate in sampleRates)
{
foreach (Encoding encoding in encodings)
{
foreach (ChannelIn channelConfig in channelConfigs)
{
try
{
Console.WriteLine("Attempting rate " + sampleRate + "Hz, bits: " + encoding + ", channel: " + channelConfig);
int bufferSize = AudioRecord.GetMinBufferSize(sampleRate, channelConfig, encoding);
if (bufferSize > 0)
{
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(AudioSource.Mic, sampleRate, channelConfig, encoding, bufferSize);
if (recorder.State == State.Initialized)
{
mBufferSize = bufferSize;
mSampleRate = sampleRate;
mChannelConfig = channelConfig;
mEncoding = encoding;
recorder.Release();
recorder = null;
return true;
}
}
}
catch (Exception ex)
{
Console.WriteLine(sampleRate + "Exception, keep trying." + ex.Message);
}
}
}
}
Según los javadocs, se garantiza que todos los dispositivos admiten este formato (para grabación):
44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT.
Cambie a CHANNEL_OUT_MONO para la reproducción.
Si su sistema de teléfono móvil es Android M o superior, tal vez necesite aplicar permiso de grabación de audio en Android M. http://developer.android.com/guide/topics/security/permissions.html
Solo tuve el mismo problema. La solución fue reiniciar el dispositivo. Mientras jugaba con el código, no solté el objeto AudioRecord, que obviamente causó que el dispositivo de audio se quedara atascado. Para probar si el dispositivo de audio funcionaba o no, descargué Audalyzer de Google Play.
Tuve el mismo problema, se resolvió poniendo
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
en el manifiesto
Desde Lollipop, también debe pedirle específicamente al usuario cada permiso. Como pueden haberlos revocado. Asegúrate de que el permiso sea otorgado.
en mi caso, tuve que permitir manualmente el permiso en android 7 para micrófono, como comentó sean zhu.