实时语音通话能够拉近人与人之间的距离,为用户提供沉浸式的交流体验,帮助你的 app 提高用户黏性。
本文介绍如何通过少量代码集成 Agora 音频 SDK 并调用 API,在你的应用中实现高质量、低延迟的语音通话功能。
下图展示在 app 中集成声网语音通话的基本工作流程:
如图所示,实现语音通话的步骤如下:
joinChannel
创建并加入频道。使用同一频道名称的 app 客户端默认加入同一频道。App 客户端加入频道需要以下信息:
开始前,请确保你的开发环境满足以下条件:
实现语音通话之前,参考如下步骤设置你的项目:
如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目。
创建项目后,Android Studio 会自动开始同步 gradle。请确保同步成功再进行下一步操作。
使用 Maven Central 将 Agora 音频 SDK 集成到你的项目中。更多集成方式,请参考集成 SDK 的其他方法。
a. 在 /Gradle Scripts/build.gradle(Project: <projectname>)
文件中添加如下代码,以添加 Maven Central 依赖:
buildscript {
repositories {
...
mavenCentral()
}
...
}
allprojects {
repositories {
...
mavenCentral()
}
}
b. 在 /Gradle Scripts/build.gradle(Module: <projectname>.app)
文件中添加如下代码,将 Agora 音频 SDK 集成到你的 Android 项目中:
...
dependencies {
...
// x.y.z,请填写具体的 SDK 版本号,如:3.5.0 或 3.7.0.2。
// 通过发版说明获取最新版本号。
implementation 'io.agora.rtc:voice-sdk:x.y.z'
}
在 /app/Manifests/AndroidManifest.xml
文件中的 </application>
后面添加如下网络和设备权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 对于 Android 12.0 及以上设备,还需要添加如下权限: -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
在 /Gradle Scripts/proguard-rules.pro
文件中添加如下行,以防止声网 SDK 的代码被混淆:
-keep class io.agora.**{*;}
本节介绍如何使用声网音频 SDK 在你的 app 里实现语音通话。
将 /app/res/layout/activity_main.xml
文件中的内容替换成如下代码:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_gravity="center_vertical|start"
android:text="Welcome to the Agora Voice Call channel."/>
</FrameLayout>
</RelativeLayout>
参考如下步骤,导入必要的 Android 类,并添加授权必要权限的逻辑。
导入必要的 Android 类
在 /app/java/com.example.<projectname>/MainActivity
文件中的 package com.example.<projectname>
后添加如下代码:
// Java
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
// Kotlin
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import android.Manifest
import java.lang.Exception
添加必要权限的授权逻辑
启动应用程序时,检查是否已在 app 中授予了实现语音通话所需的权限。如果未授权,使用内置的 Android 功能申请权限;如果已授权,则返回 true
。
为实现授权逻辑,在 /app/java/com.example.<projectname>/MainActivity
文件的 onCreate
函数前添加如下代码:
// Java
private static final int PERMISSION_REQ_ID = 22;
// 待申请的权限
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
......
};
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
// Kotlin
private val PERMISSION_REQ_ID_RECORD_AUDIO = 22
private val PERMISSION_REQ_ID_CAMERA = PERMISSION_REQ_ID_RECORD_AUDIO + 1
private fun checkSelfPermission(permission: String, requestCode: Int): Boolean {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(permission),
requestCode)
return false
}
return true
}
应用开启时,你需要依次创建 RtcEngine
实例,加入频道,并在频道中发布本地音频。如果其他用户加入频道时,你的应用会捕捉到这一加入事件,并接收远端用户的音频。
下图展示语音通话的 API 调用时序:
按照以下步骤实现该逻辑:
导入必要的声网类。
在 /app/java/com.example.<projectname>/MainActivity
文件中的 import android.os.Bundle;
后添加如下代码:
// Java
import io.agora.rtc.RtcEngine;
import io.agora.rtc.IRtcEngineEventHandler;
// Kotlin
import io.agora.rtc.RtcEngine
import io.agora.rtc.IRtcEngineEventHandler
创建变量用以创建并加入语音通话频道。
在 /app/java/com.example.<projectname>/MainActivity
文件中的 AppCompatActivity {
后添加如下代码:
// Java
// 填写你的项目在声网控制台中生成的 App ID。
private String appId = "";
// 填写频道名称。
private String channelName = "";
// 填写声网控制台中生成的临时 Token。
private String token = "";
private RtcEngine mRtcEngine;
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
};
// Kotlin
// 填写你的项目在声网控制台中生成的 App ID。
private val APP_ID = ""
// 填写频道名称。
private val CHANNEL = ""
// 填写声网控制台中生成的临时 Token。
private val TOKEN = ""
private var mRtcEngine: RtcEngine ?= null
private val mRtcEventHandler = object : IRtcEngineEventHandler() {
}
初始化 app 并加入频道。
在 MainActivity
类中调用如下核心方法加入频道。在如下示例代码中,我们使用 initializeAndJoinChannel
函数来封装这些核心方法。
在 /app/java/com.example.<projectname>/MainActivity
文件中的 onCreate
函数后添加如下代码:
// Java
private void initializeAndJoinChannel() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), appId, mRtcEventHandler);
} catch (Exception e) {
throw new RuntimeException("Check the error");
}
mRtcEngine.joinChannel(token, channelName, "", 0);
}
// Kotlin
private fun initializeAndJoinChannel() {
try {
mRtcEngine = RtcEngine.create(baseContext, APP_ID, mRtcEventHandler)
} catch (e: Exception) {
}
mRtcEngine!!.joinChannel(TOKEN, CHANNEL, "", 0)
}
现在你已经完成语音通话的逻辑,接下来需要添加启动和关闭 app 的逻辑。用户打开你的 app 时,语音通话开始;用户关闭你的 app 关闭时,语音通话结束。
检查 app 是否获取正确的权限。如果已获取权限,调用 initializeAndJoinChannel
加入语音通话频道。
在 /app/java/com.example.<projectname>/MainActivity
文件中,用如下代码替换 MainActivity
类中的 onCreate
:
// Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID)) {
initializeAndJoinChannel();
}
}
// Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO, PERMISSION_REQ_ID_RECORD_AUDIO)) {
initializeAndJoinChannel();
}
}
当用户关闭 app 关闭时,清理你在 initializeAndJoinChannel
函数中创建的所有资源。
在 /app/java/com.example.<projectname>/MainActivity
文件的 onCreate
函数后添加 onDestroy
:
// Java
protected void onDestroy() {
super.onDestroy();
mRtcEngine.leaveChannel();
mRtcEngine.destroy();
}
// Kotlin
override fun onDestroy() {
super.onDestroy()
mRtcEngine?.leaveChannel()
RtcEngine.destroy()
}
按照以下步骤测试你的 app:
appId
和 token
参数中分别填写从声网控制台获取的 App ID 和临时 Token。在 channelName
中填写用于生成临时 token 的频道名称。Run 'app'
。片刻后,项目便会安装到你的设备上。Demo/index.html
文件,并输入相同的 App ID 和频道名称。在生产环境中,为保证通信安全,声网推荐从服务器中获取 Token,详情请参考使用 Token 鉴权。
本节提供了额外的信息供参考。
除了通过 Maven Central 集成 Agora 音频 SDK 外,你也可以手动复制 SDK 文件,将 SDK 导入你的项目。
在 SDK 下载页面下载最新版本的 Agora 音频 SDK,并解压。
打开 SDK 包 libs 文件夹,将以下文件或子文件夹复制到你的项目路径中。
文件或子文件夹 | 你的项目路径 |
---|---|
agora-rtc-sdk.jar 文件 |
/app/libs/ |
arm64-v8a 文件夹 |
/app/src/main/jniLibs/ |
armeabi-v7a 文件夹 |
/app/src/main/jniLibs/ |
x86 文件夹 |
/app/src/main/jniLibs/ |
x86_64 文件夹 |
/app/src/main/jniLibs/ |
include 文件夹 |
/app/src/main/jniLibs/ |
如果你使用 armeabi 架构, 请将 armeabi-v7a
文件夹的文件复制到你的项目 armeabi
文件中。如果出现不兼容问题,请联系我们。