You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android AudioRecord启动报错status -38 如何解决?

AudioRecord start() status -38: How to resolve audio source conflict and read() returning 0

I’ve run into this exact -38 error with AudioRecord before—it’s almost always tied to audio device resource conflicts or issues with the recording session initialization that don’t throw an explicit exception (which is why you only see the log instead of a crash). Let’s break down what’s happening and how to fix it:

What does status -38 mean?

While the official Android docs don’t explicitly list -38, this error code maps to underlying native audio layer issues—usually that the requested audio source (your microphone) is already in use by another app/service, or the AudioRecord instance failed to properly acquire the audio hardware lock. The read() returning 0 confirms this: the recording session never actually started, so there’s no data to read.

Step-by-step fixes and code adjustments

1. Enforce proper AudioRecord lifecycle management

Your code releases the AudioRecord in a finally block, but you need to ensure no existing AudioRecord instances are lingering before creating a new one. Add checks to avoid duplicate instances:

  • Track a global flag or reference to your running AudioRecordRunnable
  • Before initializing a new AudioRecord, verify any previous instances were fully stopped and released

Also, add a check right after startRecording() to confirm the recording session is active (this catches silent failures like the -38 error):

mAudioRecord.startRecording();
// Add this validation
if (mAudioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
    Log.e(TAG, "Failed to start recording - session not active (status -38 likely)");
    mAudioDataCallback.onError();
    return;
}

2. Check for microphone resource conflicts

  • Verify no other apps are using the mic: On Android 11+, you can use AudioManager to check mic availability directly:
    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    if (!audioManager.isRecordingAllowed()) {
        Log.e(TAG, "Microphone is occupied by another app");
        mAudioDataCallback.onError();
        return;
    }
    
  • Ensure permissions are granted: For Android 6.0+, you must request RECORD_AUDIO dynamically before initializing AudioRecord. Add this check before starting your runnable:
    if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) 
        != PackageManager.PERMISSION_GRANTED) {
        Log.e(TAG, "RECORD_AUDIO permission not granted");
        mAudioDataCallback.onError();
        return;
    }
    

3. Fix buffer size alignment (minor but critical)

Your buffer size logic is mostly correct, but ensure byteBufferSize is a multiple of the frame size (for 16-bit PCM, that’s 2 bytes per sample per channel). A misaligned buffer can cause silent initialization failures. Update your buffer calculation to enforce this:

int frameSize = (channelConfig == AudioFormat.CHANNEL_IN_MONO ? 1 : 2) * (mAudioFormat == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1);
mByteBufferSize = ((byteBufferSize + frameSize - 1) / frameSize) * frameSize; // Align to frame size
mShortBufferSize = mByteBufferSize / 2;

4. Handle the -38 error explicitly in your error handler

Update your onError method to catch this unlisted error code and add actionable logging:

private void onError(int errorCode) {
    mAudioDataCallback.onError();
    Log.w(TAG, "record fail: " + String.valueOf(errorCode));
    if (errorCode == -38) {
        Log.w(TAG, "record fail: Audio source is occupied or unavailable (STATUS_NO_INIT)");
        // Optional: Add retry logic with a delay (e.g., 500ms) to avoid spamming
    } else if (errorCode == AudioRecord.ERROR_INVALID_OPERATION) {
        Log.w(TAG, "record fail: ERROR_INVALID_OPERATION");
    } else if (errorCode == AudioRecord.ERROR_BAD_VALUE) {
        Log.w(TAG, "record fail: ERROR_BAD_VALUE");
    }
}

5. Avoid creating AudioRecord instances on the fly

Your current code creates a new AudioRecord in the runnable constructor. Instead, consider reusing a single instance (if your use case allows) or ensuring that after stopping, you clear all references to allow garbage collection—lingering instances can hold onto the mic resource.

Final notes

The -38 error is tricky because it doesn’t throw an exception, but adding these checks will help you catch the root cause early. Always test on multiple devices—some manufacturers have stricter audio resource management that can trigger this error more easily.


内容的提问来源于stack exchange,提问作者miibpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:35:53