快速集成 AUIKaraoke
AUIKaraoke 是一个基于 AUIKit 搭建的、针对 K 歌场景的开源 UI 组件,提供 K 歌房间相关功能。asceneskit 是 K 歌房的容器组件,你可以通过 asceneskit 自定义 K 歌房间的用户界面逻辑、实现房间管理等。
本文介绍如何通过 AUIKaraoke 快速搭建一个含 UI 界面的在线 K 歌房。
示例项目
声网在 GitHub 上提供一个开源的示例项目 供你参考。
准备开发环境
前提条件
-
Android API Level 24 及以上
-
Android Studio 3.5 及以上
-
Android 设备,版本 Android 7.0 及以上
注意声网推荐使用真机运行项目。部分模拟机可能存在功能缺失或者性能问题。
-
Java Development Kit 17 及以上
创建项目并配置权限
本小节介绍如何创建项目并为项目添加体验实时互动所需的权限。
-
如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目,如果你已有 Android 项目,可跳过这一步骤。
信息创建项目后,Android Studio 会自动开始同步 gradle, 稍等片刻至同步成功后再进行下一步操作。
-
配置项目权限
在
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> -
设置主题样式
-
在
app/src/main/res/values/themes.xml
文件中修改主题(Theme)为 K 歌房主题:XML<resources>
<!-- Karaoke 主题 -->
<style name="Theme.KaraokeApp" parent="Theme.AKaraoke" />
</resources> -
在
app/src/main/AndroidManifest.xml
文件中添加主题:XML<application
···
android:theme="@style/Theme.KaraokeApp">
···
</application>
-
-
防止代码混淆
打开
app/proguard-rules.pro
文件,添加如下行以防止代码混淆:Java-keep class io.agora.**{*;}
-dontwarn javax.**
-dontwarn com.google.devtools.build.android.**
添加依赖库
-
将 asceneskit 文件夹复制到你项目的根目录下。
-
添加
asceneskit
库到你的项目中。在settings.gradle.kts
文件中,将dependencyResolutionManagement
替换为下列代码:KotlindependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// 添加jitpack仓库:拉取auikit库
maven { url = java.net.URI.create("https://www.jitpack.io") }
}
}
rootProject.name = "KaraokeApp"
include(":app")
// 添加asceneskit库到项目里
include(":asceneskit") -
添加 namespace。(可选)
信息如果你使用的 Android Gradle Plugin 版本为 8.0,则需要添加 namespace,否则可跳过该步骤。
添加 namespace在
asceneskit/build.gradle
文件中添加 namespace。Javaandroid {
// Android Gradle Plugin 8.0 要求添加 namespace
namespace = "io.agora.asceneskit"
compileSdkVersion 30
...
} -
修改 Java 版本号。(可选)
信息如果你使用的 Java Development Kit 版本为 17,则需要修改版本号,否则可跳过该步骤。
修改版本在
asceneskit/build.gradle
文件中修改 Java 版本号。 -
添加 asceneskit 依赖。
在
app/build.gradle.kts
文件中添加 asceneskit 依赖。Kotlindependencies {
...
// asceneskit依赖
implementation(project(":asceneskit"))
} -
点击 Sync Project with Gradle Files 来同步项目。最终项目的目录结构如下图所示:
创建在线 K 歌房
本节介绍如何以房主身份快速搭建一个在线 K 歌房来体验 K 歌场景。
1. 初始化 AUIKaraoke
调用 setup
初始化 KaraokeUiKit。打开 app/src/main/java/MainActivity.kt
文件,在 onCreate
方法里调用 setup
进行初始化。
/override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
// 初始化 KaraokeUiKit
KaraokeUiKit.setup(AUICommonConfig().apply {
context = applicationContext
// 你的业务服务器域名
host = "https://service.agora.io/uikit-karaoke"
// 用户 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"
})
}
2. 创建房间
-
添加创建房间按钮。
-
在
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> -
设置 UI 布局。打开
app/src/main/java/MainActivity.kt
文件,设置 xml 布局并设置按钮点击事件。Kotlinoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 将jectpack compose布局改成xml布局
setContentView(R.layout.main_activity)
// 设置点击事件并弹窗
findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
// 创建房间按钮点击
}
}
-
-
创建 K 歌房间。
调用
createRoom
方法来创建房间。在调用该方法前,请确保你已调用setup
成功初始化。在MainActivity.kt
文件中,将下列示例代码添加至findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
之后:KotlinfindViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
// 点击创建房间按钮
// 随机生成房间名
val roomName = "${Random().nextInt(100) + 1000}"
// 调用 createRoom 创建房间
val createRoomInfo = AUICreateRoomInfo()
createRoomInfo.roomName = roomName
KaraokeUiKit.createRoom(
createRoomInfo,
success = { roomInfo ->
// 创建房间成功,跳转到房间详情页
RoomActivity.launch(this@MainActivity, roomInfo)
},
failure = {
// 创建房间失败
Toast.makeText(this@MainActivity, "Create Room failed. reason: ${it.code} - ${it.message}", Toast.LENGTH_SHORT).show()
}
)
}
3. 进入房间
-
创建房间详情页界面。
-
在
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" /> -
在
app/src/main/java/MainActivity.kt
同级目录下创建一个RoomActivity
类用于显示和处理与在线 K 歌房间相关的用户界面和逻辑。Kotlinclass RoomActivity : FragmentActivity() {
companion object {
const val EXTRA_ROOM_INFO = "RoomInfo"
fun launch(context: Context, roomInfo: AUIRoomInfo){
val intent = Intent(context, RoomActivity::class.java)
intent.putExtra(EXTRA_ROOM_INFO, roomInfo)
context.startActivity(intent)
}
}
// 房间信息
private val roomInfo by lazy {
intent.getSerializableExtra(EXTRA_ROOM_INFO) as AUIRoomInfo
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 设置布局
setContentView(R.layout.room_activity)
// 初始化布局
val karaokeRoomView = findViewById<KaraokeRoomView>(R.id.karaokeRoomView)
karaokeRoomView.setFragmentActivity(this@RoomActivity)
}
} -
在
app/src/main/AndroidManifest.xml
文件中配置RoomActivity
:XML<application >
...
<activity android:name=".RoomActivity"
android:windowSoftInputMode="adjustNothing"/>
</application>
-
-
启动房间。
在
RoomActivity
里初始化完成后,调用launchRoom
启动房间。在app/src/main/java/RoomActivity
文件中,将下列代码添加至初始化布局之后:Kotlin// 检查并申请运行时权限
PermissionHelp(this).checkMicPerm(
granted = {
// 获取到权限
// 启动房间
KaraokeUiKit.launchRoom(roomInfo, karaokeRoomView)
},
unGranted = {
// 没有获取到权限
finish()
}
)
至此,你已经成功创建一个在线 K 歌房。
测试 App
按照以下步骤测试你的 App:
-
开启 Android 设备的开发者选项,打开 USB 调试,通过 USB 连接线将 Android 设备接入电脑,并在 Android 设备选项中勾选你的 Android 设备。
-
在 Android Studio 中,点击 Sync Project with Gradle Files 按钮,以让项目与 Gradle 文件同步。
-
待同步成功后,点击
开始编译。
-
编译成功后,你的 Android 设备上会出现 AUIKaraoke App。打开 App,点击创建房间创建一个新的房间来体验在线 K 歌。
后续步骤
成功搭建一个在线 K 歌房间后,你还可以参考本节来进一步了解启动 K 歌房间后的后续步骤。
听众进入房间
-
添加加入房间按钮。
-
在
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> -
在
app/src/main/java/MainActivity.kt
文件中设置点击事件,并弹出输入房间名的弹窗。KotlinfindViewById<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()
}
-
-
获取房间信息以加入房间。
在
app/src/main/java/MainActivity.kt
文件中,将下列代码添加至setPositiveButton
之后:Kotlinval 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)
},
failure = {
Toast.makeText(this@MainActivity, "Get room list failed. ${it.code} - ${it.message}", Toast.LENGTH_SHORT).show()
dialog.dismiss()
})
退出及销毁房间
-
当房间被销毁时,退出该房间。
调用
registerRoomRespObserver
方法来注册房间事件观测器。通过onRoomDestroy
回调来房间销毁事件。当房间被销毁时,调用destroyRoom
来退出该房间。在app/src/main/java/RoomActivity.kt
文件中,添加下列代码:Kotlin// 房间事件观测器
private val roomManagerRespObserver = object: AUIRoomManagerRespObserver{
override fun onRoomDestroy(roomId: String) {
super.onRoomDestroy(roomId)
// 房间被销毁
destroyRoom()
finish()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
// 注册房间事件观测器
KaraokeUiKit.registerRoomRespObserver(roomManagerRespObserver)
}
private fun destroyRoom() {
// 退出/销毁房间
KaraokeUiKit.destroyRoom(roomInfo.roomId)
// 取消注册房间事件观测器
KaraokeUiKit.unRegisterRoomRespObserver(roomManagerRespObserver)
} -
主动退出并销毁房间。
当你结束 K 歌并需要释放 K 歌房使用的所有资源时,调用
destroyRoom
来退出并销毁房间。然后调用unRegisterRoomRespObserver
来取消注册房间事件观察器,取消后不会再收到任何房间事件的通知。在app/src/main/java/RoomActivity.kt
文件中,添加下列代码:Kotlinoverride 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.destroyRoom(roomInfo.roomId)
// 取消注册房间事件观察器
KaraokeUiKit.unRegisterRoomRespObserver(roomManagerRespObserver)
}