2010-12-19 31 views
12

Mein Problem ist einfach zu erklären - Ich versuche ein AudioRecord-Objekt zu erstellen, aber es kann nicht initialisiert werden (dh nach dem Konstruktor gibt getState 0 zurück, was auf einen Fehler hinweist). Ich starte das von Eclipse auf einem MotoDroid 1 mit OS 2.2.1. Mein AndroidManifest.xml ist, AFAIK, die richtige Erlaubnis verwenden, RECORD_AUDIO (ich weiß nicht, wie dies zu bestätigen):Android AudioRecord-Initialisierung schlägt jedes Mal fehl

<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> 

ich die im Anschluss an die AudioRecord zu erstellen:

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() gibt 0 (dh STATE_UNINITIALIZED) zurück

Ich habe keine vollständigen Beispiele für die Verwendung dieser API gefunden, und ich bin sehr ein Android-Anfänger, so dass die Lösung durchaus etwas Einfaches sein kann. Was kann ich tun, um herauszufinden, warum es scheitert?

Ein paar Leute haben ähnliche Fragen gestellt, aber sie müssen andere Probleme haben als ich, weil die Korrekturen, die sie genehmigen, mir nicht geholfen haben. Am bemerkenswertesten ist this. Aber die genehmigte Lösung ist verwirrend und funktionierte für mich sowieso nicht. Ich habe auch eine Vielzahl von Bitraten (8000, 16000, 11025, 44100), sowohl Mono und Stereo und 8 und 16 Bit versucht. Keine Kombination kommt als erfolgreich initialisiert zurück.

+1

was sagt logcat? Versuchen Sie auch, Anwendungen zu verschieben, die nicht verwendet werden. afaik sollte es in manifest sitzen. – techiServices

+1

Aus irgendeinem Grund hat LogCat nach einigen Runs die meisten Log-Informationen nicht mehr angezeigt - aber das ist ein ganz anderes Problem. Ich würde Ihren Gebrauch-Erlaubniskommentar als die Antwort kennzeichnen ... wenn es eins war (weil es funktionierte!) – Dave

Antwort

36

Ich verbrachte einige Stunden dieses Problem zu lösen, und fanden heraus, dass

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

außen bewegt der Anwendungsblock hat es tatsächlich gelöst!

... 
    </application> 

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

Durch Verschieben des Benutzerberechtigungsknotens nach außen wird er gelöst. Danke Mann! –

1

Versuchen Sie 16bit. Dies ist, was für mich funktioniert:

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"); 
    } 

Und ich habe die folgenden Variablen gesetzt:

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

Ich arbeitete mit diesem heute und fand, dass es einen großen Unterschied macht, wenn Sie audioRecord.release() aufrufen Am Ende. Anscheinend wird das Objekt erst freigegeben, wenn Sie dies tun. Aus irgendeinem Grund, auch wenn audioRecord.release() am Ende eines Codes aufgerufen wird, wird es tatsächlich beim ersten Versuch funktionieren, sobald es eingefügt wird. Ich habe experimentiert und verstehe das nicht, aber ich habe herausgefunden, dass es hilft Big-Time mit der Initialisierung. – chaimp

+0

Wenn Sie die App Audalyzer herunterladen und versuchen, sie auszuführen, und sie eingefroren ist, haben Sie wahrscheinlich Ihre AudioRecord-Ressourcen gebunden. Neustart des Telefons behebt das. – chaimp

5

Ein weiteres mögliches Problem:

Ich hatte die RECORD_AUDIO Erlaubnis in meinem Manifest aktiviert, aber für die API-Level 23 musste ich auch die Erlaubnis zur Laufzeit beantragen.

+0

Wie haben Sie zur Laufzeit eine Berechtigung angefordert? – Fer

0

Falls jemand manuell Festplattenrechte für API 23+ anfordern muss, hier ist eine Methode, die ich verwendet habe. Tauschen Sie einfach permission.RECORD_AUDIO in den entsprechenden Bits ein. Die Methodenlogik hängt von ein paar Bits ab, die extern sind (z. B. strings.xml, ActivityCompat, Snackbar), aber ich denke, dass es sowieso jemandem helfen könnte.

/** 
* 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); 
     } 

    } 
} 
Verwandte Themen