使用融云 CallPlus SDK,一小时实现一款 1V1 视频应用

news2025/1/10 10:58:22

9 月 21 日,融云直播课 社交泛娱乐出海最短变现路径如何快速实现一款 1V1 视频应用? 欢迎点击小程序报名~

1V1 音视频、远程服务类应用的实现利器——融云 CallPlus SDK 上线! 关注【融云全球互联网通信云】了解更多

作为新一代音视频通话场景化 SDK,融云 CallPlus 完整封装了拨打、接听、挂断等整套呼叫流程,支持一对一及多人音视频通话,功能齐全、体验丝滑,且契合海外用户的交互偏好。

本文将以 Android 端集成为例,分享实战教程:

使用融云 CallPlus SDK,一小时集成 1V1 视频通话能力。

一个 RTC 实时音视频底层零经验开发者,只需 3 个核心 API、4 步 即可轻松实现音视频通话能力。并且,融云提供 Quick Demo 源码供开发者集成参考。


前置条件

创建融云开发者账号

创建融云开发者账号,获取 App Key。

开始之前,需创建融云开发者账号并获取 App Key。在开发者后台,系统会自动为新账号创建一个应用。默认使用国内数据中心,并提供开发环境。如果您已经有融云开发者账号,可以直接创建新应用。

导入 SDK

打开根目录下的 build.gradle(新版 Android studio 为 settings.gradle),Project 视图下,声明融云的 Maven 代码库。

allprojects {
  repositories {
      ...
      //融云 maven 仓库地址
      maven {url "https://maven.rongcloud.cn/repository/maven-releases/"}
  }
}

添加依赖项

在应用的 build.gradle 中,添加如下远程依赖项。

注意:融云 CallPlus 业务依赖 IM 通道,所以须同时集成 IMLibCore SDK。

dependencies {
  // 请填写具体的 SDK 版本号,新集成用户建议使用最新版。此处以5.6.2版本为例。
  implementation 'cn.rongcloud.sdk:im_libcore:5.6.2'  // 即时通讯基础能力库。
  implementation 'cn.rongcloud.sdk:callplus_lib:1.0.0'// 音视频呼叫能力库(内含 rtc_lib)
}

权限声明

在 AndroidManifest.xml 中声明 SDK 需要的所有权限。

<!-- 允许程序访问网络连接 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序获取网络信息状态,如当前的网络连接是否有效 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 允许程序获取当前WiFi接入的状态以及WLAN热点的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序访问摄像头进行拍照 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 允许程序录制声音通过手机或耳机的麦克 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 允许程序修改声音设置信息 -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!--允许程序访问电话状态,如通话中收到来自SIM卡的来电时,会将SIM卡通话状态通知给远端用户,所以需要该权限-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

注意:如果开发应用需要支持 Android 6.0(API 级别 23)或更高版本的设备,还需要在 App 用户使用对应功能时(如发起呼叫、接听)请求摄像头(CAMERA)、麦克风(RECORD_AUDIO)权限。

详见 Android 开发者官方文档运行时权限与请求权限的工作流。


正式集成

在着手实现之前,我们需要关注以下几个关键点:

☑ 如何发起通话
☑ 如何接收来电
☑ 通话接通后,双方通话界面如何显示

要想实现通话功能,必须以双端都已经成功连接融云为基础,参考下图所示 1V1 主叫端和被叫端的流程时序图。

主叫端时序图:

被叫端时序图:

初始化连接融云

CallPlus for Android 依赖融云即时通讯客户端 SDK 提供信令通道,故需先对 IMLibCore 进行初始化,建议放到 Application 中。

String appKey = "Your_AppKey"; // example: bos9p5rlcm2ba 创建融云开发者账号,获取 App Key。
InitOption initOption = new InitOption.Builder().build();
RongCoreClient.init(getApplicationContext(), appKey, initOption);

要拨打和接听一对一呼叫或开始多人呼叫,必须先通过 RongCoreClient 的 connect 方法连接融云服务器。

传入用户身份令牌(Token),向融云服务器验证用户身份;连接成功后,使用 RCCallPlusClient.getInstance().init() 方法初始化和配置 CallPlus SDK。

String token = "用户Token";// 您在申请开发者账号后,可以在融云后台北极星位置直接生成用户token
RongCoreClient.connect(token, new IRongCoreCallback.ConnectCallback() {
   /**
    * 成功回调
    * @param userId 当前用户 ID
    */
   @Override
   public void onSuccess(String userId) {
      runOnUiThread(new Runnable() {
          @Override
          public void run() {
              //todo 尽管在主线程初始化 RCCallPlusClient 不是必需的,但考虑到代码示例后续对 RCCallPlusClient 的调用都在主线程进行,所以目前选择在主线程进行初始化。
              //todo 请确保在同一个线程进行 RCCallPlusClient 的初始化、反初始化和使用,以确保操作的一致性。
              RCCallPlusConfig config = RCCallPlusConfig.Builder.create().build();
              /**
               * 初始化并设置通话全局配置,重复调用该方法时SDK内部会重新初始化
               * @param config    设置通话全局配置
               * @return 方法调用后同步返回结果,可以在这里得到初始化是否成功
               */
              RCCallPlusResultCode resultCode = RCCallPlusClient.getInstance().init(config);
          }
      });

   }
   /**
    * 错误回调
    * @param errorCode 错误码
    */
   @Override
   public void onError(IRongCoreEnum.ConnectionErrorCode errorCode) {

   }

   /**
    * 数据库回调.
    * @param code 数据库打开状态. DATABASE_OPEN_SUCCESS 数据库打开成功; DATABASE_OPEN_ERROR 数据库打开失败
    */
   @Override
   public void onDatabaseOpened(DatabaseOpenStatus code) {

   }
});

发起呼叫并设置本地和远端视图

使用 startCall 方法来发起一对一通话。

该方法内部会以异步方式执行,并通过 IRCCallPlusResultListener#onStartCall 回调来获取方法的结果。

在发起通话之前需先设置本地和远端视图,在对端接听视频通话时,本端会自动渲染对端的视图。

使用 setCallPlusResultListener 方法添加通话 API 异步结果回调监听。该监听可以接收 startCall、accept、hangup 等方法的结果回调。

发起呼叫:

  private void startCall(String remoteUserId) {
        //todo 打开摄像头采集,请提前完成摄像头、麦克风权限的动态申请
        RCCallPlusClient.getInstance().startCamera();
        RCCallPlusClient.getInstance().enableMicrophone(true);

        //设置本端视图
        setLocalVideoView();
        //设置对端视图
        setRemotVideoView(remoteUserId);

        List<String> userIds = new ArrayList<>();
        userIds.add(remoteUserId);//todo remoteUserId 为被呼叫的远端用户userId
        RCCallPlusType callType = RCCallPlusType.PRIVATE;//PRIVATE: 1V1通话
        RCCallPlusMediaType mediaType = RCCallPlusMediaType.VIDEO;
        /**
         * 开始发起呼叫
         * 该方法内部为异步执行,结果回调是注册的{@link RCCallPlusClient#setCallPlusResultListener(IRCCallPlusResultListener)} 监听的 {@link IRCCallPlusResultListener#onStartCall(RCCallPlusCode, String, List)}方法<br>
         */
        RCCallPlusClient.getInstance().startCall(userIds, callType, mediaType);
    }

发起端设置本地视图:

   /**
    * 设置本地视频渲染视图
    */
   private void setLocalVideoView() {
       //创建本地视图对象
       RCCallPlusLocalVideoView localVideoView = new RCCallPlusLocalVideoView(this.getApplicationContext());
       //FIT: 视频帧通过保持宽高比(可能显示黑色边框)来缩放以适应视图的大小
       localVideoView.setRenderMode(RCCallPlusRenderMode.FIT);
       //设置本地视图给  SDK
       RCCallPlusClient.getInstance().setVideoView(localVideoView);

       FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
       params.gravity = Gravity.CENTER_HORIZONTAL;//在父布局中横向居中显示
       //将本地视图添加到XML中显示
       //示例代码中 mLocalVideoViewFrameLayout 为 android.widget.FrameLayout 对象
       mLocalVideoViewFrameLayout.removeAllViews();
       mLocalVideoViewFrameLayout.addView(localVideoView, params);
   }

发起端设置对端视图:

   /**
    * 发起通话时设置对端视频渲染视图
    */

private void setRemotVideoView(String remoteUserId) {
    //创建远端视图对象 remoteUserId为远端用户userId
    RCCallPlusRemoteVideoView remoteVideoView = new RCCallPlusRemoteVideoView(remoteUserId, this.getApplicationContext(), false);
    //FIT: 视频帧通过保持宽高比(可能显示黑色边框)来缩放以适应视图的大小
    remoteVideoView.setRenderMode(RCCallPlusRenderMode.FIT);
    //因为远端视图显示在最顶层,为了防止远端视频视图被底部控件遮挡,所以添加如下设置:
    remoteVideoView.setZOrderOnTop(true);
    remoteVideoView.setZOrderMediaOverlay(true);

    List<RCCallPlusRemoteVideoView> remoteVideoViewList = new ArrayList<>(); remoteVideoViewList.add(remoteVideoView);
    //设置远端视图给SDK
    RCCallPlusClient.getInstance().setVideoView(remoteVideoViewList);

    FrameLayout.LayoutParams remoteVideoViewParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
    remoteVideoViewParams.gravity = Gravity.CENTER_HORIZONTAL;
    //将远端视图添加到XML中显示
    //示例代码中 mRemoteVideoViewFrameLayout 为 android.widget.FrameLayout 对象
    mRemoteVideoViewFrameLayout.removeAllViews();
    mRemoteVideoViewFrameLayout.addView(remoteVideoView, remoteVideoViewParams);
}

接收端接听通话并设置本地和远端视图

可选择接听或挂断来电,若要接听电话,请使用 accept 方法;若要挂断来电,请使用 RCCallPlusClient.getInstance().hangup() 方法。

可以通过 RCCallPlusSession#getCallId() 方法获取执行接听和挂断操作所需的 CallId 值。

要接收远端呼叫通知,必须确保已经注册了 IRCCallPlusEventListener,并实现了 onReceivedCall(RCCallPlusSession callSession) 方法。被叫用户通过与融云服务端的连接或者离线推送通知(离线推送 App 必须已集成第三方厂商推送,详见推送 2.0 集成概述)接收来电通知。

使用 setCallPlusEventListener 方法添加通话事件监听,提供来电事件、通话状态、通话记录等事件相关回调。

添加通话事件监听:

RCCallPlusClient.getInstance().setCallPlusEventListener(new IRCCallPlusEventListener() {

    /**
     * 用户通过该回调接收到通话呼叫 在这个回调中,可以接听通话
     *
     * @param callSession   通话实体信息<br>
     */
    @Override
    public void onReceivedCall(RCCallPlusSession callSession) {
        RCCallPlusSession currentCallSession = RCCallPlusClient.getInstance().getCurrentCallSession();
        if (currentCallSession != null && !TextUtils.equals(callSession.getCallId(), currentCallSession.getCallId())) {
            //可以使用该方法判断出,有正在进行中的通话,又有第二通通话呼入的情况<br>
            //todo 第二通通话可以直接调用 RCCallPlusClient.getInstance().accept 方法接听,SDK内部会将第一通通话挂断
        }

        //todo SDK 的回调均为子线程调用,showDialog() 方法中存在UI操作,所以切换到主线程执行
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //todo 打开摄像头采集,请提前完成摄像头、麦克风权限的动态申请
                RCCallPlusClient.getInstance().startCamera();
                RCCallPlusClient.getInstance().enableMicrophone(true);

                setLocalVideoView();//复用发起通话逻辑中的 设置本地视频渲染视图 方法

                showDialog(CallPlusActivity.this, "收到通话,是否接听?", "接听", new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        acceptCall(callSession);
                    }
                }, "挂断", new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        RCCallPlusClient.getInstance().hangup();
                    }
                });
            }
        });
    }

    @Override
    public void onCallEnded(RCCallPlusSession session, RCCallPlusReason reason) {
        IRCCallPlusEventListener.super.onCallEnded(session, reason);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(CallPlusActivity.this,"通话结束,callId: "+session.getCallId() +" 通话结束原因:"+ reason.getValue(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 远端用户状态改变监听<br>
     *
     * @param callId 通话Id<br>
     * @param userId 用户Id<br>
     * @param status 该用户当前状态<br>
     * @param reason 该用户当前状态原因<br>
     */
    @Override
    public void onRemoteUserStateChanged(String callId, String userId, RCCallPlusUserSessionStatus status, RCCallPlusReason reason) {
        IRCCallPlusEventListener.super.onRemoteUserStateChanged(callId, userId, status, reason);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                StringBuilder stringBuilder = new StringBuilder("通话 ");
                stringBuilder.append(callId).append(" 中的远端用户 ").append(userId).append(" 当前状态为 ");
                switch (status) {
                    case CALLING:
                        stringBuilder.append("呼叫中");
                        break;
                    case INVITED:
                        stringBuilder.append("被邀请中");
                        break;
                    case CONNECTING:
                        stringBuilder.append("已接听,连接中");
                        break;
                    case ON_CALL:
                        stringBuilder.append("通话中");
                        break;
                    case ENDED:
                        stringBuilder.append("通话已结束");
                        break;
                }
                Toast.makeText(CallPlusActivity.this, stringBuilder.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }
});

具体接听通话的方法:

private void acceptCall(RCCallPlusSession callSession) {
    setRemoteUserVideoView(callSession.getRemoteUserList());
    /**
     * 开始接听通话
     * 该方法内部为异步执行,结果回调是注册的{@link RCCallPlusClient#setCallPlusResultListener(IRCCallPlusResultListener)} 监听的 {@link IRCCallPlusResultListener#onAccept(RCCallPlusCode, String)}方法<br>
     */
    RCCallPlusClient.getInstance().accept(callSession.getCallId());
}

接收端设置本地和远端视图:

/**
 * 接听方设置远端用户视频渲染视图
 */
private void setRemoteUserVideoView(List<RCCallPlusUser> remoteUserList) {
    List<RCCallPlusRemoteVideoView> remoteVideoViewList = new ArrayList<>();
    for (RCCallPlusUser callPlusUser : remoteUserList) {
        RCCallPlusRemoteVideoView remoteVideoView = new RCCallPlusRemoteVideoView(callPlusUser.getUserId(), this.getApplicationContext(), false);
        //视频帧通过保持宽高比(可能显示黑色边框)来缩放以适应视图的大小
        remoteVideoView.setRenderMode(RCCallPlusRenderMode.FIT);
        remoteVideoViewList.add(remoteVideoView);
        //本示例代码中,因为远端视图显示在最顶层,为了防止远端视频视图被底部控件(视图)遮挡,所以添加如下设置:
        remoteVideoView.setZOrderOnTop(true);
        remoteVideoView.setZOrderMediaOverlay(true);

        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        params.gravity = Gravity.CENTER_HORIZONTAL;
        //todo 将每个远端视图(remoteVideoView)添加到XML中显示,远端为多人时,需要添加给多个控件显示,本示例代码仅展示一个远端用户情况
        mRemoteVideoViewFrameLayout.removeAllViews();
        mRemoteVideoViewFrameLayout.addView(remoteVideoView, params);
    }
    /**
     * 设置远端用户视频流渲染视图给SDK
     * 若没有为远端用户设置视频渲染视图,则不会产生该用户的视频流的下行流量
     */
    RCCallPlusClient.getInstance().setVideoView(remoteVideoViewList);
}
private AlertDialog showDialog(Context context, String content, String positiveBtn, final DialogInterface.OnClickListener positiveListener, final String negativeBtn, final DialogInterface.OnClickListener negativeListener) {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder = builder.setMessage(content);
    builder.setCancelable(false);
    if (!TextUtils.isEmpty(positiveBtn)) {
        builder.setPositiveButton(positiveBtn, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (positiveListener != null) {
                    positiveListener.onClick(dialog, which);
                } else {
                    dialog.dismiss();
                }
            }
        });
    } if (!TextUtils.isEmpty(negativeBtn)) {
        builder.setNegativeButton(negativeBtn, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (negativeListener != null) {
                    negativeListener.onClick(dialog, which);
                } else {
                    dialog.dismiss();
                }
            }
        });
    } return builder.show();
}

运行项目发起通话,当被叫端接听并且主叫端能够看到双方视频,说明 1V1 音视频通话核心能力已经实现了,全程仅需 4 个步骤、3 个核心 API。


其他功能

切换前后摄像头

成功打开摄像头后,可以使用 switchCamera 方法切换前后摄像头。

switchCamera 方法是异步调用的,支持通过 IRCCallPlusResultListener 的 onSwitchCamera 回调来获取调用结果。

RCCallPlusClient.getInstance().switchCamera();
RCCallPlusClient.getInstance().setCallPlusResultListener(new IRCCallPlusResultListener() {
    /**
     * 切换前后摄像头方法结果回调<br>
     *
     * @param code 方法请求结果<br>
     * @param isFrontCamera 当前开启的摄像头是否是前置摄像头<br>
     */
    @Override
    public void onSwitchCamera(RCCallPlusCode code, boolean isFrontCamera) {
        IRCCallPlusResultListener.super.onSwitchCamera(code, isFrontCamera);
    }
});

美颜

融云 SDK 已经接入专业三方美颜服务,三步即可实现美颜功能。

  1. 在应用的 build.gradle 中添加如下远程依赖项。

    implementation 'cn.rongcloud.sdk:fu_beautifier:5.6.2'
    implementation 'androidx.core:core-ktx:1.7.0'

  2. 提供有效的美颜授权文件(感兴趣可联系融云商务详细咨询:131 6185 6839)。
  3. 初始化美颜插件,初始化时请提供有效的美颜授权文件。应用运行期间只调用一次即可,建议在 Application#onCreate 中初始化。

下面代码块中的 authpackNew 即为相关美颜服务的授权文件。

RCRTCFUBeautifierEngine.getInstance()
        .register(
                getApplicationContext(),
                null,
                authpackNew.A(),
                new FUBeautifierResultCallback() {
                    @Override
                    public void onSuccess() {
                        setBeautyEnable();
                        SetBeautyParameters();
                    }

                    @Override
                    public void onFailed(int code) {
                    }
                });
private void setBeautyEnable() {
    // 打开美颜开关后设置的美颜效果才会生效;关闭开关美颜会失效。
    RCRTCFUBeautifierEngine.getInstance().setBeautyEnable(true, new FUBeautifierResultCallback() {
        @Override
        public void onSuccess() {
        }

        @Override
        public void onFailed(int code) {

        }
    });
}
// 设置美颜参数
private void SetBeautyParameters() {
    RCRTCFUBeautifierEngine.getInstance().setBlurIntensity(6); 范围[0-6]
    RCRTCFUBeautifierEngine.getInstance().setColorIntensity(2); // 范围 [0-2]
    RCRTCFUBeautifierEngine.getInstance().setRedIntensity(2);// 范围 [0-2]
    RCRTCFUBeautifierEngine.getInstance().setSharpenIntensity(1);// 范围 [0-1]
    RCRTCFUBeautifierEngine.getInstance().setEyeBrightIntensity(1); // 范围 [0-1]
    RCRTCFUBeautifierEngine.getInstance().setToothIntensity(1);// 范围 [0-1]
    RCRTCFUBeautifierEngine.getInstance().setRemovePouchIntensity(1);// 范围 [0-1]
    RCRTCFUBeautifierEngine.getInstance().setRemoveLawPatternIntensity(1);// 范围 [0-1]
}

在业务开发集成、上线运营等全过程中,融云都将提供全流程一站式技术服务支持,开发者可提交工单与融云工程师交流。欢迎来电咨询:131 6185 6839


最后,callback 一下融云 CallPlus SDK 的核心优势:

完整封装:提供完整的呼叫功能方案,包括连接、呼叫、接听、拒接、挂断、呼叫状态通知等。

集成便捷:接口设计贴近业务且简洁明了,结合 Quick Demo 源码,开发者只需使用 3 个核心接口,一小时即可实现音视频通话核心功能。

场景全面:支持 iOS、Android、Web 等平台,可以满足陌生人社交、在线招聘、远程医疗、线上咨询、售后客服等多种单人和多人通话场景使用。

服务稳定: 100% 可靠必达的音视频呼叫信令能力,保证连接安全可靠;音频弱网抗丢包 80%,视频弱网抗丢包 60%,并有 3A 算法,保证通话清晰稳定。

周边完善:提供业务场景所需的丰富高级功能,包括内容审核、云端录制、高级美颜等,让开发者的业务开展无忧且高效。

性价比高:目前月功能费仅为 1500 元/月,含 200,000 分钟免费时长。场景灵活度高,不限音视频,视频最高分辨率可支持 2K+;真正省心透明,支持 RTC 与 IM 服务单独采购,且不单独收取呼叫信令费用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Transformer模型 | 个人理解

一、Transformer整体架构图 二、Encoder端的输入 以机器翻译任务为例子&#xff0c;训练数据是法语句子“Je suis etudiant”和翻译成英文后的句子“I am a student”。 Inputs是法语句子“ J e {Je } Je s u i s {suis} suis e t u d i a n t {etudiant} etudiant”&#x…

9月16日相约openGauss Meetup(杭州站)

由云和恩墨、图尔兹、浙江鲲鹏、openGauss社区联合主办的“openGauss Meetup &#xff08;杭州站&#xff09;”活动将于9月16日在杭州市拱墅区祥园路108号中国智慧信息产业园G座3楼连廊1号会议室举办&#xff01;我们诚邀您的莅临&#xff01; 扫码报名 数据库作为企业核心的重…

Jetty服务器好处

Jetty可以同时处理大量连接而且可以长时间保持连接&#xff0c;适合于web聊天应用等等。 Jetty的架构简单&#xff0c;因此作为服务器&#xff0c;Jetty可以按需加载组件&#xff0c;减少不需要的组件&#xff0c;减少了服务器内存开销&#xff0c;从而提高服务器性能。 Jetty默…

最新遥感数据与作物模型同化教程

详情点击公众号链接&#xff1a;最新遥感数据与作物模型同化教程一&#xff1a;遥感基础1.遥感平台&#xff08;如无人机&#xff09;与传感器、国内外主要陆地卫星&#xff08;如Landsat、SPOT、HJ、GF&#xff09; 2.遥感基本原理、光谱响应函数、遥感数据处理流程 3.遥感在陆…

接口自动化测试的概述及流程梳理~

接下来开始学习接口自动化测试。 因为之前从来没接触过&#xff0c;所以先了解一些基础知识。 1.接口测试的概述 2.接口自动化测试流程。 接口测试概述 接口&#xff0c;又叫API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;&a…

Java“牵手”天猫商品详情数据,天猫商品详情接口,天猫API接口申请指南

天猫平台API是天猫应用程序编程接口的缩写&#xff0c;它是一套允许程序员从他们的应用程序中访问天猫网站上数据的规范。通过API&#xff0c;程序员可以编写能够与天猫网站交互的程序&#xff0c;从而绕过网页浏览器的限制&#xff0c;直接访问和操作数据。 天猫平台API可以提…

模拟考试系统提升备考效果和成功机会

备考是每位参加考试的学生都非常重视的阶段。为了提高备考效果和增加成功机会&#xff0c;模拟考试系统是一种非常有效的工具。 备考对于任何一位参加考试的学生来说都是至关重要的阶段。无论是应对学校期末考试、入学考试还是国家级考试&#xff0c;备考都需要充分的准备和调…

怎样建立一个班级查分系统?

在现代教育中&#xff0c;建立一个高效的班级查分系统对于老师和家长们来说至关重要。物种草作为一款功能强大的在线教育工具&#xff0c;为教师们提供了一个便捷的方式来管理和分享学生成绩。本文将以物种草的口吻&#xff0c;为你介绍如何建立一个高效的班级查分系统&#xf…

javascript二维数组按指定要求进行对象合并遍历的算法开发

javascript二维数组按指定要求进行对象合并遍历的算法开发 项目原数据项目需求数据格式算法开发 项目原数据 从第三方API获取如何格式的数据&#xff1a; “device”: “二(1)班”,不同班级名称&#xff0c;会重复“name”: “二(1)班-电量”,不同班级的数据标准“value”: 1…

如何初始化静态成员在类中

c - How do I initialize a const data member? - Stack Overflow

安卓逆向 - 某东sign(基于unidbg主动调用)

本文仅供学习交流&#xff0c;只提供关键思路不会给出完整代码&#xff0c;严禁用于非法用途&#xff0c;拒绝转载&#xff0c;若有侵权请联系我删除&#xff01; 目标app&#xff1a;5Lqs5LicYXBwMTEuMy4y 目标接口&#xff1a;aHR0cHM6Ly9hcGkubS5qZC5jb20vY2xpZW50LmFjdGl…

9月1日作业

思维导图 服务器代码 #include<myhead.h>#define PORT 4567 #define IP "192.168.6.225"struct msg //接收到的客户端信息结构体 {char type;char name[20];char txt[128]; };//定义节点类型 typedef struct Node {union{struct sockaddr_in cin; //数据…

springboot+springSecurity+jwt实现登录认证后令牌授权

springbootspringSecurityjwt实现登录认证后令牌授权&#xff08;已绑定整个项目的源码&#xff09; 目录 springbootspringSecurityjwt实现登录认证后令牌授权&#xff08;已绑定整个项目的源码&#xff09;一、自定义数据源登录认证1、实现spring security中UserDetails类2、…

22.1 JavaScript 基础

1. JavaScript 1.1 简介 JavaScript(简称js): 是一种广泛应用于网页开发的脚本语言. 它被用于增强网页的交互性和动态性, 可以让开发者对网页进行操作和控制. JavaScript可用于处理用户输入, 改变网页的内容, 动态加载数据, 创建动画效果等. 它在现代的Web开发中扮演着至关重…

【GIS】栅格转面报错:ERROR 000864输入栅格: 输入不在定义的属性域内。 ERROR 000863: 无效的 GP 数据类型

问题: 栅格转面(矢量)时,ArcGIS窗口显示:ERROR 000864输入栅格: 输入不在定义的属性域内。 ERROR 000863: 无效的 GP 数据类型. 原因: 栅格转面时输入的栅格数据集的字段必须是整型. 解决办法: 使用Spatial Analyst中的转为整型工具,将栅格数据转为整型后再进行栅格转面的操作…

pycharm增加新的编译器

安装了python2和3的电脑上&#xff0c;使用pycharm时候&#xff0c;最好将2和3都加入其编译器。 方法&#xff1a; 1、File-settings... 2、如图选择&#xff0c;然后点击加号&#xff0c;添加python2或者3的exe

通常用哪些软件做数据可视化大屏?

一般就两种&#xff0c;一种是可视化大屏编辑软件&#xff0c;另一种则是BI系统&#xff08;BI数据可视化工具&#xff09;。考虑到数据来源多、数据量大以及数据分析效率、直观易懂性等实实在在的客观问题&#xff0c;建议采用BI系统来制作数据可视化大屏。 BI系统做可视化大…

首个国家级元宇宙计划发布,和数集团迎来赛道发展新机遇

近日&#xff0c;工业和信息化部、教育部、文化和旅游部、国务院国资委、国家广播电视总局办公厅五部门联合印发《元宇宙产业创新发展三年行动计划&#xff08;2023-2025年&#xff09;》&#xff08;以下简称《计划》&#xff09;&#xff0c;其中在发展目标中提到要培育3-5家…

手把手教你搭建WordPress博客网站并发布至公网

文章目录 概述前置准备1 安装数据库管理工具1.1 安装图形图数据库管理工具&#xff0c;SQL_Front 2 创建一个新数据库2.1 创建数据库2.2 为数据库创建一个用户 3 安装PHP7.44. 创建一个新站点4.1 创建站点根目录4.2 访问WordPress官网&#xff0c;下载最新版本的压缩包4.3 创建…

Linux之yum/git的使用

目录 一、yum 1、关于yum 2、yum的操作 ①、yum list ②、yum install ③、yum remove 二、git 1、Linux中连接gitee 2、git的操作 ①git add [文件] ②git commit -m "提交日志" ③git push 3、可能出现的问题 ①配置用户名、邮箱 ②出现提交冲突 ③…