Android AudioRecord启动报错status -38 如何解决?
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
AudioManagerto 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_AUDIOdynamically 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

