Screen Share - Android
Screen sharing in a meeting is the process of sharing your mobile screen with other participants in the meeting. It allows everyone in the meeting to see exactly what you are seeing on your screen, which can be helpful for presentations, demonstrations, or collaborations.
How Screen share works?
- The following diagram shows flow of the screen sharing in android using VideoSDK :
 

enableScreenShare()
- 
By using
enableScreenShare()function ofMeetingclass, local participant can share his/her mobile screen to other participants. - 
You can pass customised screenshare track in
enableScreenShare()by using Custom Screen Share Track. - 
Screen Share stream of the participant can be accessed from the
onStreamEnabledevent ofParticipantEventListener. 
System Audio with Screen Share
- 
System Audio Sharing during screen sharing, allowing users to share both the screen and the audio from their device simultaneously.
 - 
Boolean enableAudio: In theenableScreenShare()method, the second parameter,enableAudio, is a flag that controls whether system audio is shared. Set it totrueto include system audio with the screen share, orfalseto share only the screen without audio. - 
Ensure that you request the necessary permissions (
android.permission.RECORD_AUDIO) for screen sharing and system audio capture on the user's device. The required permissions may vary based on the Android version and device manufacturer. - 
Devices running
Android 9(API Level 28) or below will not support the System Audio sharing feature.noteSystem audio will only work when the microphone is on. If the microphone is muted, the system audio will also be muted.
 
Screenshare permission
- 
A participant’s Screen share stream is provided via the
MediaProjectionAPI. This API is only compatible withBuild.VERSION_CODES.LOLLIPOPor higher. - 
Get an instance of the
MediaProjectionManagerand Call thecreateScreenCaptureIntent()method in an activity. This initiates a prompt dialog for the user to confirm screen projection. - 
One will get a prompt dialog like this:
 

- After permission is received from the user, you can call 
enableScreenShare()method. 
- Kotlin
 - Java
 
private fun enableScreenShare() {
    val mediaProjectionManager = application.getSystemService(
        MEDIA_PROJECTION_SERVICE
    ) as MediaProjectionManager
    startActivityForResult(
        mediaProjectionManager.createScreenCaptureIntent(), CAPTURE_PERMISSION_REQUEST_CODE
    )
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode != CAPTURE_PERMISSION_REQUEST_CODE) return
    if (resultCode == RESULT_OK) {
        // Enabling screen share
        meeting!!.enableScreenShare(data, true) // enableAudio = true: Enables system audio sharing
    }
}
private void enableScreenShare() {
    MediaProjectionManager mediaProjectionManager =
        (MediaProjectionManager) getApplication().getSystemService(
            Context.MEDIA_PROJECTION_SERVICE);
    startActivityForResult(
        mediaProjectionManager.createScreenCaptureIntent(), CAPTURE_PERMISSION_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode != CAPTURE_PERMISSION_REQUEST_CODE)
        return;
    if (resultCode == Activity.RESULT_OK) {
        // Enabling screen share
        meeting.enableScreenShare(data , true); // enableAudio = true: Enables system audio sharing
    }
}
Customise notification
- 
When a presenter starts screen share, presenter will receive a notification with a pre-defined title and message.
 - 
Notification with pre-defined title and message will look like this:
 

- You can Customise those title, message and icon as per your requirements using 
<meta-data>specified inapp/src/main/AndroidManifest.xml. 
<application>
  <meta-data
    android:name="notificationTitle"
    android:value="@string/notificationTitle"
  />
  <meta-data
    android:name="notificationContent"
    android:value="@string/notificationContent"
  />
  <meta-data
    android:name="notificationIcon"
    android:resource="@mipmap/ic_launcher_round"
  />
</application>
disableScreenShare()
- By using 
disableScreenShare()function ofMeetingclass, local participant can stop sharing his/her mobile screen to other participants. 
- Kotlin
 - Java
 
private fun disableScreenShare() {
    // Disabling screen share
    meeting!!.disableScreenShare()
}
private void disableScreenShare(){
    // Disabling screen share
    meeting.disableScreenShare();
}
Events associated with enableScreenShare
- 
Participant who share their mobile screen will receive a callback on
onStreamEnabled()of theParticipantwithStreamobject. - 
While other Participants will receive
onPresenterChanged()callback of theMeetingclass with the participantId aspresenterIdwho started the screen share. 
Events associated with disableScreenShare
- 
Participant who shared their mobile screen will receive a callback on
onStreamDisabled()of theParticipantwithStreamobject. - 
While other Participants will receive
onPresenterChanged()callback of theMeetingclass with thepresenterIdasnullindicating there is no presenter. 
- Kotlin
 - Java
 
private fun setLocalListeners() {
    meeting!!.localParticipant.addEventListener(object : ParticipantEventListener() {
        //Callback for when the participant starts a stream
        override fun onStreamEnabled(stream: Stream) {
           if (stream.kind.equals("share", ignoreCase = true)) {
              Log.d("VideoSDK","Share Stream On: onStreamEnabled $stream");
            }
        }
        //Callback for when the participant stops a stream
        override fun onStreamDisabled(stream: Stream) {
            if (stream.kind.equals("share", ignoreCase = true)) {
               Log.d("VideoSDK","Share Stream On: onStreamDisabled $stream");
            }
        }
    });
}
private val meetingEventListener: MeetingEventListener = object : MeetingEventListener() {
    //Callback for when the presenter changes
    override fun onPresenterChanged(participantId: String) {
        if(!TextUtils.isEmpty(participantId))
        {
          Log.d("VideoSDK","$participantId started screen share");
        }else{
          Log.d("VideoSDK","some one stopped screen share");
        }
    }
}
private void setLocalListeners() {
    meeting.getLocalParticipant().addEventListener(new ParticipantEventListener() {
        //Callback for when the participant starts a stream
        @Override
        public void onStreamEnabled(Stream stream) {
            if (stream.getKind().equalsIgnoreCase("share")) {
                Log.d("VideoSDK","Share Stream On: onStreamEnabled" + stream);
            }
        }
        //Callback for when the participant stops a stream
        @Override
        public void onStreamDisabled(Stream stream) {
            if (stream.getKind().equalsIgnoreCase("share")) {
                Log.d("VideoSDK","Share Stream Off: onStreamDisabled" + stream);
            }
        }
    });
}
private final MeetingEventListener meetingEventListener = new MeetingEventListener() {
    //Callback for when the presenter changes
    @Override
    public void onPresenterChanged(String participantId) {
      if(participantId != null){
        Log.d("VideoSDK",participantId + "started screen share");
      }else{
        Log.d("VideoSDK","some one stopped screen share");
      }
    }
};
Rendering Screen Share Stream
- When a local participant shares their screen, the 
onStreamEnabled()function of theParticipantEventListeneris triggered, allowing theStreamto be added to aVideoView. 
- Kotlin
 - Java
 
private fun setLocalListeners() {
    meeting!!.localParticipant.addEventListener(object : ParticipantEventListener() {
        override fun onStreamEnabled(stream: Stream) {
           if (stream.kind.equals("share", ignoreCase = true)) {
                // display share video
                val videoTrack = stream.track as VideoTrack
                shareView!!.addTrack(videoTrack)
            }
        }
        override fun onStreamDisabled(stream: Stream) {
            if (stream.kind.equals("share", ignoreCase = true)) {
               shareView!!.removeTrack()
            }
        }
    });
}
private void setLocalListeners() {
    meeting.getLocalParticipant().addEventListener(new ParticipantEventListener() {
        @Override
        public void onStreamEnabled(Stream stream) {
            if (stream.getKind().equalsIgnoreCase("share")) {
                // display share video
                VideoTrack videoTrack = (VideoTrack) stream.getTrack();
                shareView.addTrack(videoTrack);
            }
        }
        @Override
        public void onStreamDisabled(Stream stream) {
            if (stream.getKind().equalsIgnoreCase("share")) {
                shareView.removeTrack();
            }
        }
    });
}
- When another participant (excluding the local participant) shares their screen, the 
onPresenterChanged()function in theMeetingEventListeneris triggered, providing theparticipantIdof the screen sharer. 
- Kotlin
 - Java
 
private val meetingEventListener: MeetingEventListener = object : MeetingEventListener() {
    override fun onPresenterChanged(participantId: String) {
        updatePresenter(participantId)
    }
}
//Getting the stream from the participantId
private fun updatePresenter(participantId: String?) {
    // find participant
    val participant = meeting!!.participants.get(participantId) ?: return
    // find share stream in participant
    var shareStream: Stream? = null
    for (stream: Stream in participant.streams.values) {
        if ((stream.kind == "share")) {
            shareStream = stream
            break
        }
    }
    if (shareStream == null) return
    // display share video
    val videoTrack = shareStream.track as VideoTrack
    shareView!!.addTrack(videoTrack)
    // listen for share stop event
    participant.addEventListener(object : ParticipantEventListener() {
        override fun onStreamDisabled(stream: Stream) {
            if ((stream.kind == "share")) {
                shareView!!.removeTrack()
            }
        }
    })
}
private final MeetingEventListener meetingEventListener = new MeetingEventListener() {
    //Triggered when Presenter changes
    @Override
    public void onPresenterChanged(String participantId) {
        updatePresenter(participantId);
    }
};
//Getting the stream from the participantId
private void updatePresenter(String participantId) {
    // find participant
    Participant participant = meeting.getParticipants().get(participantId);
    if (participant == null) return;
    // find share stream in participant
    Stream shareStream = null;
    for (Stream stream: participant.getStreams().values()) {
        if (stream.getKind().equals("share")) {
            shareStream = stream;
            break;
        }
    }
    if (shareStream == null) return;
    // display share video
    VideoTrack videoTrack = (VideoTrack) shareStream.getTrack();
    shareView.addTrack(videoTrack)
    // listen for share stop event
    participant.addEventListener(new ParticipantEventListener() {
        @Override
        public void onStreamDisabled(Stream stream) {
            if (stream.getKind().equals("share")) {
                shareView.removeTrack();
            }
        }
    });
}
- Here screenShare stream is displayed using 
VideoView, but you may also useSurfaceViewRenderfor the same. - For 
VideoView, SDK version should be0.1.13or higher. - To know more about 
VideoView, please visit here 
API Reference
The API references for all the methods and events utilised in this guide are provided below.
Got a Question? Ask us on discord

