# Receive a screen share
When another participant starts, pauses, resumes, or stops sharing, the Video SDK for Android fires `onUserShareStatusChanged` on your `ZoomVideoSDKDelegate`. Render the incoming share by attaching a `ZoomVideoSDKVideoView` to your layout and subscribing it to the share canvas.
Confirmation that the _local_ user's own share started successfully comes from the return value of `startShareScreen` and the `onFailedToStartShare` callback.
## Add a share view to your layout
Place a `ZoomVideoSDKVideoView` in the layout you want to render shares into.
```xml
```
You'll attach a `ZoomVideoSDKVideoView` to this container at runtime when a share starts, and remove it when the share stops.
## Listen for share status changes
The callback receives the user whose share state changed and a `ZoomVideoSDKShareAction` describing the change.
```kotlin
private val shareViews = mutableMapOf()
override fun onUserShareStatusChanged(
shareHelper: ZoomVideoSDKShareHelper,
userInfo: ZoomVideoSDKUser,
shareAction: ZoomVideoSDKShareAction
) {
val container = findViewById(R.id.share_container)
val userId = userInfo.userID
when (shareAction.shareStatus) {
ZoomVideoSDKShareStatus.ZoomVideoSDKShareStatus_Start -> {
val videoView = ZoomVideoSDKVideoView(this)
container.addView(videoView)
shareViews[userId] = videoView
shareAction.shareCanvas.subscribe(
videoView,
ZoomVideoSDKVideoAspect.ZoomVideoSDKVideoAspect_Original,
ZoomVideoSDKVideoResolution.ZoomVideoSDKResolution_Auto
)
}
ZoomVideoSDKShareStatus.ZoomVideoSDKShareStatus_Stop -> {
shareViews.remove(userId)?.let {
shareAction.shareCanvas.unSubscribe(it)
container.removeView(it)
}
}
ZoomVideoSDKShareStatus.ZoomVideoSDKShareStatus_Pause,
ZoomVideoSDKShareStatus.ZoomVideoSDKShareStatus_Resume,
ZoomVideoSDKShareStatus.ZoomVideoSDKShareStatus_None -> {
// No subscription change — see the table below.
}
}
}
```
```java
private final Map shareViews = new HashMap<>();
@Override
public void onUserShareStatusChanged(
ZoomVideoSDKShareHelper shareHelper,
ZoomVideoSDKUser userInfo,
ZoomVideoSDKShareAction shareAction
) {
FrameLayout container = findViewById(R.id.share_container);
String userId = userInfo.getUserID();
switch (shareAction.getShareStatus()) {
case ZoomVideoSDKShareStatus_Start: {
ZoomVideoSDKVideoView videoView = new ZoomVideoSDKVideoView(this);
container.addView(videoView);
shareViews.put(userId, videoView);
shareAction.getShareCanvas().subscribe(
videoView,
ZoomVideoSDKVideoAspect.ZoomVideoSDKVideoAspect_Original,
ZoomVideoSDKVideoResolution.ZoomVideoSDKResolution_Auto
);
break;
}
case ZoomVideoSDKShareStatus_Stop: {
ZoomVideoSDKVideoView videoView = shareViews.remove(userId);
if (videoView != null) {
shareAction.getShareCanvas().unSubscribe(videoView);
container.removeView(videoView);
}
break;
}
case ZoomVideoSDKShareStatus_Pause:
case ZoomVideoSDKShareStatus_Resume:
case ZoomVideoSDKShareStatus_None:
// No subscription change — see the table below.
break;
}
}
```
Tracking views in a per-user map makes it easy to attach and detach them as users start and stop sharing, and to find them later in the lifecycle callbacks covered below.
### Share status values
The `onUserShareStatusChanged` callback reports the share state as a `ZoomVideoSDKShareStatus` value. Each value tells you whether to subscribe the view, keep it, or tear it down.
| Status | When it fires | What to do |
| -------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `ZoomVideoSDKShareStatus_Start` | The user began sharing. | Subscribe the share canvas to a `ZoomVideoSDKVideoView` and add the view to your layout. |
| `ZoomVideoSDKShareStatus_Pause` | The user paused the share. | Optionally dim or overlay the view. The last frame stays on screen. Keep the subscription. |
| `ZoomVideoSDKShareStatus_Resume` | The user resumed a paused share. | Clear any pause overlay you applied. Keep the subscription. |
| `ZoomVideoSDKShareStatus_Stop` | The user stopped sharing, either programmatically or via the system Media Projection notification. | Unsubscribe the view and remove it from your layout. |
| `ZoomVideoSDKShareStatus_None` | There is no active share for this user. | No action needed. This is typically the initial state. |
## Aspect mode and resolution
The `subscribe` call takes two enums that control how the share renders:
- `ZoomVideoSDKVideoAspect_Original` keeps the source aspect ratio with letterboxing if the view doesn't match. This is the safest default and what this topic uses.
- `ZoomVideoSDKVideoAspect_Full_Filled` fills the view, cropping if the aspect ratios disagree.
- `ZoomVideoSDKVideoAspect_LetterBox` and `ZoomVideoSDKVideoAspect_PanAndScan` give finer control. See the [video best practices](/docs/video-sdk/android/video/best-practices/#aspect-ratio-and-orientation) for guidance on choosing an aspect mode.
`ZoomVideoSDKResolution_Auto` lets the SDK pick the streaming resolution based on view size and network conditions. Force a specific resolution only if you have a clear reason. Pinning low when you have screen real estate hurts quality, and pinning high when you don't wastes bandwidth.
## React to dimension changes
When the sharer resizes their window, rotates their device, or otherwise changes the content dimensions, the SDK fires `onShareContentSizeChanged`. Read the new dimensions from the share action and re-layout your container if the aspect ratio is now different.
```kotlin
override fun onShareContentSizeChanged(shareAction: ZoomVideoSDKShareAction) {
val size = shareAction.shareSourceContentSize // ZoomVideoSDKViewSize
// Resize your container or the share view to match the new aspect.
}
```
```java
@Override
public void onShareContentSizeChanged(ZoomVideoSDKShareAction shareAction) {
ZoomVideoSDKViewSize size = shareAction.getShareSourceContentSize();
// Resize your container or the share view to match the new aspect.
}
```
## Handle subscription failures
If a share canvas subscription can't be established (for example, the share has already stopped between callback and subscribe, or the SDK hits a resource limit), the delegate fires `onShareCanvasSubscribeFail`. Surface the error to the user, remove the orphaned view from your layout, and consider retrying once.
```kotlin
override fun onShareCanvasSubscribeFail(
failReason: ZoomVideoSDKVideoSubscribeFailReason,
user: ZoomVideoSDKUser,
view: ZoomVideoSDKVideoView
) {
// Remove the view from your layout and surface the failure.
}
```
```java
@Override
public void onShareCanvasSubscribeFail(
ZoomVideoSDKVideoSubscribeFailReason failReason,
ZoomVideoSDKUser user,
ZoomVideoSDKVideoView view
) {
// Remove the view from your layout and surface the failure.
}
```
## Identify the share source
A share may be a screen, a camera, or a pure-audio stream. Read `getShareType()` on the action to identify which.
```kotlin
when (shareAction.shareType) {
ZoomVideoSDKShareType.ZoomVideoSDKShareType_Normal -> {
// Screen, application window, or external source.
}
ZoomVideoSDKShareType.ZoomVideoSDKShareType_Camera -> {
// The user is sharing a camera as content.
}
ZoomVideoSDKShareType.ZoomVideoSDKShareType_PureAudio -> {
// Audio-only share — no video frames, no canvas to subscribe.
}
ZoomVideoSDKShareType.ZoomVideoSDKShareType_None -> {}
}
```
```java
switch (shareAction.getShareType()) {
case ZoomVideoSDKShareType_Normal:
// Screen, application window, or external source.
break;
case ZoomVideoSDKShareType_Camera:
// The user is sharing a camera as content.
break;
case ZoomVideoSDKShareType_PureAudio:
// Audio-only share — no video frames, no canvas to subscribe.
break;
case ZoomVideoSDKShareType_None:
break;
}
```
Skip the canvas subscription when `shareType` is `ZoomVideoSDKShareType_PureAudio`. There are no frames to render.
The SDK also fires `onShareContentChanged` when a sharer _switches_ between source types (for example, from camera share to screen share) without stopping the share. Treat it as a signal to refresh anything you cached based on share type.
## Unsubscribe when your view goes away
Activity rotation, navigation, or tearing down a video tile all destroy `ZoomVideoSDKVideoView` instances. Always `unSubscribe` from the share canvas before the view is detached. Otherwise the SDK keeps holding a reference and you leak memory and bandwidth.
```kotlin
override fun onDestroy() {
val container = findViewById(R.id.share_container)
shareViews.forEach { (userId, view) ->
// Find the user and unsubscribe from their share canvas.
ZoomVideoSDK.getInstance().session.remoteUsers
.firstOrNull { it.userID == userId }
?.shareActionList
?.firstOrNull()
?.shareCanvas
?.unSubscribe(view)
container.removeView(view)
}
shareViews.clear()
super.onDestroy()
}
```
```java
@Override
protected void onDestroy() {
FrameLayout container = findViewById(R.id.share_container);
for (Map.Entry entry : shareViews.entrySet()) {
ZoomVideoSDKUser user = findUserById(entry.getKey());
if (user != null) {
List actions = user.getShareActionList();
if (!actions.isEmpty()) {
actions.get(0).getShareCanvas().unSubscribe(entry.getValue());
}
}
container.removeView(entry.getValue());
}
shareViews.clear();
super.onDestroy();
}
```
For the same reason, prefer keeping share-related state in a `ViewModel` so configuration changes (such as device rotation) don't tear down the share UI alongside the Activity. For the pattern, see the [Lifecycle](/docs/video-sdk/android/video/best-practices/#lifecycle) in the video best practices.
## Check whether anyone is sharing
Outside of the callback, you can also query whether any other participant is currently sharing, useful when joining a session in progress.
```kotlin
val otherSharing = ZoomVideoSDK.getInstance().shareHelper.isOtherSharing
```
```java
boolean otherSharing = ZoomVideoSDK.getInstance().getShareHelper().isOtherSharing();
```
If multiple users may be sharing at the same time, see [Handle Multiple Screen Shares](/docs/video-sdk/android/share/handle-multiple-shares/) for how to pick which share to subscribe to. To draw on a share you're viewing, see [Annotation](/docs/video-sdk/android/share/annotation/).