Android AudioRecord初始化每次都失败

我的问题很容易解释 – 我正在尝试创建一个AudioRecord对象,但它无法初始化(即在构造函数之后,getState返回0,表示失败)。 我在运行OS 2.2.1的MotoDroid 1上从Eclipse运行它。 我的AndroidManifest.xml是AFAIK,使用了正确的权限,RECORD_AUDIO(我不知道如何确认):

         

我执行以下操作来创建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()返回0(即STATE_UNINITIALIZED)

我还没有find任何使用这个API的完整示例,我非常喜欢Android初学者,所以解决方案可能很简单。 我该怎么做才能找出失败的原因?

有些人提出了类似的问题,但是他们一定遇到了与我不同的问题,因为他们批准的修复措施对我没有帮助。 最值得注意的是这个 。 但批准的解决方案令人困惑,无论如何都不适用于我。 我还尝试了各种比特率(8000,16000,11025,44100),单声道和立体声以及8和16比特。 成功初始化后没有组合回来。

我花了几个小时来解决这个问题,并发现了移动

  

在应用程序块之外实际解决了它!

 ...    

另一个问题是:

我在清单中启用了RECORD_AUDIO权限,但对于API级别23,我还必须在运行时请求权限。

试试16bit。 这对我有用:

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

我设置了以下variables:

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

如果有人需要手动为API 23+请求磁盘权限,这是我使用过的一种方法。 只需在相关位中交换permission.RECORD_AUDIO 。 方法逻辑依赖于外部的一些位(例如strings.xmlActivityCompatSnackbar ),但认为它可能对某人有帮助。

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