2010-12-19 14 views
12

Mi problema es simple de explicar: estoy intentando crear un objeto AudioRecord pero no se inicializa (es decir, después del constructor, getState devuelve 0, lo que indica una falla). Estoy ejecutando esto desde Eclipse en un MotoDroid 1 con SO 2.2.1. Mi AndroidManifest.xml es, que yo sepa, el uso de los permisos adecuados, RECORD_AUDIO (no sé cómo confirmar esto):La inicialización de Android AudioRecord falla cada vez

<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> 
    <uses-permission android:name="android.permission.RECORD_AUDIO"/> 
    <activity android:name=".SphinxMic" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

que hacer lo siguiente para crear el AudioRecord:

bufferSize = AudioRecord.getMinBufferSize(8000, CHANNEL_IN_MONO, ENCODING_PCM_8BIT); 
audioRecorder = new AudioRecord(AudioSource.MIC, 8000, CHANNEL_IN_MONO, ENCODING_PCM_8BIT, 50*bufferSize); 
if (audioRecorder.getState() != AudioRecord.STATE_INITIALIZED) 
    throw new Exception("AudioRecord init failed"); 

Audiorecorder .getState() devuelve 0 (es decir, STATE_UNINITIALIZED)

No he encontrado ningún ejemplo completo del uso de esta API y soy un principiante de Android por lo que la solución puede ser algo simple. ¿Qué puedo hacer para descubrir por qué falla?

Algunas personas han hecho preguntas similares, pero deben haber tenido problemas diferentes a los míos porque las correcciones que aprobaron no me han ayudado. Más notablemente this. Pero la solución aprobada es desconcertante y no funcionó para mí de todos modos. También he probado una variedad de velocidades de bits (8000, 16000, 11025, 44100), tanto mono como estéreo y 8 y 16 bits. Ninguna combinación regresa tan exitosamente inicializada.

+1

¿Qué significa logcat? también intente mover usos; permiso fuera de aplicación. afaik debe sentarse en manifiesto. – techiServices

+1

Por algún motivo, LogCat dejó de mostrar la mayoría de la información de registro después de algunas ejecuciones, pero ese es otro problema. Marcaría su comentario de permisos de uso como la respuesta ... si fuera uno (¡porque funcionó!) – Dave

Respuesta

36

Pasé unas horas la solución de este problema, y ​​descubrió que se mueve

<uses-permission android:name="android.permission.RECORD_AUDIO" /> 

fuera ¡el bloque de aplicación realmente lo resolvió!

... 
    </application> 

    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
</manifest> 
+0

Mover el nodo de permiso de usuario al exterior lo resuelve. Gracias hombre! –

1

Pruebe 16bit. Esto es lo que funciona para mí:

try { 
     // Create a new AudioRecord object to record the audio. 
     bufferSize = AudioRecord.getMinBufferSize(frequency,channelConfiguration,audioEncoding); 

     audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 
                frequency, channelConfiguration, 
                audioEncoding, bufferSize); 
    } catch (Throwable t) { 
     Log.e("AudioRecord","Recording Failed"); 
    } 

Y he puesto en las siguientes variables:

int frequency = 8000; 
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 
+1

Estaba trabajando con esto hoy y descubrí que hace una gran diferencia si llama a audioRecord.release() al final. Aparentemente, el objeto no se liberará hasta que lo hagas. Por alguna razón, incluso si se llama a audioRecord.release() al final de algún código, en realidad funcionará en el primer intento una vez que se haya insertado. He estado experimentando y no lo entiendo, pero he descubierto que ayuda grande con la inicialización. – chaimp

+0

Si descargas la aplicación Audalyzer e intentas ejecutarla y está congelada, es probable que tengas tus recursos de AudioRecord atados. Reiniciar el teléfono corrige eso. – chaimp

5

Otro posible problema:

tuve la RECORD_AUDIO permiso activado en mi manifiesto, pero para el nivel de API 23 tuve que solicitar el permiso también en tiempo de ejecución.

+0

¿cómo solicitó permiso en tiempo de ejecución? – Fer

0

En caso de que alguien necesite solicitar permisos de disco manualmente para API 23+, aquí hay un método que he usado. Simplemente intercambie permission.RECORD_AUDIO en los bits relevantes. La lógica del método depende de algunos bits que son externos (por ejemplo, strings.xml, ActivityCompat, Snackbar), pero pensó que podría ayudar a alguien de todos modos.

/** 
* Requests the Storage permissions. 
* If the permission has been denied previously, 
* a SnackBar will prompt the user to grant the 
* permission, otherwise it is requested directly. 
*/ 
private void requestStoragePermissions() { 

    // Newer versions Android 18+ 
    if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) { 
     /** 
     * Permissions required to read and write storage. 
     */ 
     final String[] PERMISSIONS_STORAGE = { 
       permission.READ_EXTERNAL_STORAGE, 
       permission.WRITE_EXTERNAL_STORAGE, 
     }; 

     final boolean readResult = 
       ActivityCompat.shouldShowRequestPermissionRationale(
         this, permission.READ_EXTERNAL_STORAGE); 
     final boolean writeResult = 
       ActivityCompat.shouldShowRequestPermissionRationale(
         this, permission.WRITE_EXTERNAL_STORAGE); 

     if (readResult || writeResult) { 

      // Provide an additional rationale to the user if the permission was not granted 
      // and the user would benefit from additional context for the use of the permission. 
      // For example, if the request has been denied previously. 
      Log.i(TAG, 
        "Displaying disk permission rationale to provide additional context."); 

      // Display a SnackBar with an explanation and a button to trigger the request. 
      Snackbar.make(mainView, R.string.permission_storage_rationale, 
        Snackbar.LENGTH_INDEFINITE) 
        .setAction(R.string.ok, new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          ActivityCompat 
            .requestPermissions(MainActivity.this, 
              PERMISSIONS_STORAGE, 
              REQUEST_STORAGE); 
         } 
        }) 
        .show(); 
     } else { 
      // Storage permissions have not been granted. Request them directly. 
      ActivityCompat.requestPermissions(
        this, PERMISSIONS_STORAGE, REQUEST_STORAGE); 
     } 

    } 
} 
Cuestiones relacionadas