# Demo自定义扩展功能说明

使用SDK业务组件时，需要先完成SDK的基础组件的初始化(初始化要放在Application的oncreate里，尽量时许提前，sdk内部通过监听activity的生命获取当前activity， 跳转界面，否则可能出现界面无法跳转的情况：)。
```
HWMSdk.init(Application，OpenSDKConfig );
```

## 在初始化之前我们可以对SDK进行自定义的相关设置：

## 自定义会中UI行为通知
```
private CLMNotifyHandler customNotifyHandler = new CLMNotifyHandler() {
     /**
      * 呼叫结束后，会收到该通知
      * @param callInfo 呼叫信息
      */
     @Override
     public void onCallEnded(CallInfo callInfo) {
         Log.i(TAG, "呼叫结束了");
     }
     @Override
     public void onConfDetailNotify(ConfInfo confInfo) {
         Log.i(TAG, "confInfo: confId" + confInfo.getConfId() + ", Subject:" + confInfo.getConfSubject());
     }
     /**
      * 会议结束该后，会收到通知
      * @param result 会议结束后的错误码
      */
     @Override
     public void onConfEnded(ConfEndedReason result) {
        Toast.makeText(HWMBizSdk.getApplication(), "会议结束了 : " + result.getCode() + ", reason: " + result.getDetail(),  Toast.LENGTH_LONG).show();
     }
     @Override
     public void onLeaveConf(int result) {
        Log.i(TAG, "离开了会议");
     }
};

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setNotifyHandler(customNotifyHandler);
HWMSdk.init(this,sdkConfig);
```

## 自定义账号被踢下线
```
//账号被T，收到该通知表示账号已经在其他设备登录回调
public class CustomIKickOutHandle implements IKickOutHandle{
    private static final String TAG = "DefaultIKickOutHandle";
    @Override
    public void onKickedOut(@Nullable KickOutState kickOutState) {
        Log.i(TAG, "kickOutState:" + kickOutState.msg);
    }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
    ......
    .setKickOutHandle(new CustomIKickOutHandle ());
HWMSdk.init(this,sdkConfig);
```

## 自定义分享链接
```
//分享调用
public class CustomIConfLinkHandle implements IConfLinkHandle{
    private static final String TAG = "DefaultIConfLinkHandle";
    @Override
    public String buildConfLink(ConfInfo confInfo) {
        //会议主题
        String confSubject = confInfo.getConfSubject();
        //会议ID
        String confId = confInfo.getConfId();
        //会议邀请链接
        String confGuestUri = confInfo.getConfGuestUri();
        //会议密码
        String confPwd = confInfo.getConfPwd();
        //会议开始时间
        String confStartTime = confInfo.getConfStartTime();
        //会议参与人数
        String confAccessNum = confInfo.getConfAccessNum();
        //会议参与人数
        String confScheduserName = confInfo.getConfScheduserName();
        //会议主持人密码
        String confChairPwd = confInfo.getConfChairPwd();
        //会议结束时间
        String confEndTime = confInfo.getConfEndTime();
        return confGuestUri;
    }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setConfLinkHandle(new CustomIConfLinkHandle());
HWMSdk.init(this,sdkConfig);
```

## 自定义分享
```
//自定义分享菜单
public class CustomIShareHandle implements IShareHandle{
     private static final String TAG = "DefaultIShareHandle";
     @Override
     public List<IShareModel> buildShareItems(Context context, ConfDetailModel confDetailModel) {
          List<IShareModel> shareModels = new ArrayList<>();
          //微信分享封装
          WeChatShareModel weChatShareModel = new WeChatShareModel();
          //短信分享封装
          SmsShareModel smsShareModel = new SmsShareModel();
          //邮件分享封装
          EmailShareModel emailShareModel = new EmailShareModel();
          //链接分享封装
          CopyShareModel copyShareModel = new CopyShareModel();
          //IM分享封装
          ImChatShareModel imChatShareModel = new ImChatShareModel();
          //获取会议主题
          String subject = confDetailModel.getConfSubject();
          //获取会议访客链接
          String guestUrl = confDetailModel.getGuestJoinUri();
          //获取会议开始结束时间
          String time = DateUtil.getDateTimeStringForUi(confDetailModel.getStartTime(), confDetailModel.getEndTime());
          //获取会议主持人
          String chairman = confDetailModel.getScheduserName();
          //获取会议ID号
          String confId = confDetailModel.getConfId();
          //获取访客密码
          String guestPwd = TextUtils.isEmpty(confDetailModel.getGeneralPwd()) ?Utils.getApp().getString(R.string.conf_no_pwd) : confDetailModel.getGeneralPwd();
          shareModels.add(weChatShareModel);
          shareModels.add(smsShareModel);
          shareModels.add(emailShareModel);
          shareModels.add(copyShareModel);
          shareModels.add(imChatShareModel);
          return null;
     }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setShareHandle(new CustomIShareHandle());
HWMSdk.init(this,sdkConfig);
```

## 自定义会中通知栏
```
//自定义会中通知栏
public class ConfNotificationDifferenceHandle implements IConfNotificationDifferenceHandle {
      private final Context context;
      public ConfNotificationDifferenceHandle(Context context) {
             this.context = context;
      }
      /**
      * 通知栏的标题名字
      * @return
      */
      @Override
      public String resNotificationName() {
          return context.getString(R.string.app_name);
      }

      //通知栏的图标
      @Override
      public int resNotificationIcon() {
          return R.mipmap.ic_launcher;
      }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
    ......
    .setConfNotificationDifferenceHandle(new ConfNotificationDifferenceHandle());
HWMSdk.init(this,sdkConfig);
```

## 自定义日志保存路径
```
//自定义日志保存路径
public class CustomLoggerHandle implements ILoggerHandle {
    private static final String TAG = "HCLog";
    private Application application;
    public CustomLoggerHandle(Application application) {
        this.application = application;
    }
    //自定义日志保存地址
    @Override
    public String getLogPath() {
        return FileUtil.getExternalFilesDir(this.application) + "/log/meeting/";
    }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setLoggerHandle(new CustomLoggerHandle(this));
HWMSdk.init(this,sdkConfig);
```

## 自定义菜单
```
public class CustomConfMenu implements IConfMenuHandle {
    private static final String TAG = "DefaultConfMenuHandle";
    //语音通话和会议自定义菜单
    @Override
    public List<IConfMenu> buildAudioCallAndConfMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         confMenus.add(new MicMenu());
         confMenus.add(new SpeakerMenu());
         confMenus.add(new ShareMenu());
         confMenus.add(new ParticipantMenu());
         confMenus.add(new TransVideoMenu());
         //新增自定义菜单
         confMenus.add(new CustomizeMenu());
         return confMenus;
    }
   //视频通话和会议自定义菜单
    @Override
    public List<IConfMenu> buildVideoCallAndConfMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         //语音菜单
         confMenus.add(new MicMenu());
         //相机菜单
         confMenus.add(new CameraMenu());
         //分享菜单
         confMenus.add(new ShareMenu());
         //参会者菜单
         confMenus.add(new ParticipantMenu());
         //更多选项菜单
         confMenus.add(new MoreMenu());
         //新增自定义菜单
         confMenus.add(new CustomizeMenu());

         return confMenus;
    }
    //语音通话更多选项自定义菜单
    @Override
    public List<IConfMenu> buildVideoCallMoreMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         //切换摄像头菜单
         confMenus.add(new SwitchCameraMenu());
         //转换成语音菜单
         confMenus.add(new CallVideoToAudioMenu());
         //转换成视频菜单
         confMenus.add(new CallAudioToVideoMenu());
         //打开和关闭小画面菜单
         confMenus.add(new OpenOrClosePipMenu());
         //打开和关闭美颜菜单
         confMenus.add(new OpenOrCloseBeautyMenu());
         //新增自定义菜单
         confMenus.add(new CustomizeMenu());
         return confMenus;
    }
    //视频会议自定义菜单
    @Override
    public List<IConfMenu> buildVideoConfMoreMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         //申请主席释放主席菜单
         confMenus.add(new ReleaseOrRequestChairManMenu());
         //锁定和解锁会议菜单
         confMenus.add(new LockOrUnlockConfMenu());
         //举手和放下手菜单
         confMenus.add(new HandsUpOrDownMenu());
         //切换摄像头菜单
         confMenus.add(new SwitchCameraMenu());
         //打开和关闭小画面菜单
         confMenus.add(new OpenOrClosePipMenu());
         //打开和关闭美颜菜单
         confMenus.add(new OpenOrCloseBeautyMenu());
         //打开和关闭录制菜单
         confMenus.add(new OpenOrCloseRecordMenu());
         //反馈菜单
         confMenus.add(new FeedbackMenu());
         //打开和关闭啸叫检测菜单
         confMenus.add(new OpenOrCloseHowlDetectMenu());
         return confMenus;
    }
    //与会者右上角更多选项菜单
    @Override
    public List<IConfMenu> buildParticipantMoreMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         confMenus.add(new ContantMenu());
         confMenus.add(new QrcodeMenu());
         confMenus.add(new ParticipantShareMenu());
         return confMenus;
    }
    //与会者菜单选项自定义
    @Override
    public List<IConfMenu> buildParticipantItemMenuItems() {
         List<IConfMenu> confMenus = new ArrayList<>();
         confMenus.add(new ReleaseOrRequestChairManMenu());
         confMenus.add(new BroastAndCacelMenu());
         confMenus.add(new MuteOrUnmuteMenu());
         confMenus.add(new CallOtherNumberMenu());
         confMenus.add(new RenameMenu());
         confMenus.add(new HangupMenu());
         confMenus.add(new SetChairmanMenu());
         confMenus.add(new SelectWatchOrCacnelMenu());
         confMenus.add(new HandsUpOrDownMenu());
         confMenus.add(new RecallMenu());
         return confMenus;
    }

    //自定义菜单点击回调
    @Override
    public void onClickCustomMenu(int menuId, ConfInfo confInfo) {

    }

    @Override
    public boolean isBuildSpecialParticipantItems() {
        return false;
    }
}
```
如果需要新增菜单，自定义一个菜单(即IConfMenu的实现)找到对应位置，插入即可，菜单的点击事件在onClickCustomMenu里回调
```
class CustomizeMenu implements IConfMenu{
     //自定义菜单ID
     @Override
     public int getId() {
         return 0;
     }
     //自定义菜单icon
     @Override
     public int getImage() {
         return 0;
     }
     //自定义菜单文字
     @Override
     public int getText() {
         return 0;
     }
     //自定义菜单未选中文字
     @Override
     public int getUnCheckedText() {
         return 0;
     }
     //自定义菜单选中文字
     @Override
     public int getCheckedText() {
         return 0;
     }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setConfMenuHandle(new CustomConfMenu());
HWMSdk.init(this,sdkConfig);
```

## 自定义会议中加人
```
//点击添加与会者界面注入，在方法中跳转到自己的选人界面
public class CustomAddAttendeesHandle implements IAddAttendeesHandle {
     private HwmCallback<List<AttendeeModel>> callback;
     //activity 调用的activity
     //list     已选择的账号
     //b        是否预约会议
     //hwmCallback  加人完成后返回已选中与会者列表
     @Override
     public void doAddAttendees(Activity activity, List<AttendeeModel> list, String s, boolean b, HwmCallback<List<AttendeeModel>> hwmCallback) {
          callback = hwmCallback;
          //可以传入已经选择的与会者列表在自定义界面做操作
          Intent intent = new Intent(Utils.getApp(), AddPeopleActivity.class);
          activity.startActivityForResult(intent,5000);
      }
     @Override
     public void dealContactSelect(Intent intent) {
     }
     @Override
     public void onActivityResult(int i, int i1, Intent intent) {
          if(i == 5000){
              if(null != callback){
                  //回调选中的与会者加入会议
                  callback.onSuccess(DemoUtil.selectModels);
              }
          }
     }
}

OpenSDKConfig sdkConfig = new OpenSDKConfig(this)
     ......
     .setAddAttendeesHandle(new CustomAddAttendeesHandle());
HWMSdk.init(this,sdkConfig);
```
