startAnnotation method not working for customised UI

Description
startAnnotation method not working for customised UI

Which Client Android SDK version?
zoom-sdk-android-5.4.3.613

To Reproduce(If applicable)
Steps to reproduce the behavior:

  1. Go to ‘Using android sdk first set customised UI to true then enable waiting room and start meeting with params.’
  2. Start screen share with “startShareScreenSession” method. [We have disabled display over app permission to hide floating annotation button over app].
  3. After screen sharing starts, calling “startAnnotation” on our apps custom button press event.
  4. startAnnotation error: SDKERR_OTHER_ERROR, however canDoAnnotation flag is: true and isPresenter: false

Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • Device: [OnePlus6]
  • OS: [Android 10]
  • Version [Oxygen os 10.3.7]

Additional context
Code is as below:

Initialising SDK:

``ZoomSDK zoomSDK = ZoomSDK.getInstance();

ZoomSDKInitParams initParams = new ZoomSDKInitParams();
initParams.jwtToken = “ ”;
initParams.enableLog = true;
initParams.logSize = 50;
initParams.domain= “zoom.us”;
initParams.appKey = “ ";
initParams.appSecret = " ”;
initParams.videoRawDataMemoryMode = ZoomSDKRawDataMemoryMode.ZoomSDKRawDataMemoryModeStack;
zoomSDK.initialize(this, mZoomSDKListener, initParams);
zoomSDK.addAuthenticationListener(mZoomSDKListener);``

Enable waiting room:

``

PreMeetingService preMeetingService = ZoomSDK.getInstance().getPreMeetingService();
if (preMeetingService == null) {
    Log.i(TAG, “preMeetingService is null.”);
    return;
}
MeetingItem meetingItem = preMeetingService.getMeetingItemByUniqueId(Long.parseLong(MEETING_ID));
if (meetingItem == null) {
    Log.i(TAG, “meetingItem is null.”);
    return;
}
meetingItem.setMeetingTopic("***");
meetingItem.setEnableWaitingRoom(true);
meetingItem.setCanJoinBeforeHost(false);
InMeetingWaitingRoomController waitingRoomController = ZoomSDK.getInstance().getInMeetingService().getInMeetingWaitingRoomController();
if (waitingRoomController.isSupportWaitingRoomUponEntryFeature()) {
    waitingRoomController.enableWaitingRoomOnEntry(true);
}``

Enabling customised UI:

ZoomSDK.getInstance().getMeetingSettingsHelper().setCustomizedMeetingUIEnabled(true);

Start meeting:

``

public void startMeeting() {
    
    enableWaitingRoom();
    if (ZoomSDK.getInstance().getMeetingSettingsHelper().isCustomizedMeetingUIEnabled()) {
        QtNative.activity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "startMeeting, runOnUiThread");
                MeetingService meetingService = ZoomSDK.getInstance().getMeetingService();
                if (meetingService == null) {
                    Log.i(TAG, "startMeeting, meetingService is null");
                    return;
                }
                StartMeetingOptions opts = new StartMeetingOptions();
                opts.no_video=true;

                if (ZoomSDK.getInstance().isLoggedIn()) {
                    StartMeetingParams4NormalUser params = new StartMeetingParams4NormalUser();
                    params.meetingNo = MEETING_ID;
                    int res = meetingService.startMeetingWithParams(QtNative.activity(), params, opts);
                    Log.i(TAG, "startMeeting, startMeetingWithParams with login res: " + res);
                } else {
                    StartMeetingParamsWithoutLogin params = new StartMeetingParamsWithoutLogin();
                    APIUserInfo userInfo = getAPIUserInfo();
                    if (userInfo != null) {
                        params.userId = userInfo.userId;
                        params.userType = STYPE;
                        params.displayName = "Name";
                        params.zoomAccessToken = userInfo.userZoomAccessToken;
                        params.meetingNo = MEETING_ID;
                        int res = meetingService.startMeetingWithParams(QtNative.activity(), params, opts);
                        Log.i(TAG, "startMeeting, startMeetingWithParams without login res: " + res);
                    } else {
                        Log.i(TAG, "startMeeting, Invalid User Info");
                    }
                }
            }
        });
    } else {
        Log.i(TAG, "startMeeting, isCustomizedMeetingUIEnabled is false");
    }
}``

Start Sharing:

``

 public void shareScreen() {
    
    Log.i(TAG, "shareScreen");
    InMeetingShareController inMeetingShareController = 
    
    ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController();

    if (inMeetingShareController.isOtherSharing()) {
        return;
    }
    if (mScreenInfoData == null) {
        MediaProjectionManager mgr = (MediaProjectionManager) QtNative.activity().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        if (mgr != null) {
            Intent intent = mgr.createScreenCaptureIntent();
            try {
               QtNative.activity().startActivityForResult(mgr.createScreenCaptureIntent(), REQUEST_SHARE_SCREEN_PERMISSION);
            } catch (Exception e) {
               Log.e(TAG, "askScreenSharePermission failed");
            }
        }
    } else {
        startShareScreenSession(mScreenInfoData);
    }
}

public void startScreenSharing(Intent data) {
    Log.i(TAG, "startScreenSharing");
    InMeetingShareController inMeetingShareController = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController();
    if (data == null) {
        Log.e(TAG, " startScreenSharing intent object is null.");
        return;
    }
    mScreenInfoData = data;
    if (!inMeetingShareController.isOtherSharing()) {
        startShareScreenSession(mScreenInfoData);
    }
}

public void startShareScreenSession(Intent data) {
    Log.i(TAG, "startShareScreenSession");
    if (data == null) {
        Log.e(TAG, " startShareScreenSession intent object is null.");
        return;
    }
    MobileRTCSDKError error = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController().startShareScreenSession(data);
    Log.i(TAG, " startShareScreenSession error: " + error);
}``

Start Annotation:

public void startAnnotation() {

    QtNative.activity().runOnUiThread(new Runnable() {
        
        @Override
        
         public void run() {
            
            InMeetingAnnotationController inMeetingAnnotationController = ZoomSDK.getInstance().getInMeetingService().getInMeetingAnnotationController();
            if (inMeetingAnnotationController == null) {
                Log.e(TAG, " Failed to startAnnotation as inMeetingAnnotationController is null.");
                return;
            }
            Log.i(TAG, " canDoAnnotation: " + inMeetingAnnotationController.canDoAnnotation() + " isPresenter: " + inMeetingAnnotationController.isPresenter()
            + " canDisableViewerAnnotation: " + inMeetingAnnotationController.canDisableViewerAnnotation() + " isViewerAnnotationDisabled: " + inMeetingAnnotationController.isViewerAnnotationDisabled());
            error = inMeetingAnnotationController.startAnnotation();
            Log.i(TAG, " startAnnotation error: " + error);
            error = inMeetingAnnotationController.setToolColor(RED);
            error = inMeetingAnnotationController.setToolType(AnnotationToolType.ANNO_TOOL_TYPE_PEN);
        }
    });
}

Hi @taher.lakdawala, thanks for the post.

We have disabled display over app permission to hide floating annotation button over app

Can you please try enabling this permission and let me know if you are still experiencing this issue? The toolbar can be hidden by calling hideAnnotationInScreenShareToolbar with a value of true.

Thanks!

No we have intentionally disabled the permission as we want to use customised button to start annotations. Even we tried with floating annotations button but that is using zoom in built UI and which is what we don’t want to use. We want to use our own customised UI button which is when pressed call to method startAnnotation should start annotations.

Hi @taher.lakdawala,

The correct way to hide the annotation toolbar is through the method I linked to in my previous post. After calling that method, the default UI for starting an annotation will not be displayed. Is there something else that disabling the overlay through the SDK in this manner does not accomplish?

Thanks!

Hi @taher.lakdawala please use SDKShareView to implement share function, then you can use startAnnotation method

Great to have all the responses, i will try out and let you guys know the updates.

Hello, the solution you provided for annotation by calling startShareViewSession is working.

But now i ran into another problem. Basically we are using Qt/qml for UI development for android and iOS. Now as there is no android layout present, “MobileRTCShareView” cannot be used as described in zoom android SDK documentation. In this case if i do below initialisation:

MobileRTCShareView mShareView = new MobileRTCShareView(QtNative.activity());

and then start session:

MobileRTCSDKError error = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController().startShareViewSession();
mShareView.setShareWhiteboard();

and on callback:

@Override
public void onShareActiveUser(long userId) {
     MobileRTCSDKError error = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController().startShareViewContent( RemoteSharingUtils.getInstance().mShareView);
     Log.i(TAG, " startShareViewContent error: " + error);
     if (error == MobileRTCSDKError.SDKERR_SUCCESS) {
        screenShareStatus(true); // Screen sharing stopped by the Melody
     }
}

It shows error as success but on client side instead of white board nothing is visible.

Hi @taher.lakdawala, glad to hear that’s working!

I’m having a little trouble understanding what the new issue is. Can you please provide a screenshot to help clarify so that I may better assist?

Thanks!

What i meant to say is we are using Qt/qml for UI development. Hence we don’t have layout implemented in layout .xml files. Now if i’m using ``

MobileRTCShareView mShareView = new MobileRTCShareView(QtNative.activity());    
MobileRTCSDKError error = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController().startShareViewSession();
mShareView.setShareWhiteboard();

@Override
public void onShareActiveUser(long userId) {
 MobileRTCSDKError error = ZoomSDK.getInstance().getInMeetingService().getInMeetingShareController().startShareViewContent( RemoteSharingUtils.getInstance().mShareView);
 Log.i(TAG, " startShareViewContent error: " + error);
 if (error == MobileRTCSDKError.SDKERR_SUCCESS) {
    screenShareStatus(true); 
 }
}``

then nothing comes on “startShareViewContent” because as per document we need to give view from declared in layout .xml. But as we don’t have any layout .xml how to handle this scenario.

Hi @taher.lakdawala Can not MobileRTCShareView embed in Qt?

This is the answer i am looking for how to do that, i am not sure how MobileRTCShareView will get the view created by qml?

Also if i create my own layout in android and add below lines:

            <us.zoom.sdk.MobileRTCShareView
            android:id="@+id/sharingView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"/>

After starting meeting i set content and try to get the view:

setContentView(R.layout.my_meeting_layout);
RemoteSharingUtils.getInstance().mShareView = (MobileRTCShareView) findViewById(R.id.sharingView);

But mShareView is always null. So from creating native view way also its not working.

Hi @taher.lakdawala,

If I’m understanding correctly, you are having issues integrating the MobileRTCShareView element in your UI framework, correct? If that’s the case, we unfortunately cannot provide support for third party frameworks. Please refer to the documentation for the Qt QML and let me know if we can help with anything directly related to the SDK. :slightly_smiling_face:

Thanks!

Yes this why i am trying to create layout in android but still it seems to not working:

#my_meeting_layout:

``

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal">

    <FrameLayout
        android:id="@+id/share_contain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignWithParentIfMissing="true"
        android:orientation="vertical">

        <us.zoom.sdk.MobileRTCShareView
            android:id="@+id/sharingView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>
        <Button
            android:id="@+id/backButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="go_back"
            android:layout_gravity="center_vertical|center_horizontal" />

    </FrameLayout>

</RelativeLayout>

After starting the meeting i am executing below code:

setContentView(R.layout.my_meeting_layout);
mShareView = (MobileRTCShareView) findViewById(R.id.sharingView);

But findViewById always return null, whereas for

mButton = (Button) findViewById(R.id.myBackButton);

Just works fine. Please let me know if i’m missing anything here.

I use the code provided by you in my project, findViewById(R.id.sharingView) is not null. Please tell me detail so that I can help you.

Yeah seems to be problem occurring because of Qt UI and android activity layout. Need to find solution on how to handle MobileRTCShareView in Qt. Thanks for the support so far.

Hi @taher.lakdawala,

Yes, it does seem to be an issue related to the Qt framework. Please let us know if you experience any issues directly related to the SDK after getting that aspect sorted out. :slightly_smiling_face:

Thanks!