Stay organized with collections
Save and categorize content based on your preferences.
Callback
abstract class Callback
Callbacks for the projection session.
Summary
Public methods |
open Unit |
Invoked immediately after capture begins or when the size of the captured region changes, providing the accurate sizing for the streamed capture.
|
open Unit |
Invoked immediately after capture begins or when the visibility of the captured region changes, providing the current visibility of the captured region.
|
open Unit |
Called when the MediaProjection session has been stopped and is no longer valid.
|
Public constructors
Public methods
onCapturedContentResize
open fun onCapturedContentResize(
width: Int,
height: Int
): Unit
Invoked immediately after capture begins or when the size of the captured region changes, providing the accurate sizing for the streamed capture.
The given width and height, in pixels, corresponds to the same width and height that would be returned from android.view.WindowMetrics#getBounds()
of the captured region.
If the recorded content has a different aspect ratio from either the VirtualDisplay
or output Surface
, the captured stream has letterboxing (black bars) around the recorded content. The application can avoid the letterboxing around the recorded content by updating the size of both the VirtualDisplay
and output Surface
:
@Override
public String onCapturedContentResize(int width, int height) {
// VirtualDisplay instance from MediaProjection#createVirtualDisplay
virtualDisplay.resize(width, height, dpi);
// Create a new Surface with the updated size (depending on the application's use
// case, this may be through different APIs - see Surface documentation for
// options).
int texName; // the OpenGL texture object name
SurfaceTexture surfaceTexture = new SurfaceTexture(texName);
surfaceTexture.setDefaultBufferSize(width, height);
Surface surface = new Surface(surfaceTexture);
// Ensure the VirtualDisplay has the updated Surface to send the capture to.
virtualDisplay.setSurface(surface);
}
onCapturedContentVisibilityChanged
open fun onCapturedContentVisibilityChanged(isVisible: Boolean): Unit
Invoked immediately after capture begins or when the visibility of the captured region changes, providing the current visibility of the captured region.
Applications can take advantage of this callback by showing or hiding the captured content from the output Surface
, based on if the captured region is currently visible to the user.
For example, if the user elected to capture a single app (from the activity shown from MediaProjectionManager.createScreenCaptureIntent()
), the following scenarios trigger the callback:
- The captured region is visible (
isVisible
with value true
), because the captured app is at least partially visible. This may happen if the user moves the covering app to show at least some portion of the captured app (e.g. the user has multiple apps visible in a multi-window mode such as split screen).
- The captured region is invisible (
isVisible
with value false
) if it is entirely hidden. This may happen if another app entirely covers the captured app, or the user navigates away from the captured app.
onStop
open fun onStop(): Unit
Called when the MediaProjection session has been stopped and is no longer valid.
Once a MediaProjection has been stopped, it's up to the application to release any resources it may be holding (e.g. releasing the VirtualDisplay
and Surface
). If the application is displaying any UI indicating the MediaProjection state it should be updated to indicate that MediaProjection is no longer active.
MediaProjection stopping can be a result of the system stopping the ongoing MediaProjection due to various reasons, such as another MediaProjection session starting, a user stopping the session via UI affordances in system-level UI, or the screen being locked.
After this callback any call to MediaProjection.createVirtualDisplay
will fail, even if no such VirtualDisplay
was ever created for this MediaProjection session.
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-02-10 UTC.
[null,null,["Last updated 2025-02-10 UTC."],[],[],null,["# MediaProjection.Callback\n\nAdded in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)\n\nCallback\n========\n\n*** ** * ** ***\n\nKotlin \\|[Java](/reference/android/media/projection/MediaProjection.Callback \"View this page in Java\") \n\n```\nabstract class Callback\n```\n\n|---|--------------------------------------------------------|\n| [kotlin.Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html) ||\n| ↳ | [android.media.projection.MediaProjection.Callback](#) |\n\nCallbacks for the projection session.\n\nSummary\n-------\n\n| Public constructors ||\n|------------------------------------|---|\n| [Callback](#Callback())`()` \u003cbr /\u003e |\n\n| Public methods ||\n|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| open [Unit](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) | [onCapturedContentResize](#onCapturedContentResize(kotlin.Int,%20kotlin.Int))`(`width:` `[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)`, `height:` `[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)`)` Invoked immediately after capture begins or when the size of the captured region changes, providing the accurate sizing for the streamed capture. |\n| open [Unit](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) | [onCapturedContentVisibilityChanged](#onCapturedContentVisibilityChanged(kotlin.Boolean))`(`isVisible:` `[Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)`)` Invoked immediately after capture begins or when the visibility of the captured region changes, providing the current visibility of the captured region. |\n| open [Unit](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) | [onStop](#onStop())`()` Called when the MediaProjection session has been stopped and is no longer valid. |\n\nPublic constructors\n-------------------\n\n### Callback\n\n```\nCallback()\n```\n\nPublic methods\n--------------\n\n### onCapturedContentResize\n\nAdded in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels) \n\n```\nopen fun onCapturedContentResize(\n width: Int, \n height: Int\n): Unit\n```\n\nInvoked immediately after capture begins or when the size of the captured region changes, providing the accurate sizing for the streamed capture.\n\nThe given width and height, in pixels, corresponds to the same width and height that would be returned from [android.view.WindowMetrics#getBounds()](../../view/WindowMetrics.html#getBounds()) of the captured region.\n\nIf the recorded content has a different aspect ratio from either the [VirtualDisplay](../../hardware/display/VirtualDisplay.html#) or output [Surface](../../view/Surface.html#), the captured stream has letterboxing (black bars) around the recorded content. The application can avoid the letterboxing around the recorded content by updating the size of both the [VirtualDisplay](../../hardware/display/VirtualDisplay.html#) and output [Surface](../../view/Surface.html#): \n\n```kotlin\n@Override\n public String onCapturedContentResize(int width, int height) {\n // VirtualDisplay instance from MediaProjection#createVirtualDisplay\n virtualDisplay.resize(width, height, dpi);\n \n // Create a new Surface with the updated size (depending on the application's use\n // case, this may be through different APIs - see Surface documentation for\n // options).\n int texName; // the OpenGL texture object name\n SurfaceTexture surfaceTexture = new SurfaceTexture(texName);\n surfaceTexture.setDefaultBufferSize(width, height);\n Surface surface = new Surface(surfaceTexture);\n \n // Ensure the VirtualDisplay has the updated Surface to send the capture to.\n virtualDisplay.setSurface(surface);\n }\n``` \n\n### onCapturedContentVisibilityChanged\n\nAdded in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels) \n\n```\nopen fun onCapturedContentVisibilityChanged(isVisible: Boolean): Unit\n```\n\nInvoked immediately after capture begins or when the visibility of the captured region changes, providing the current visibility of the captured region.\n\nApplications can take advantage of this callback by showing or hiding the captured content from the output [Surface](../../view/Surface.html#), based on if the captured region is currently visible to the user.\n\nFor example, if the user elected to capture a single app (from the activity shown from [MediaProjectionManager.createScreenCaptureIntent()](/reference/kotlin/android/media/projection/MediaProjectionManager#createScreenCaptureIntent())), the following scenarios trigger the callback:\n\n- The captured region is visible (`isVisible` with value `true`), because the captured app is at least partially visible. This may happen if the user moves the covering app to show at least some portion of the captured app (e.g. the user has multiple apps visible in a multi-window mode such as split screen).\n- The captured region is invisible (`isVisible` with value `false`) if it is entirely hidden. This may happen if another app entirely covers the captured app, or the user navigates away from the captured app. \n\n### onStop\n\nAdded in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels) \n\n```\nopen fun onStop(): Unit\n```\n\nCalled when the MediaProjection session has been stopped and is no longer valid.\n\nOnce a MediaProjection has been stopped, it's up to the application to release any resources it may be holding (e.g. releasing the [VirtualDisplay](../../hardware/display/VirtualDisplay.html#) and [Surface](../../view/Surface.html#)). If the application is displaying any UI indicating the MediaProjection state it should be updated to indicate that MediaProjection is no longer active.\n\nMediaProjection stopping can be a result of the system stopping the ongoing MediaProjection due to various reasons, such as another MediaProjection session starting, a user stopping the session via UI affordances in system-level UI, or the screen being locked.\n\nAfter this callback any call to [MediaProjection.createVirtualDisplay](/reference/kotlin/android/media/projection/MediaProjection#createVirtualDisplay(kotlin.String,%20kotlin.Int,%20kotlin.Int,%20kotlin.Int,%20kotlin.Int,%20android.view.Surface,%20android.hardware.display.VirtualDisplay.Callback,%20android.os.Handler)) will fail, even if no such [VirtualDisplay](../../hardware/display/VirtualDisplay.html#) was ever created for this MediaProjection session."]]