Screen recording shows black screen when "Screen sharing protection" notification appears on Android 16
When I start screen recording using MediaProjection API, whenever
the "Screen sharing protection" system notification appears, the
recording goes black for that moment. No password fields or secure
windows are present on screen at that time.
Permission Request
val config = MediaProjectionConfig.createConfigForDefaultDisplay()
val permissionIntent = mediaProjectionManager.createScreenCaptureIntent(config)
startActivityForResult(permissionIntent, SCREEN_RECORD_REQUEST_CODE)
Virtual Display
mVirtualDisplay = mMediaProjection?.createVirtualDisplay(
"ScreenRecorder",
mScreenWidth,
mScreenHeight,
mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder?.surface,
null,
null
)
MediaProjection Callback
mMediaProjection?.registerCallback(object : MediaProjection.Callback() {
override fun onCapturedContentVisibilityChanged(isVisible: Boolean) {
Log.d(TAG, "isVisible=$isVisible") // Always returns TRUE
}
}, handler)
Apps like XRecorder and AZ Screen Recorder do NOT have this black
screen issue on same device. They also choose "entire screen" but
recording stays smooth without any black frames when system
notification appears.
What you’re experiencing is expected behavior on newer Android versions, especially Android 14 and above (including 15/16). It’s not a bug in your implementation.
When you use the MediaProjection API to record the screen, Android applies additional privacy protections at the system level. If the system decides that a protected or privacy-sensitive layer is being shown, even briefly, it can temporarily blank out the captured output. The “Screen sharing protection” notification is part of that internal privacy mechanism. Even if there are no password fields, no secure windows, and your onCapturedContentVisibilityChanged() callback always returns true, the system compositor can still decide to suppress the frame.
What’s important to understand is that this happens below your app layer. The blank frame is introduced by the system’s rendering pipeline (SurfaceFlinger), not by your MediaProjection setup. When a protected system overlay appears:
The compositor detects a protected layer.
MediaProjection output is temporarily muted.
Your VirtualDisplay receives a black frame buffer.
Recording resumes normally right after.
This is intentional behavior from the OS and cannot be disabled by third-party apps.
You might wonder why apps like XRecorder and AZ Screen Recorder don’t seem to show this issue on the same device. There are a few likely reasons.
One possibility is frame buffering. Those apps may cache the last valid frame and, if a black frame appears, simply reuse the previous frame instead of encoding the black one. To the user, the recording looks smooth and uninterrupted.
Another possibility is that they use a lower-level recording pipeline. Instead of relying purely on MediaRecorder, they may use MediaCodec with manual frame handling. This gives them control over individual frames, allowing them to inspect and filter frames before encoding.
There’s also the possibility that some commercial screen recorders use manufacturer-level privileges or hidden APIs on certain devices. These capabilities are not available to normal third-party apps distributed through standard channels.
To directly answer your questions:
Because Android’s privacy system temporarily blanks MediaProjection output when certain protected system overlays are displayed. This is enforced at the system compositor level, not in your app logic.
You cannot disable this protection. Android does not provide a way to bypass it, and attempting to do so would violate platform security rules.
However, you can reduce the visible impact by:
Switching from MediaRecorder to MediaCodec so you can access frame buffers directly.
Detecting fully black frames before encoding.
Skipping those frames or reusing the last valid frame.
Implementing simple frame caching so that short blank periods are visually masked.
This is likely what polished commercial recorders are doing.
Finally, regarding your callback: onCapturedContentVisibilityChanged(true) does not indicate whether frames are being blanked. It only tells you whether the captured content is currently visible to the user. It does not reflect internal compositor suppression.
Aqsa