快速集成 UIKit 开源方案

  • Android

更新时间不可用

了解如何快速接入 UIKit 开源方案,完成环境准备、参数配置、示例运行和核心流程验证。

AUIKaraoke 是一个基于 AUIKit 搭建的、针对 K 歌场景的开源 UI 组件,提供 K 歌房间相关功能。asceneskit 是 K 歌房的容器组件,你可以通过 asceneskit 自定义 K 歌房间的用户界面逻辑并实现房间管理等功能。

本文介绍如何通过 AUIKaraoke 快速搭建一个含 UI 界面的在线 K 歌房。

示例项目

声网在 GitHub 上提供一个开源的示例项目 供你参考。

准备开发环境

本节介绍集成 AUIKaraoke 的前提条件和项目相关配置。

前提条件

  • Git

  • Android API Level 24 及以上

  • Android Studio 3.5 及以上

  • Android 设备,版本 Android 7.0 及以上

    注意

    声网推荐使用真机运行项目。部分模拟机可能存在功能缺失或者性能问题。

  • Java Development Kit 17 及以上

  • 你的声网项目的 App ID、证书,以及环信项目的 APPKEY、Client ID 以及 Client Secret,如何获取请参考开通 UIKit 开源方案相关服务

创建项目并配置权限

本节介绍如何创建项目并为项目添加体验实时互动所需的权限。

  1. 如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目,如果你已有 Android 项目,可跳过这一步骤。

    信息

    创建项目后,Android Studio 会自动开始同步 Gradle,稍等片刻,待同步成功后再进行下一步操作。

  2. 配置项目权限。在 app/src/main/AndroidManifest.xml 文件中添加下列内容:

    XML
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="io.agora.app.karaoke">
    
        <!-- asceneskit 运行所需权限 -->
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.CALL_PHONE" />
    
        ...
    </manifest>

    如果你使用的不是 https 的业务服务器域名,还需要在 app/src/main/AndroidManifest.xml 文件中将 usersCleartextTraffic 属性设为 true 以允许所有明文请求:

    XML
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="io.agora.app.karaoke">
    
        ...
    
        <application
            ...
            android:usesCleartextTraffic="true">
    
            ...
        </application>
    
    </manifest>
  3. 防止代码混淆。打开 app/proguard-rules.pro 文件,添加如下行以防止代码混淆:

    Java
    -keep class io.agora.**{*;}
    -dontwarn javax.**
    -dontwarn com.google.devtools.build.android.**

添加依赖库

  1. 下载声网提供的 AUIKaraoke 源码。运行以下命令克隆项目到本地:

    Shell
    git clone git@github.com:AgoraIO-Community/AUIKaraoke.git
  2. 将 AUIKaraoke 源码目录下 Android/asceneskit 文件夹复制到与你的 App 文件夹所在的同一级目录下。

  3. 将 AUIKaraoke 源码目录下 Android/app/src/main/java/io/agora/app/karaoke/KaraokeUIKit.kt 类复制到你的项目的 app/src/main/java/<package_name> 目录下。

  4. 添加 asceneskit 库到你的项目中。在 settings.gradle.kts 文件中,将 dependencyResolutionManagement 替换为下列代码:

    Kotlin
    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
            // 添加 jitpack 仓库
            maven { url = java.net.URI.create("https://www.jitpack.io") }
        }
    }
    
    
    rootProject.name = "KaraokeApp"
    include(":app")
    // 添加 asceneskit 库到项目里
    include(":asceneskit")
  5. 添加 namespace。(可选)

    信息

    如果你使用的 Android Gradle Plugin 版本为 8.0,则需要添加 namespace,否则可跳过该步骤。

  1. 修改 Java 版本号。(可选)

    信息

    如果你使用的 Java Development Kit 版本为 17,则需要修改版本号,否则可跳过该步骤。

  1. 设置主题样式。

    1. 在 app/src/main/res/values/themes.xml 文件中修改主题(Theme)为 K 歌房主题:

      XML
      <resources>
      
          <!-- Karaoke 主题 -->
          <style name="Theme.KaraokeApp" parent="Theme.AKaraoke" />
      
      </resources>
    2. 在 app/src/main/AndroidManifest.xml 文件中添加主题:

      XML
      <application
          ···
      android:theme="@style/Theme.KaraokeApp">
          ···
      </application>
  2. 添加 asceneskit 依赖。

    在 app/build.gradle.kts 文件中添加 asceneskit 依赖。

    Kotlin
    dependencies {
        ...
    
        // asceneskit依赖
        implementation(project(":asceneskit"))
    }
  3. 点击 Sync Project with Gradle Files 来同步项目。

创建在线 K 歌房

本节介绍如何以房主身份快速搭建一个在线 K 歌房来体验 K 歌场景。

1. 初始化 AUIKaraoke

调用 setup 初始化 KaraokeUIKit。打开 app/src/main/java/MainActivity.kt 文件,在 onCreate 方法里调用 setup 进行初始化。

Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...

    // 初始化 KaraokeUiKit
    val config = AUICommonConfig()
    config.context = this
    // 你的业务服务器域名
    config.host = ""
    // 你的声网 AppID
    config.appId = ""
    // 你的声网 App 证书
    config.appCert = ""
    // 你的 IM AppKey
    config.imAppKey = ""
    // 你的 IM Client ID
    config.imClientId = ""
    // 你的 IM Client Secret
    config.imClientSecret = ""
    config.owner = AUIUserThumbnailInfo().apply {
        // 用户 ID
        userId = (Random().nextInt(1000) + 10000).toString()
        // 用户名
        userName = "User-$userId"
        // 用户头像
        userAvatar = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png"
    }
    // Setup KaraokeUIKit
    KaraokeUIKit.setup(
        commonConfig = config, // must
        apiConfig = AUIAPIConfig(
            ktvApi = null,
            rtcEngineEx = null,
            rtmClient = null
        )
    )
}

2. 创建并进入房间

  1. 添加创建房间按钮。

    1. 在 app/src/main/res 路径下新建一个名为 layout 的文件夹,在该文件夹下创建一个 .xml 文件,文件名为 main_activity.xml,然后将下列代码复制到该文件中:

      Kotlin
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center">
      
          <Button
              android:id="@+id/btnCreateRoom"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginBottom="12dp"
              android:text="创建房间"/>
      
      </LinearLayout>
    2. 设置 UI 布局。打开 app/src/main/java/MainActivity.kt 文件,设置 xml 布局并设置按钮点击事件。

      Kotlin
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          // 将 jectpack compose 布局改成 xml 布局
          setContentView(R.layout.main_activity)
      
          // 设置点击事件并弹窗
          findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
              // 创建房间按钮点击
      
          }
      }
  2. 创建房间详情页界面。

    1. 在 app/src/main/res/layout/ 路径下新建一个 .xml 文件,文件名为 room_activity.xml,然后将下列代码复制到该文件中:

      XML
      <?xml version="1.0" encoding="utf-8"?>
      <io.agora.asceneskit.karaoke.KaraokeRoomView
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/karaokeRoomView"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
    2. 在 app/src/main/java/MainActivity.kt 同级目录下创建一个 RoomActivity 类用于显示和处理与在线 K 歌房间相关的用户界面和逻辑。

      Kotlin
      class RoomActivity : FragmentActivity() {
      
          companion object {
              const val EXTRA_ROOM_INFO = "RoomInfo"
              const val EXTRA_IS_CREATE = "isCreate"
      
              fun launch(context: Context, roomInfo: AUIRoomInfo, isCreate: Boolean){
                  val intent = Intent(context, RoomActivity::class.java)
                  intent.putExtra(EXTRA_ROOM_INFO, roomInfo)
                  intent.putExtra(EXTRA_IS_CREATE, isCreate)
                  context.startActivity(intent)
              }
          }
      
          // 房间信息
          private val isCreate by lazy {
              intent.getSerializableExtra(EXTRA_ROOM_INFO) as AUIRoomInfo
          }
      
          // 是否创建房间
          private val isCreate by lazy {
              intent.getBooleanExtra(EXTRA_IS_CREATE, false)
          }
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              // 设置布局
              setContentView(R.layout.room_activity)
      
              // 初始化布局
              val karaokeRoomView = findViewById<KaraokeRoomView>(R.id.karaokeRoomView)
              karaokeRoomView.setFragmentActivity(this@RoomActivity)
      
      
          }
      }
    3. 在 app/src/main/AndroidManifest.xml 文件中配置 RoomActivity:

      XML
      <application>
          ...
      
          <activity android:name=".RoomActivity"
              android:windowSoftInputMode="adjustNothing"/>
      
      </application>
  3. 进入 K 歌房间。用户点击创建房间按钮后,随机生成一个房间名和 ID 并进入到新创建的房间中。在 MainActivity.kt 文件中,将下列示例代码添加至 findViewById<Button>(R.id.btnCreateRoom).setOnClickListener { 之后:

    Kotlin
    findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
        // 点击创建房间按钮
        // 随机生成房间名
        val roomName = "${Random().nextInt(100) + 1000}"
        val roomInfo = AUIRoomInfo()
        roomInfo.roomId = UUID.randomUUID().toString()
        roomInfo.roomName = roomName
        roomInfo.thumbnail = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png"
        roomInfo.owner = AUIRoomContext.shared().currentUserInfo
        RoomActivity.launch(this@MainActivity, roomInfo, true)
    }
  4. 启动房间。

    在 RoomActivity 的onCreate方法里,调用 createRoom 创建并启动房间。在 app/src/main/java/RoomActivity 文件中,将下列代码添加至初始化布局之后:

    Kotlin
    class RoomActivity : FragmentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
    
            ...
    
            // 检查并申请运行时权限
            PermissionHelp(this).checkMicPerm(
                granted = {
                    // 获取到权限
    
                    // 生成 RoomConfig 配置
                    KaraokeUIKit.generateToken(roomInfo.roomId,
                        onSuccess = { roomConfig ->
                            // 启动房间
                            if(isCreate){
                                // 创建并进入房间
                                KaraokeUIKit.createRoom(roomInfo, roomConfig, karaokeRoomView){ ex, roomInfo ->
                                    if(ex != null){
                                        // 创建房间失败,直接退出
                                        finish()
                                    }
                                }
                            }
                        },
                        onFailure = {
                            // 获取 Token 失败,直接退出
                            finish()
                        })
                },
                unGranted = {
                    // 没有获取到权限
                    finish()
                })
        }
    }

至此,你已经成功创建一个在线 K 歌房。

测试 App

按照以下步骤测试你的 App:

  1. 开启 Android 设备的开发者选项,打开 USB 调试,通过 USB 连接线将 Android 设备接入电脑,并在 Android 设备选项中勾选你的 Android 设备。

  2. 在 Android Studio 中,点击 Sync Project with Gradle Files 按钮,以让项目与 Gradle 文件同步。

  3. 待同步成功后,点击 运行 开始编译。

  4. 编译成功后,你的 Android 设备上会出现 AUIKaraoke App。打开 App,点击创建房间创建一个新的房间来体验在线 K 歌。

后续步骤

成功搭建一个在线 K 歌房间后,你还可以参考本节来进一步了解启动 K 歌房间后的后续步骤。

听众进入房间

  1. 添加加入房间按钮。

    1. 在 app/src/main/java/res/layout/main_activity.xml 文件中,添加下列代码:

      XML
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          ...
      
          <Button
              android:id="@+id/btnJoinRoom"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginBottom="12dp"
              android:text="加入房间"/>
      
      </LinearLayout>
    2. 在 app/src/main/java/MainActivity.kt 文件中设置点击事件,并弹出输入房间名的弹窗。

      Kotlin
      findViewById<Button>(R.id.btnJoinRoom).setOnClickListener {
          // 弹出房间名输入弹窗
          val input = EditText(this@MainActivity)
          input.hint = "Room Name"
          AlertDialog.Builder(this@MainActivity)
              .setTitle("Launch Room")
              .setView(input)
              .setPositiveButton("Confirm"){ dialog: DialogInterface, i: Int ->
                  // 确认加入房间
      
              }
              .setNegativeButton("Cancel"){ dialog: DialogInterface, i: Int ->
                  dialog.dismiss()
              }
              .show()
      }
  2. 获取房间信息以加入房间。

    在 app/src/main/java/MainActivity.kt 文件中,将下列代码添加至 setPositiveButton 之后:

    Kotlin
    val roomName = input.text.toString()
    if(TextUtils.isEmpty(roomName)){
        Toast.makeText(this@MainActivity, "Room name is empty", Toast.LENGTH_SHORT).show()
        dialog.dismiss()
        return@setPositiveButton
    }
    // 查询房间信息
    KaraokeUIKit.getRoomList(0, 50,
        success = { list ->
            val roomInfo = list.findLast { it.roomName == roomName }
            if(roomInfo == null){
                Toast.makeText(this@MainActivity, "The room is unavailable. RoomName=$roomName", Toast.LENGTH_SHORT).show()
                dialog.dismiss()
                return@getRoomList
            }
            // 启动房间
            RoomActivity.launch(this@MainActivity, roomInfo, false)
        },
        failure = {
            Toast.makeText(this@MainActivity, "Get room list failed. ${it.code} - ${it.message}", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        })
  3. 进入房间。

    在 RoomActivity 获取到 roomConfig 后,调用 enterRoom 进入房间。在 app/src/main/java/RoomActivity 文件中,将下列代码添加至获取到 roomConfig 之后:

    Kotlin
    KaraokeUIKit.generateToken(roomInfo.roomId,
    onSuccess = {roomConfig ->
        // 启动房间
        if(isCreate){
            // 创建并进入房间
            ...
        }else{
            // 进入房间
            KaraokeUIKit.enterRoom(roomInfo, roomConfig, karaokeRoomView){ ex, roomInfo ->
                if(ex != null){
                    // 进入房间失败,直接退出
                    finish()
                }
            }
        }
    },
    onFailure = {
        // 获取 Token 失败,直接退出
        finish()
    })

退出及销毁房间

  • 当房间被销毁时,退出该房间。

    调用 registerRoomRespObserver 方法来注册房间事件观测器。通过 onRoomDestroy 回调获取房间销毁事件。当房间被销毁时,调用 leaveRoom 退出该房间。在 app/src/main/java/RoomActivity.kt 文件中,添加下列代码:

    Kotlin
    // 房间事件观测器
    private val roomManagerRespObserver = object: AUIKaraokeRoomServiceRespObserver{
        override fun onRoomDestroy(roomId: String) {
            super.onRoomDestroy(roomId)
            // 房间被销毁
            destroyRoom()
            finish()
        }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
    
        // 注册房间事件观测器
        KaraokeUIKit.registerRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
    }
    
    private fun destroyRoom() {
        // 退出房间
        KaraokeUIKit.leaveRoom(roomInfo.roomId)
        // 取消注册房间事件观测器
        KaraokeUIKit.unRegisterRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
    }
  • 主动退出并销毁房间。

    当你结束 K 歌并需要释放 K 歌房使用的所有资源时,调用 leaveRoom 来退出并销毁房间。然后调用 unRegisterRoomRespObserver 来取消注册房间事件观察器,取消后不会再收到任何房间事件的通知。在 app/src/main/java/RoomActivity.kt 文件中,添加下列代码:

    Kotlin
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 设置布局
        setContentView(R.layout.room_activity)
        // 初始化布局
        val karaokeRoomView = findViewById<KaraokeRoomView>(R.id.karaokeRoomView)
        karaokeRoomView.setFragmentActivity(this@RoomActivity)
        karaokeRoomView.setOnShutDownClick {
            // 主动退出房间
            destroyRoom()
            finish()
        }
        ...
    }
    
    
    override fun onBackPressed() {
        destroyRoom()
        super.onBackPressed()
    }
    
    
    private fun destroyRoom() {
        // 退出、销毁房间
        KaraokeUIKit.leaveRoom(roomInfo.roomId)
        // 取消注册房间事件观察器
        KaraokeUIKit.unRegisterRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
    }

API 参考