# 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/).