diff --git a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java index 839ebb022..6b7bb9062 100644 --- a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java +++ b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java @@ -69,8 +69,8 @@ private void init(AttributeSet attrs, int defStyle) { private void initPainters() { mWavePaint = new Paint(); - mWavePaint.setColor(mWaveColor);// 画笔为color - mWavePaint.setStrokeWidth(waveStrokeWidth);// 设置画笔粗细 + mWavePaint.setColor(mWaveColor);// Set paint color + mWavePaint.setStrokeWidth(waveStrokeWidth);// Set paint stroke width mWavePaint.setAntiAlias(true); mWavePaint.setFilterBitmap(true); mWavePaint.setStrokeCap(Paint.Cap.ROUND); @@ -78,8 +78,8 @@ private void initPainters() { Shader shader = new LinearGradient(0, 0, 1000, 0, 0xffffffff, 0xFFe850ee, Shader.TileMode.CLAMP); mWavePaint.setShader(shader); baseLinePaint = new Paint(); - baseLinePaint.setColor(mBaseLineColor);// 画笔为color - baseLinePaint.setStrokeWidth(1f);// 设置画笔粗细 + baseLinePaint.setColor(mBaseLineColor);// Set paint color + baseLinePaint.setStrokeWidth(1f);// Set paint stroke width baseLinePaint.setAntiAlias(true); baseLinePaint.setFilterBitmap(true); baseLinePaint.setStyle(Paint.Style.FILL); @@ -145,7 +145,7 @@ public void setMaxConstant(boolean maxConstant) { } /** - * 如果改变相应配置 需要刷新相应的paint设置 + * If you change the corresponding configuration, you need to refresh the paint settings */ public void invalidateNow() { initPainters(); diff --git a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java index 324fc3087..f096d04bf 100644 --- a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java +++ b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java @@ -16,7 +16,7 @@ * Executors * * @version 1.0 - * @since 16/4/28 下午4:07 + * @since 16/4/28 4:07 PM */ public class DefaultPoolExecutor extends ThreadPoolExecutor { diff --git a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java index 7a6f99fca..73fe50d33 100644 --- a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java +++ b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java @@ -12,7 +12,7 @@ * * @author zhilong Contact me. * @version 1.0 - * @since 15/12/25 上午10:51 + * @since 15/12/25 10:51 AM */ public class DefaultThreadFactory implements ThreadFactory { diff --git a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/FileUtils.java b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/FileUtils.java index f3c1210fa..415dd8909 100644 --- a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/FileUtils.java +++ b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/FileUtils.java @@ -32,27 +32,27 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin AssetManager assetManager = context.getAssets(); try { File file = new File(storagePath); - if (!file.exists()) {//如果文件夹不存在,则创建新的文件夹 + if (!file.exists()) {//If the folder does not exist, create a new folder file.mkdirs(); } - // 获取assets目录下的所有文件及目录名 + // Get all file and directory names under assets String[] fileNames = assetManager.list(assetsPath); - if (fileNames.length > 0) {//如果是目录 apk + if (fileNames.length > 0) {//If it's a directory for (String fileName : fileNames) { if (!TextUtils.isEmpty(assetsPath)) { - temp = assetsPath + SEPARATOR + fileName;//补全assets资源路径 + temp = assetsPath + SEPARATOR + fileName;//Complete assets resource path } String[] childFileNames = assetManager.list(temp); - if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) {//判断是文件还是文件夹:如果是文件夹 + if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) {//Check if it's a file or folder: if it's a folder copyFilesFromAssets(context, temp, storagePath + SEPARATOR + fileName); - } else {//如果是文件 + } else {//If it's a file InputStream inputStream = assetManager.open(temp); readInputStream(storagePath + SEPARATOR + fileName, inputStream); } } - } else {//如果是文件 doc_test.txt或者apk/app_test.apk + } else {//If it's a file like doc_test.txt or apk/app_test.apk InputStream inputStream = assetManager.open(assetsPath); if (assetsPath.contains(SEPARATOR)) {//apk/app_test.apk assetsPath = assetsPath.substring(assetsPath.lastIndexOf(SEPARATOR), assetsPath.length()); @@ -66,27 +66,27 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin } /** - * 读取输入流中的数据写入输出流 + * Read data from input stream and write to output stream * - * @param storagePath 目标文件路径 - * @param inputStream 输入流 + * @param storagePath Target file path + * @param inputStream Input stream */ public static void readInputStream(String storagePath, InputStream inputStream) { File file = new File(storagePath); try { if (!file.exists()) { - // 1.建立通道对象 + // 1. Create channel object FileOutputStream fos = new FileOutputStream(file); - // 2.定义存储空间 + // 2. Define storage space byte[] buffer = new byte[inputStream.available()]; - // 3.开始读文件 + // 3. Start reading file int lenght = 0; - while ((lenght = inputStream.read(buffer)) != -1) {// 循环从输入流读取buffer字节 - // 将Buffer中的数据写到outputStream对象中 + while ((lenght = inputStream.read(buffer)) != -1) {// Read buffer bytes from input stream in a loop + // Write data from Buffer to outputStream object fos.write(buffer, 0, lenght); } - fos.flush();// 刷新缓冲区 - // 4.关闭流 + fos.flush();// Flush buffer + // 4. Close streams fos.close(); inputStream.close(); } diff --git a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/YUVUtils.java b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/YUVUtils.java index 2cdb1f1f6..e5f16b33c 100644 --- a/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/YUVUtils.java +++ b/Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/YUVUtils.java @@ -184,7 +184,7 @@ public static byte[] toWrappedI420(ByteBuffer bufferY, return out; } /** - * I420转nv21 + * Convert I420 to NV21 */ public static byte[] I420ToNV21(byte[] data, int width, int height) { byte[] ret = new byte[data.length]; diff --git a/Android/APIExample-Audio/app/src/main/res/layout/fragment_ready_layout.xml b/Android/APIExample-Audio/app/src/main/res/layout/fragment_ready_layout.xml index 155790ea9..d4a1127fe 100644 --- a/Android/APIExample-Audio/app/src/main/res/layout/fragment_ready_layout.xml +++ b/Android/APIExample-Audio/app/src/main/res/layout/fragment_ready_layout.xml @@ -12,7 +12,7 @@ android:layout_marginTop="24dp" android:layout_marginEnd="24dp" android:textSize="17sp" - android:text="此示例演示了如何使用SDK进行语音通话的功能。"/> + android:text="@string/the_example_feature_tips"/> 耳机(TypeC) 蓝牙耳机 请打开通知权限,防止后台录音中断 + 此示例演示了如何使用SDK进行语音通话的功能。 \ No newline at end of file diff --git a/Android/APIExample-Audio/app/src/main/res/values/strings.xml b/Android/APIExample-Audio/app/src/main/res/values/strings.xml index ca378d453..9269092e1 100644 --- a/Android/APIExample-Audio/app/src/main/res/values/strings.xml +++ b/Android/APIExample-Audio/app/src/main/res/values/strings.xml @@ -94,4 +94,5 @@ headset(TypeC) bluetooth headset Please turn on notification permission to prevent background recording from being interrupted. + This example demonstrates how to use the SDK to implement voice call functionality. diff --git a/Android/APIExample-Compose/app/build.gradle.kts b/Android/APIExample-Compose/app/build.gradle.kts index 984e0b4ec..45a721f22 100644 --- a/Android/APIExample-Compose/app/build.gradle.kts +++ b/Android/APIExample-Compose/app/build.gradle.kts @@ -35,7 +35,7 @@ android { properties.load(rootProject.file("local.properties").inputStream()) val AGORA_APP_ID = properties.getProperty("AGORA_APP_ID", "") if (AGORA_APP_ID == "") { - throw GradleException("请在项目根目录下local.properties文件里正确配置:AGORA_APP_ID=<您的声网AppId>") + throw GradleException("Please configure correctly in the local.properties file in the project root directory: AGORA_APP_ID=") } val AGORA_APP_CERT = properties.getProperty("AGORA_APP_CERT", "") buildConfigField("String", "AGORA_APP_ID", "\"$AGORA_APP_ID\"") diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ChannelEncryption.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ChannelEncryption.kt index 198acabb0..c0409085d 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ChannelEncryption.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ChannelEncryption.kt @@ -172,7 +172,7 @@ fun ChannelEncryption() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val encryptionConfig = EncryptionConfig() encryptionConfig.encryptionMode = encryptionMode @@ -194,7 +194,7 @@ fun ChannelEncryption() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioRender.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioRender.kt index b3d6d9f98..34bde5ec8 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioRender.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioRender.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.unit.dp import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.AudioGrid import io.agora.api.example.compose.ui.common.AudioStatsInfo @@ -160,7 +161,7 @@ fun CustomAudioRender() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -171,7 +172,7 @@ fun CustomAudioRender() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioSource.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioSource.kt index 1b11b4605..b8ed266d2 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioSource.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomAudioSource.kt @@ -140,7 +140,7 @@ fun CustomAudioSource() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() option.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING option.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER option.publishMicrophoneTrack = false @@ -150,7 +150,7 @@ fun CustomAudioSource() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } CustomAudioSourceView( diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoRender.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoRender.kt index ef78e9e69..b0eae0fe0 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoRender.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoRender.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalSoftwareKeyboardController import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.TwoVideoView @@ -134,7 +135,7 @@ fun CustomVideoRender() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -143,7 +144,7 @@ fun CustomVideoRender() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoSource.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoSource.kt index 56a58dd61..daabf75ba 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoSource.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoSource.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalSoftwareKeyboardController import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.DropdownMenuRaw @@ -171,7 +172,7 @@ fun CustomVideoSource() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -185,7 +186,7 @@ fun CustomVideoSource() { externalVideoFramePusher.start() } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/HostAcrossChannel.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/HostAcrossChannel.kt index 024344fd7..32d51e53f 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/HostAcrossChannel.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/HostAcrossChannel.kt @@ -183,7 +183,7 @@ fun HostAcrossChannel() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -196,7 +196,7 @@ fun HostAcrossChannel() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelAudio.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelAudio.kt index 47b7a8c2b..b568104a3 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelAudio.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelAudio.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.AudioGrid import io.agora.api.example.compose.ui.common.AudioStatsInfo @@ -126,7 +127,7 @@ fun JoinChannelAudio() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.publishCameraTrack = false mediaOptions.publishMicrophoneTrack = true @@ -138,7 +139,7 @@ fun JoinChannelAudio() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideo.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideo.kt index 8aeeac6c9..97dd506db 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideo.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideo.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.VideoGrid @@ -151,7 +152,7 @@ fun JoinChannelVideo() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -161,7 +162,7 @@ fun JoinChannelVideo() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideoToken.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideoToken.kt index 0322d2823..6856f33fa 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideoToken.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinChannelVideoToken.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.VideoGrid @@ -154,7 +155,7 @@ fun JoinChannelVideoToken() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -162,7 +163,7 @@ fun JoinChannelVideoToken() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinMultiChannel.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinMultiChannel.kt index 1f3a8d7a2..c2b2c21ad 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinMultiChannel.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/JoinMultiChannel.kt @@ -156,7 +156,7 @@ fun JoinMultiChannel() { super.onLocalAudioStateChanged(state, reason) if (state == Constants.LOCAL_AUDIO_STREAM_STATE_STOPPED) { mainHandler.post { - Toast.makeText(context, "麦克风已关闭", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Microphone is turned off", Toast.LENGTH_SHORT).show() } } } @@ -174,7 +174,7 @@ fun JoinMultiChannel() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val options = ChannelMediaOptions() options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING options.clientRoleType = Constants.CLIENT_ROLE_AUDIENCE @@ -196,7 +196,7 @@ fun JoinMultiChannel() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LiveStreaming.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LiveStreaming.kt index d827cb97e..05bf81439 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LiveStreaming.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LiveStreaming.kt @@ -191,7 +191,7 @@ fun LiveStreaming() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = clientRole @@ -200,7 +200,7 @@ fun LiveStreaming() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } @@ -308,7 +308,8 @@ private fun LiveStreamingView( } ) { Text( - if (clientRole == Constants.CLIENT_ROLE_AUDIENCE) "开始连麦" else "关闭连麦" + if (clientRole == Constants.CLIENT_ROLE_AUDIENCE) stringResource(R.string.start_co_hosting) + else stringResource(R.string.stop_co_hosting) ) } } @@ -333,7 +334,7 @@ private fun LiveStreamingView( openSettingSheet = true } ) { - Text("Settings") + Text(stringResource(R.string.settings)) } } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LocalVideoTranscoding.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LocalVideoTranscoding.kt index 8996bcd38..359c0dba4 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LocalVideoTranscoding.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/LocalVideoTranscoding.kt @@ -184,7 +184,7 @@ fun LocalVideoTranscoding() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val dimension = SettingPreferences.getVideoDimensions() val width = dimension.width val height = dimension.height @@ -228,7 +228,7 @@ fun LocalVideoTranscoding() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaMetadata.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaMetadata.kt index 5c431f8bc..b5340b845 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaMetadata.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaMetadata.kt @@ -190,7 +190,7 @@ fun MediaMetadata() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = clientRole @@ -199,7 +199,7 @@ fun MediaMetadata() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaPlayer.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaPlayer.kt index 106c0b5bf..941d56a11 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaPlayer.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaPlayer.kt @@ -249,7 +249,7 @@ fun MediaPlayer() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_AUDIENCE @@ -262,7 +262,7 @@ fun MediaPlayer() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } MediaPlayerView( diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaRecorder.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaRecorder.kt index 83d41992b..5ec29865b 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaRecorder.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/MediaRecorder.kt @@ -165,7 +165,7 @@ fun MediaRecorder() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -174,7 +174,7 @@ fun MediaRecorder() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } val coroutineScope = rememberCoroutineScope() diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginAudioData.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginAudioData.kt index b67566201..e545e6f6f 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginAudioData.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginAudioData.kt @@ -127,7 +127,7 @@ fun OriginAudioData() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -137,7 +137,7 @@ fun OriginAudioData() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginVideoData.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginVideoData.kt index 14fab7bac..8855afd69 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginVideoData.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/OriginVideoData.kt @@ -31,8 +31,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.TwoVideoView @@ -187,7 +189,7 @@ fun OriginVideoData() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = clientRole @@ -196,7 +198,7 @@ fun OriginVideoData() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } @@ -286,7 +288,7 @@ private fun OriginVideoDataView( modifier = Modifier.align(Alignment.End).padding(16.dp, 0.dp), onClick = onScreenshotClick ) { - Text(text = "截图") + Text(text = stringResource(id = R.string.screenshot)) } ChannelNameInput( @@ -420,7 +422,7 @@ private class OriginVideoDataScreenshotTaker( ) val matrix = Matrix() matrix.setRotate(videoFrame.rotation.toFloat()) - // 围绕原地进行旋转 + // Rotate around the original position val newBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false) // save to file saveBitmap2Gallery(newBitmap) diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PictureInPicture.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PictureInPicture.kt index 06d045b00..7af8f1aa3 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PictureInPicture.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PictureInPicture.kt @@ -195,7 +195,7 @@ private fun PictureInPicture() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -208,7 +208,7 @@ private fun PictureInPicture() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PlayAudioFiles.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PlayAudioFiles.kt index 3b72f57fa..0119bc612 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PlayAudioFiles.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PlayAudioFiles.kt @@ -125,7 +125,7 @@ fun PlayAudioFiles() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -135,7 +135,7 @@ fun PlayAudioFiles() { } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PreCallTest.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PreCallTest.kt index f91338fe2..427bd3af4 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PreCallTest.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/PreCallTest.kt @@ -115,10 +115,10 @@ fun PreCallTest() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/RTMPStreaming.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/RTMPStreaming.kt index dd9f718cd..ff62acb62 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/RTMPStreaming.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/RTMPStreaming.kt @@ -196,7 +196,7 @@ fun RTMPStreaming() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = clientRole @@ -205,7 +205,7 @@ fun RTMPStreaming() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ScreenSharing.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ScreenSharing.kt index 1c769762d..920a1c8fb 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ScreenSharing.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/ScreenSharing.kt @@ -189,7 +189,7 @@ fun ScreenSharing() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() rtcEngine.startScreenCapture(screenCaptureParameters) val mediaOptions = ChannelMediaOptions() @@ -206,7 +206,7 @@ fun ScreenSharing() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } ScreenSharingView( diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SendDataStream.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SendDataStream.kt index 9ce1aeb8b..ca77b3b22 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SendDataStream.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SendDataStream.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalSoftwareKeyboardController import io.agora.api.example.compose.BuildConfig +import io.agora.api.example.compose.R import io.agora.api.example.compose.data.SettingPreferences import io.agora.api.example.compose.ui.common.ChannelNameInput import io.agora.api.example.compose.ui.common.InputRaw @@ -176,7 +177,7 @@ fun SendDataStream() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -185,7 +186,7 @@ fun SendDataStream() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SpatialSound.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SpatialSound.kt index 2e5b55e09..75c0e069f 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SpatialSound.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/SpatialSound.kt @@ -176,7 +176,7 @@ fun SpatialSound() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -189,7 +189,7 @@ fun SpatialSound() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VideoProcessExtension.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VideoProcessExtension.kt index 27ea702f5..a15820c70 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VideoProcessExtension.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VideoProcessExtension.kt @@ -164,7 +164,7 @@ fun VideoProcessExtension() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -173,7 +173,7 @@ fun VideoProcessExtension() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VoiceEffects.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VoiceEffects.kt index 4df78c431..f46e8a806 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VoiceEffects.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/VoiceEffects.kt @@ -118,7 +118,7 @@ fun VoiceEffects() { val allGranted = grantedMap.values.all { it } if (allGranted) { // Permission is granted - Toast.makeText(context, "Permission Granted", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show() val mediaOptions = ChannelMediaOptions() mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING mediaOptions.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER @@ -127,7 +127,7 @@ fun VoiceEffects() { } } else { // Permission is denied - Toast.makeText(context, "Permission Denied", Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show() } } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/ui/common/Widgets.kt b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/ui/common/Widgets.kt index 0bc72a042..e30668597 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/ui/common/Widgets.kt +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/ui/common/Widgets.kt @@ -637,7 +637,7 @@ fun RadioGroup( fun WidgetsPreview() { Column { SwitchRaw( - "Enable Video", + stringResource(R.string.enable_video), true, ) // SliderRaw("Bitrate", 0.5f) diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/FileUtils.java b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/FileUtils.java index 82bf81527..cce983c71 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/FileUtils.java +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/FileUtils.java @@ -53,27 +53,27 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin AssetManager assetManager = context.getAssets(); try { File file = new File(storagePath); - if (!file.exists()) { //如果文件夹不存在,则创建新的文件夹 + if (!file.exists()) { //If the folder does not exist, create a new folder file.mkdirs(); } - // 获取assets目录下的所有文件及目录名 + // Get all file and directory names under the assets directory String[] fileNames = assetManager.list(assetsPath); - if (fileNames.length > 0) { //如果是目录 apk + if (fileNames.length > 0) { //If it is a directory apk for (String fileName : fileNames) { if (!TextUtils.isEmpty(assetsPath)) { - temp = assetsPath + SEPARATOR + fileName; //补全assets资源路径 + temp = assetsPath + SEPARATOR + fileName; //Complete the assets resource path } String[] childFileNames = assetManager.list(temp); - if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) { //判断是文件还是文件夹:如果是文件夹 + if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) { //Determine if it is a file or folder: if it is a folder copyFilesFromAssets(context, temp, storagePath + SEPARATOR + fileName); - } else { //如果是文件 + } else { //If it is a file InputStream inputStream = assetManager.open(temp); readInputStream(storagePath + SEPARATOR + fileName, inputStream); } } - } else { //如果是文件 doc_test.txt或者apk/app_test.apk + } else { //If it is a file doc_test.txt or apk/app_test.apk InputStream inputStream = assetManager.open(assetsPath); if (assetsPath.contains(SEPARATOR)) { //apk/app_test.apk assetsPath = assetsPath.substring(assetsPath.lastIndexOf(SEPARATOR), assetsPath.length()); @@ -87,27 +87,27 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin } /** - * 读取输入流中的数据写入输出流 + * Read data from input stream and write to output stream * - * @param storagePath 目标文件路径 - * @param inputStream 输入流 + * @param storagePath Target file path + * @param inputStream Input stream */ public static void readInputStream(String storagePath, InputStream inputStream) { File file = new File(storagePath); try { if (!file.exists()) { - // 1.建立通道对象 + // 1. Create channel object FileOutputStream fos = new FileOutputStream(file); - // 2.定义存储空间 + // 2. Define storage space byte[] buffer = new byte[inputStream.available()]; - // 3.开始读文件 + // 3. Start reading file int lenght = 0; - while ((lenght = inputStream.read(buffer)) != -1) { // 循环从输入流读取buffer字节 - // 将Buffer中的数据写到outputStream对象中 + while ((lenght = inputStream.read(buffer)) != -1) { // Loop to read buffer bytes from input stream + // Write the data in the Buffer to the outputStream object fos.write(buffer, 0, lenght); } - fos.flush(); // 刷新缓冲区 - // 4.关闭流 + fos.flush(); // Flush buffer + // 4. Close streams fos.close(); inputStream.close(); } diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/GLTextureView.java b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/GLTextureView.java index 9397f2bf3..5b10f4b96 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/GLTextureView.java +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/GLTextureView.java @@ -39,7 +39,7 @@ import javax.microedition.khronos.opengles.GL10; /** - * 参考 {@link GLSurfaceView} 实现 + * Reference implementation based on {@link android.opengl.GLSurfaceView} * * @author fkwl5 */ @@ -89,7 +89,7 @@ public class GLTextureView extends TextureView implements TextureView.SurfaceTex public final static int DEBUG_LOG_GL_CALLS = 2; /** - * 构造方法,必须调用 {@link #setRenderer} 才能进行渲染 + * Constructor, must call {@link #setRenderer} for rendering to occur * * @param context the context */ diff --git a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/YUVUtils.java b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/YUVUtils.java index 7ab72bfef..b3ff48488 100644 --- a/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/YUVUtils.java +++ b/Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/utils/YUVUtils.java @@ -257,7 +257,7 @@ public static byte[] toWrappedI420(ByteBuffer bufferY, } /** - * I420转nv21 + * Convert I420 format to NV21 format * * @param data the data * @param width the width diff --git a/Android/APIExample-Compose/app/src/main/res/values-zh/strings.xml b/Android/APIExample-Compose/app/src/main/res/values-zh/strings.xml index 2c733c923..58992caf7 100644 --- a/Android/APIExample-Compose/app/src/main/res/values-zh/strings.xml +++ b/Android/APIExample-Compose/app/src/main/res/values-zh/strings.xml @@ -100,4 +100,10 @@ 帧率 方向 区域 + 截图 + 开始连麦 + 关闭连麦 + 权限已授予 + 权限被拒绝 + 启用视频 \ No newline at end of file diff --git a/Android/APIExample-Compose/app/src/main/res/values/strings.xml b/Android/APIExample-Compose/app/src/main/res/values/strings.xml index ab5edbb19..74a399a35 100644 --- a/Android/APIExample-Compose/app/src/main/res/values/strings.xml +++ b/Android/APIExample-Compose/app/src/main/res/values/strings.xml @@ -101,4 +101,10 @@ Frame Rate Orientation Area + Screenshot + Start Co-hosting + Stop Co-hosting + Permission Granted + Permission Denied + Enable Video \ No newline at end of file diff --git a/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/FileUtils.java b/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/FileUtils.java index 757c3b63a..940210376 100644 --- a/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/FileUtils.java +++ b/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/FileUtils.java @@ -14,7 +14,6 @@ public class FileUtils { /** - * 递归拷贝Asset目录中的文件到rootDir中 * Recursively copy the files in the Asset directory to rootDir * @param assets * @param path @@ -87,9 +86,8 @@ public static void copyToFileOrThrow(InputStream inputStream, File destFile) /** - * 解压压缩包 - * 解压后删除zip文件 - * unzip the package and delete thd zip file + * Unzip the package + * After unzipping, delete the zip file * @return */ public static boolean unzipAssetFile(Context context, String zipFilePath, File dstDir) { @@ -139,7 +137,7 @@ public static boolean unzipFile(ZipInputStream zipInputStream, File dstDir) { folder.mkdirs(); } else { - //否则创建文件,并输出文件的内容 + //Otherwise create a file and output its content File file = new File(dstDir, name); file.getParentFile().mkdirs(); file.createNewFile(); diff --git a/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/ResourceHelper.java b/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/ResourceHelper.java index af35ad13e..0e22a0d8b 100644 --- a/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/ResourceHelper.java +++ b/Android/APIExample/agora-simple-filter/src/main/java/io/agora/extension/ResourceHelper.java @@ -182,7 +182,6 @@ public static boolean isResourceReady(@NonNull final Context context, int versio boolean resourceReady = preferences.getBoolean("resource", false); int preVersioncode = preferences.getInt("versionCode", 0); - // 如果上次已经拷贝过 继续检查版本号 // Continue to check the version number if it was copied last time if (resourceReady && versionCode == preVersioncode){ return true; diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/MainActivity.java b/Android/APIExample/app/src/main/java/io/agora/api/example/MainActivity.java index 4038a7aa2..09c5dd2d6 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/MainActivity.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/MainActivity.java @@ -1,6 +1,5 @@ package io.agora.api.example; -import android.content.Intent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; @@ -27,21 +26,6 @@ protected void onCreate(Bundle savedInstanceState) { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); - - handleIntent(getIntent()); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - handleIntent(intent); - } - - private void handleIntent(Intent intent) { - if (intent != null) { - // 处理从通知栏启动的逻辑 - // 可以添加特定的标志来识别是否是从通知栏启动 - } } @Override diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/common/BaseBrowserFragment.java b/Android/APIExample/app/src/main/java/io/agora/api/example/common/BaseBrowserFragment.java index b42b3a240..45891090c 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/common/BaseBrowserFragment.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/common/BaseBrowserFragment.java @@ -89,15 +89,15 @@ private void initWebview() { mWebView.setFocusableInTouchMode(true); mWebView.setSaveEnabled(true); - // 硬件加速 + // Hardware acceleration requireActivity().getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); - // WebView 配置 + // WebView configuration WebSettings webSettings = mWebView.getSettings(); - // 后退 + // Back button handling requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { @@ -110,32 +110,32 @@ public void handleOnBackPressed() { } }); - // 缓存相关 - // mWebView.clearCache(true); // 清除缓存 - // mWebView.clearHistory(); // 清除历史 - // mWebView.clearFormData(); // 清除表单数据 - // 缓存模式 + // Cache related settings + // mWebView.clearCache(true); // Clear cache + // mWebView.clearHistory(); // Clear history + // mWebView.clearFormData(); // Clear form data + // Cache mode // LOAD_DEFAULT: - // 默认,根据 cache -control 决定是否从网络上取数据 + // Default, decides whether to fetch from network based on cache-control // LOAD_NORMAL: - // API level 17 中已经废弃, 从API level 11 开始作用同 LOAD_DEFAULT 模式 + // Deprecated in API level 17, from API level 11 it functions same as LOAD_DEFAULT // LOAD_CACHE_ELSE_NETWORK: - // 只要本地有,无论是否过期,或者 no -cache,都使用缓存中的数据 + // Use cached data if available, regardless of expiration or no-cache // LOAD_NO_CACHE: - // 不使用缓存,只从网络获取数据 + // Do not use cache, fetch data from network only // LOAD_CACHE_ONLY: - // 不使用网络,只读取本地缓存数据 - webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // 设置缓存模式 + // Do not use network, read only from local cache + webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // Set cache mode - // js 相关 - webSettings.setJavaScriptEnabled(true); // 支持 js。如果碰到后台无法释放 js 导致耗电,应在 onStop 和 onResume 里分别设成 false 和 true + // js related + webSettings.setJavaScriptEnabled(true); // Support js. If js cannot be released after background, it should be set to false in onStop and true in onResume webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setDomStorageEnabled(true); - // mWebView.addJavascriptInterface(new WebAppInterface(this), "android"); // js 接口 + // mWebView.addJavascriptInterface(new WebAppInterface(this), "android"); // js interface try { - // webSettings.setPluginsEnabled(true); // 支持插件 + // webSettings.setPluginsEnabled(true); // Support plugins Method setPluginsEnabled = webSettings.getClass().getMethod("setPluginsEnabled", Boolean.class); setPluginsEnabled.setAccessible(true); setPluginsEnabled.invoke(webSettings, true); @@ -144,16 +144,16 @@ public void handleOnBackPressed() { } - // 设置自适应屏幕,两者合用 - webSettings.setUseWideViewPort(true); // 将图片调整到适合 WebView 的大小 - webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 + // Set adaptive screen, both are used + webSettings.setUseWideViewPort(true); // Adjust image to fit WebView size + webSettings.setLoadWithOverviewMode(true); // Scale to screen size - // 缩放操作 - webSettings.setSupportZoom(true); // 支持缩放,默认为 true - webSettings.setBuiltInZoomControls(true); // 设置内置的缩放控件,若为 false,则该 WebView 不可缩放 - webSettings.setDisplayZoomControls(false); // 隐藏原生的缩放控件 + // Scaling operation + webSettings.setSupportZoom(true); // Support zoom, default is true + webSettings.setBuiltInZoomControls(true); // Set built-in zoom control, if false, this WebView cannot be zoomed + webSettings.setDisplayZoomControls(false); // Hide native zoom control - // 支持同时打开https和http + // Support opening https and http at the same time webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); mWebView.setWebChromeClient(new WebChromeClient() { diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/AVCallFloatView.java b/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/AVCallFloatView.java index 44faabb7b..b1aac3539 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/AVCallFloatView.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/AVCallFloatView.java @@ -20,31 +20,31 @@ public class AVCallFloatView extends FrameLayout { private static final String TAG = "AVCallFloatView"; /** - * 记录手指按下时在小悬浮窗的View上的横坐标的值 + * Record the horizontal coordinate value of the finger press on the small floating window view */ private float xInView; /** - * 记录手指按下时在小悬浮窗的View上的纵坐标的值 + * Record the vertical coordinate value of the finger press on the small floating window view */ private float yInView; /** - * 记录当前手指位置在屏幕上的横坐标值 + * Record the current finger position's horizontal coordinate value on the screen */ private float xInScreen; /** - * 记录当前手指位置在屏幕上的纵坐标值 + * Record the current finger position's vertical coordinate value on the screen */ private float yInScreen; /** - * 记录手指按下时在屏幕上的横坐标的值 + * Record the horizontal coordinate value of the finger press on the screen */ private float xDownInScreen; /** - * 记录手指按下时在屏幕上的纵坐标的值 + * Record the vertical coordinate value of the finger press on the screen */ private float yDownInScreen; @@ -103,16 +103,16 @@ public boolean onTouchEvent(MotionEvent event) { case MotionEvent.ACTION_MOVE: xInScreen = event.getRawX(); yInScreen = event.getRawY(); - // 手指移动的时候更新小悬浮窗的位置 + // Update the position of the small floating window when the finger moves updateViewPosition(); break; case MotionEvent.ACTION_UP: if (Math.abs(xDownInScreen - xInScreen) <= ViewConfiguration.get(getContext()).getScaledTouchSlop() && Math.abs(yDownInScreen - yInScreen) <= ViewConfiguration.get(getContext()).getScaledTouchSlop()) { - // 点击效果 + // Click effect Log.d(TAG, "this float window is clicked"); } else { - //吸附效果 + // Adsorption effect anchorToSide(); } break; @@ -220,7 +220,7 @@ public void run() { } private void updateViewPosition() { - //增加移动误差 + //Add movement error mParams.x = (int) (xInScreen - xInView); mParams.y = (int) (yInScreen - yInView); Log.e(TAG, "x " + mParams.x + " y " + mParams.y); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/FloatWindowHelper.java b/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/FloatWindowHelper.java index b6e136662..be8682247 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/FloatWindowHelper.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/common/floatwindow/FloatWindowHelper.java @@ -94,7 +94,7 @@ public static void destroyFloatView(@NonNull AVCallFloatView floatView) { * @return the boolean */ public static boolean checkPermission(Context context) { - //6.0 版本之后由于 google 增加了对悬浮窗权限的管理,所以方式就统一了 + // After Android 6.0, Google added management for floating window permissions, so the method is unified return commonROMPermissionCheck(context); } @@ -141,7 +141,7 @@ private static boolean oppoROMPermissionCheck(Context context) { } private static boolean commonROMPermissionCheck(Context context) { - //最新发现魅族6.0的系统这种方式不好用,天杀的,只有你是奇葩,没办法,单独适配一下 + // Recently found that this method doesn't work well on Meizu 6.0 system, only this one is special, need to adapt separately if (RomUtils.checkIsMeizuRom()) { return meizuPermissionCheck(context); } else { @@ -184,12 +184,12 @@ private static void oppoROMPermissionApply(final Context context) { } /** - * 通用 rom 权限申请 + * Common ROM permission application * * @param context Context. */ private static void commonROMPermissionApply(final Context context) { - //这里也一样,魅族系统需要单独适配 + // Same here, Meizu system needs to be adapted separately if (RomUtils.checkIsMeizuRom()) { meizuROMPermissionApply(context); } else { diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java b/Android/APIExample/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java index 6329cea8a..e148997f2 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/common/widget/WaveformView.java @@ -90,8 +90,8 @@ private void init(AttributeSet attrs, int defStyle) { private void initPainters() { mWavePaint = new Paint(); - mWavePaint.setColor(mWaveColor); // 画笔为color - mWavePaint.setStrokeWidth(waveStrokeWidth); // 设置画笔粗细 + mWavePaint.setColor(mWaveColor); // Set paint color + mWavePaint.setStrokeWidth(waveStrokeWidth); // Set paint stroke width mWavePaint.setAntiAlias(true); mWavePaint.setFilterBitmap(true); mWavePaint.setStrokeCap(Paint.Cap.ROUND); @@ -99,8 +99,8 @@ private void initPainters() { Shader shader = new LinearGradient(0, 0, 1000, 0, 0xffffffff, 0xFFe850ee, Shader.TileMode.CLAMP); mWavePaint.setShader(shader); baseLinePaint = new Paint(); - baseLinePaint.setColor(mBaseLineColor); // 画笔为color - baseLinePaint.setStrokeWidth(1f); // 设置画笔粗细 + baseLinePaint.setColor(mBaseLineColor); // Set paint color + baseLinePaint.setStrokeWidth(1f); // Set paint stroke width baseLinePaint.setAntiAlias(true); baseLinePaint.setFilterBitmap(true); baseLinePaint.setStyle(Paint.Style.FILL); @@ -236,7 +236,7 @@ public void setMaxConstant(boolean maxConstant) { } /** - * 如果改变相应配置 需要刷新相应的paint设置 + * If you change the corresponding configuration, you need to refresh the paint settings */ public void invalidateNow() { initPainters(); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java index 24f680374..c973a0168 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java @@ -325,7 +325,7 @@ public boolean onCaptureVideoFrame(int sourceType, VideoFrame videoFrame) { height); Matrix matrix = new Matrix(); matrix.setRotate(videoFrame.getRotation()); - // 围绕原地进行旋转 + // Rotate around the original position Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); // save to file saveBitmap2Gallery(newBitmap); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoProcessExtension.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoProcessExtension.java index 21144de08..d23741617 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoProcessExtension.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoProcessExtension.java @@ -71,11 +71,11 @@ public class VideoProcessExtension extends BaseFragment implements View.OnClickL private Button join; private Switch shapeBeauty, makeUp, beauty, virtualBackground, lightness2, colorful2, noiseReduce2; private SeekBar seek_lightness, seek_redness, seek_sharpness, seek_videoEnhance, seek_smoothness, seek_strength, seek_skin; - //美妆 + // Makeup private SeekBar sbBrowStrength, sbLashStrength, sbShadowStrength, sbPupilStrength, sbBlushStrength, sbLipStrength; private Spinner spinnerBrowStyle, spinnerLashStyle, spinnerShadowStyle, spinnerPupilStyle, spinnerBlushStyle, spinnerLipStyle; private Spinner spinnerBrowColor, spinnerLashColor, spinnerShadowColor, spinnerPupilColor, spinnerBlushColor, spinnerLipColor; - //美型 + // Beauty Shape private SeekBar sbShapeBeautifyAreaIntensity, sbShapeBeautifyStyleIntensity; private Spinner spinnerShapeBeautyArea, spinnerShapeBeautifyStyle; private EditText et_channel; @@ -137,7 +137,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat seek_skin = view.findViewById(R.id.skinProtect); seek_skin.setOnSeekBarChangeListener(this); - //美型 + // Beauty Shape sbShapeBeautifyAreaIntensity = view.findViewById(R.id.sb_shape_beautify_area_intensity); sbShapeBeautifyAreaIntensity.setOnSeekBarChangeListener(this); sbShapeBeautifyStyleIntensity = view.findViewById(R.id.sb_shape_beautify_style_intensity); @@ -148,7 +148,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat spinnerShapeBeautifyStyle = view.findViewById(R.id.spinner_shape_beautify_style); spinnerShapeBeautifyStyle.setOnItemSelectedListener(this); - //美妆 + // Makeup sbBrowStrength = view.findViewById(R.id.sb_brow_strength); sbBrowStrength.setOnSeekBarChangeListener(this); sbLashStrength = view.findViewById(R.id.sb_lash_strength); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeautySDK.kt b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeautySDK.kt index 4d496d55a..f01d6ee44 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeautySDK.kt +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeautySDK.kt @@ -25,10 +25,10 @@ object ByteDanceBeautySDK { private var beautyAPI: ByteDanceBeautyAPI? = null - // 特效句柄 + // Effect handle val renderManager = RenderManager() - // 美颜配置 + // Beauty configuration val beautyConfig = BeautyConfig() @@ -149,7 +149,7 @@ object ByteDanceBeautySDK { class BeautyConfig { - // 磨皮 + // Smooth skin var smooth = 0.65f set(value) { field = value @@ -158,7 +158,7 @@ object ByteDanceBeautySDK { } } - // 美白 + // Whitening var whiten = 0.5f set(value) { field = value @@ -167,7 +167,7 @@ object ByteDanceBeautySDK { } } - // 红润 + // Ruddy var redden = 0.0f set(value) { field = value @@ -176,7 +176,7 @@ object ByteDanceBeautySDK { } } - // 瘦脸 + // Face thinning var thinFace = 0.3f set(value) { field = value @@ -192,7 +192,7 @@ object ByteDanceBeautySDK { } } - // 大眼 + // Eye enlarging var enlargeEye = 0.0f set(value) { field = value @@ -204,7 +204,7 @@ object ByteDanceBeautySDK { } } - // 瘦颧骨 + // Cheekbone thinning var shrinkCheekbone = 0.3f set(value) { field = value @@ -220,7 +220,7 @@ object ByteDanceBeautySDK { } } - // 下颌骨 + // Jawbone var shrinkJawbone = 0.0f set(value) { field = value @@ -236,7 +236,7 @@ object ByteDanceBeautySDK { } } - // 美牙 + // Teeth whitening var whiteTeeth = 0.0f set(value) { field = value @@ -252,7 +252,7 @@ object ByteDanceBeautySDK { } } - // 额头 + // Forehead var hairlineHeight = 0.0f set(value) { field = value @@ -268,7 +268,7 @@ object ByteDanceBeautySDK { } } - // 瘦鼻 + // Nose thinning var narrowNose = 0.0f set(value) { field = value @@ -284,7 +284,7 @@ object ByteDanceBeautySDK { } } - // 嘴形 + // Mouth shape var mouthSize = 0.0f set(value) { field = value @@ -300,7 +300,7 @@ object ByteDanceBeautySDK { } } - // 下巴 + // Chin var chinLength = 0.0f set(value) { field = value @@ -316,7 +316,7 @@ object ByteDanceBeautySDK { } } - // 亮眼 + // Eye brightening var brightEye = 0.0f set(value) { field = value @@ -332,7 +332,7 @@ object ByteDanceBeautySDK { } } - // 祛黑眼圈 + // Dark circles removal var darkCircles = 0.0f set(value) { field = value @@ -348,7 +348,7 @@ object ByteDanceBeautySDK { } } - // 祛法令纹 + // Nasolabial folds removal var nasolabialFolds = 0.0f set(value) { field = value @@ -364,7 +364,7 @@ object ByteDanceBeautySDK { } } - // 锐化 + // Sharpen var sharpen = 0.0f set(value) { field = value @@ -377,7 +377,7 @@ object ByteDanceBeautySDK { } } - // 清晰度 + // Clarity var clear = 0.0f set(value) { field = value @@ -391,7 +391,7 @@ object ByteDanceBeautySDK { } - // 美妆 + // Makeup var makeUp: MakeUpItem? = null set(value) { if (field == value) { @@ -442,7 +442,7 @@ object ByteDanceBeautySDK { } - // 贴纸 + // Sticker var sticker: String? = null set(value) { if (field == value) { diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/FaceUnityBeautySDK.kt b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/FaceUnityBeautySDK.kt index 7d78db409..2c9c69914 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/FaceUnityBeautySDK.kt +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/FaceUnityBeautySDK.kt @@ -22,11 +22,11 @@ object FaceUnityBeautySDK { private const val TAG = "FaceUnityBeautySDK" - /* AI道具*/ + /* AI Props */ private const val BUNDLE_AI_FACE = "model/ai_face_processor.bundle" private const val BUNDLE_AI_HUMAN = "model/ai_human_processor.bundle" - // 美颜配置 + // Beauty configuration val beautyConfig = BeautyConfig() private var beautyAPI: FaceUnityBeautyAPI? = null @@ -99,7 +99,7 @@ object FaceUnityBeautySDK { private val fuRenderKit = FURenderKit.getInstance() - // 美颜配置 + // Beauty configuration private val faceBeauty: FaceBeauty get() { var faceBeauty = fuRenderKit.faceBeauty @@ -112,10 +112,10 @@ object FaceUnityBeautySDK { } - // 资源基础路径 + // Resource base path private val resourceBase = "beauty_faceunity" - // 磨皮 + // Smoothing var smooth = 0.65f set(value) { field = value @@ -124,7 +124,7 @@ object FaceUnityBeautySDK { } } - // 美白 + // Whitening var whiten = 0.65f set(value) { field = value @@ -133,7 +133,7 @@ object FaceUnityBeautySDK { } } - // 瘦脸 + // Face thinning var thinFace = 0.3f set(value) { field = value @@ -142,7 +142,7 @@ object FaceUnityBeautySDK { } } - // 大眼 + // Eye enlarging var enlargeEye = 0.0f set(value) { field = value @@ -151,7 +151,7 @@ object FaceUnityBeautySDK { } } - // 红润 + // Skin redness var redden = 0.0f set(value) { field = value @@ -160,7 +160,7 @@ object FaceUnityBeautySDK { } } - // 五官立体 + // 3D facial features var faceThree = 0.0f set(value) { field = value @@ -169,7 +169,7 @@ object FaceUnityBeautySDK { } } - // 瘦颧骨 + // Cheekbone thinning var shrinkCheekbone = 0.3f set(value) { field = value @@ -178,7 +178,7 @@ object FaceUnityBeautySDK { } } - // 下颌骨 + // Jawbone var shrinkJawbone = 0.0f set(value) { field = value @@ -187,7 +187,7 @@ object FaceUnityBeautySDK { } } - // 美牙 + // Teeth whitening var whiteTeeth = 0.0f set(value) { field = value @@ -196,7 +196,7 @@ object FaceUnityBeautySDK { } } - // 额头 + // Forehead var hairlineHeight = 0.0f set(value) { field = value @@ -205,7 +205,7 @@ object FaceUnityBeautySDK { } } - // 瘦鼻 + // Nose thinning var narrowNose = 0.0f set(value) { field = value @@ -214,7 +214,7 @@ object FaceUnityBeautySDK { } } - // 嘴形 + // Mouth shape var mouthSize = 0.0f set(value) { field = value @@ -223,7 +223,7 @@ object FaceUnityBeautySDK { } } - // 下巴 + // Chin var chinLength = 0.0f set(value) { field = value @@ -232,7 +232,7 @@ object FaceUnityBeautySDK { } } - // 亮眼 + // Eye brightening var brightEye = 0.0f set(value) { field = value @@ -241,7 +241,7 @@ object FaceUnityBeautySDK { } } - // 祛黑眼圈 + // Dark circles removal var darkCircles = 0.0f set(value) { field = value @@ -250,7 +250,7 @@ object FaceUnityBeautySDK { } } - // 祛法令纹 + // Nasolabial folds removal var nasolabialFolds = 0.0f set(value) { field = value @@ -259,7 +259,7 @@ object FaceUnityBeautySDK { } } - // 锐化 + // Sharpening var sharpen = 0.0f set(value) { field = value @@ -268,7 +268,7 @@ object FaceUnityBeautySDK { } } - // 贴纸 + // Sticker var sticker: String? = null set(value) { field = value @@ -281,7 +281,7 @@ object FaceUnityBeautySDK { } } - // 美妆 + // Makeup var makeUp: MakeUpItem? = null set(value) { field = value diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/SenseTimeBeautySDK.kt b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/SenseTimeBeautySDK.kt index 42bcd0985..fb14eb854 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/SenseTimeBeautySDK.kt +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/SenseTimeBeautySDK.kt @@ -19,38 +19,38 @@ object SenseTimeBeautySDK { private const val MODEL_106 = "models/M_SenseME_Face_Video_Template_p_3.9.0.3.model" // 106 // private const val MODEL_FACE_EXTRA = "models/M_SenseME_Face_Extra_Advanced_Template_p_2.0.0.model" // 282 - // private const val MODEL_AVATAR_HELP = "models/M_SenseME_Avatar_Help_p_2.3.7.model" // avatar人脸驱动 - // private const val MODEL_LIPS_PARSING = "models/M_SenseME_MouthOcclusion_p_1.3.0.1.model" // 嘴唇分割 - // private const val MODEL_HAND = "models/M_SenseME_Hand_p_6.0.8.1.model" // 手势 - // private const val MODEL_SEGMENT = "models/M_SenseME_Segment_Figure_p_4.14.1.1.model" // 前后背景分割 - // private const val MODEL_SEGMENT_HAIR = "models/M_SenseME_Segment_Hair_p_4.4.0.model" // 头发分割 - // private const val MODEL_FACE_OCCLUSION = "models/M_SenseME_FaceOcclusion_p_1.0.7.1.model" // 妆容遮挡 - // private const val MODEL_SEGMENT_SKY = "models/M_SenseME_Segment_Sky_p_1.1.0.1.model" // 天空分割 - // private const val MODEL_SEGMENT_SKIN = "models/M_SenseME_Segment_Skin_p_1.0.1.1.model" // 皮肤分割 + // private const val MODEL_AVATAR_HELP = "models/M_SenseME_Avatar_Help_p_2.3.7.model" // avatar face driving + // private const val MODEL_LIPS_PARSING = "models/M_SenseME_MouthOcclusion_p_1.3.0.1.model" // lips segmentation + // private const val MODEL_HAND = "models/M_SenseME_Hand_p_6.0.8.1.model" // gesture + // private const val MODEL_SEGMENT = "models/M_SenseME_Segment_Figure_p_4.14.1.1.model" // foreground and background segmentation + // private const val MODEL_SEGMENT_HAIR = "models/M_SenseME_Segment_Hair_p_4.4.0.model" // hair segmentation + // private const val MODEL_FACE_OCCLUSION = "models/M_SenseME_FaceOcclusion_p_1.0.7.1.model" // makeup occlusion + // private const val MODEL_SEGMENT_SKY = "models/M_SenseME_Segment_Sky_p_1.1.0.1.model" // sky segmentation + // private const val MODEL_SEGMENT_SKIN = "models/M_SenseME_Segment_Skin_p_1.0.1.1.model" // skin segmentation // private const val MODEL_3DMESH = "models/M_SenseME_3DMesh_Face2396pt_280kpts_Ear_p_1.1.0v2.model" // 3DMesh - // private const val MODEL_HEAD_P_EAR = "models/M_SenseME_Ear_p_1.0.1.1.model" // 搭配 mesh 耳朵模型 - // private const val MODEL_360HEAD_INSTANCE = "models/M_SenseME_3Dmesh_360Head2396pt_p_1.0.0.1.model" // 360度人头mesh - // private const val MODEL_FOOT = "models/M_SenseME_Foot_p_2.10.7.model" // 鞋子检测模型 - // private const val MODEL_PANT = "models/M_SenseME_Segment_Trousers_p_1.1.10.model" // 裤腿的检测 - // private const val MODEL_WRIST = "models/M_SenseME_Wrist_p_1.4.0.model" // 试表 - // private const val MODEL_CLOTH = "models/M_SenseME_Segment_Clothes_p_1.0.2.2.model" // 衣服分割 - // private const val MODEL_HEAD_INSTANCE = "models/M_SenseME_Segment_Head_Instance_p_1.1.0.1.model" // 实例分割版本 - // private const val MODEL_HEAD_P_INSTANCE = "models/M_SenseME_Head_p_1.3.0.1.model" // 360度人头-头部模型 - // private const val MODEL_NAIL = "models/M_SenseME_Nail_p_2.4.0.model" // 指甲检测 + // private const val MODEL_HEAD_P_EAR = "models/M_SenseME_Ear_p_1.0.1.1.model" // ear model with mesh + // private const val MODEL_360HEAD_INSTANCE = "models/M_SenseME_3Dmesh_360Head2396pt_p_1.0.0.1.model" // 360-degree head mesh + // private const val MODEL_FOOT = "models/M_SenseME_Foot_p_2.10.7.model" // shoe detection model + // private const val MODEL_PANT = "models/M_SenseME_Segment_Trousers_p_1.1.10.model" // trouser leg detection + // private const val MODEL_WRIST = "models/M_SenseME_Wrist_p_1.4.0.model" // watch try-on + // private const val MODEL_CLOTH = "models/M_SenseME_Segment_Clothes_p_1.0.2.2.model" // clothing segmentation + // private const val MODEL_HEAD_INSTANCE = "models/M_SenseME_Segment_Head_Instance_p_1.1.0.1.model" // instance segmentation version + // private const val MODEL_HEAD_P_INSTANCE = "models/M_SenseME_Head_p_1.3.0.1.model" // 360-degree head model + // private const val MODEL_NAIL = "models/M_SenseME_Nail_p_2.4.0.model" // nail detection private var stickerPackageId = 0 - // 特效句柄 + // Effect handle private var _mobileEffectNative: STMobileEffectNative? = null val mobileEffectNative get() = _mobileEffectNative ?: throw RuntimeException("Please initMobileEffect firstly!") - // 人脸识别句柄 + // Face recognition handle private var _humanActionNative: STMobileHumanActionNative? = null val humanActionNative get() = _humanActionNative ?: throw RuntimeException("Please initBeautySDK firstly!") - // 美颜配置 + // Beauty configuration val beautyConfig = BeautyConfig() private var beautyAPI: SenseTimeBeautyAPI? = null @@ -125,25 +125,27 @@ object SenseTimeBeautySDK { return } - // 其他模型配置 + // Other model configurations // _humanActionNative?.addSubModelFromAssetFile("$resourcePath/$MODEL_FACE_EXTRA", assets) - // 背景分割羽化程度[0,1](默认值0.35),0 完全不羽化,1羽化程度最高,在strenth较小时,羽化程度基本不变.值越大,前景与背景之间的过度边缘部分越宽. + // Background segmentation feathering degree [0,1] (default value 0.35), 0 means no feathering at all, 1 means maximum feathering. + // When strength is small, feathering remains basically unchanged. The larger the value, the wider the transition edge between foreground and background. // _humanActionNative?.setParam( // STHumanActionParamsType.ST_HUMAN_ACTION_PARAM_BACKGROUND_BLUR_STRENGTH, // 0.35f // ) - // 设置face mesh结果输出坐标系,(0: 屏幕坐标系, 1:3d世界坐标系, 2:3d摄像机坐标系,是摄像头透视投影坐标系, 原点在摄像机 默认是0) + // Set face mesh result output coordinate system (0: screen coordinate system, 1: 3D world coordinate system, + // 2: 3D camera coordinate system, which is the camera perspective projection coordinate system, with origin at the camera, default is 0) // _humanActionNative?.setParam( // STHumanActionParamsType.ST_HUMAN_ACTION_PARAM_FACE_MESH_OUTPUT_FORMAT, // 1.0f // ) - // 设置mesh渲染模式 + // Set mesh rendering mode // _humanActionNative?.setParam( // STHumanActionParamsType.ST_HUMAN_ACTION_PARAM_MESH_MODE, // STCommonNative.MESH_CONFIG.toFloat() // ) - // 设置人头实例分割 + // Set head instance segmentation // _humanActionNative?.setParam( // STHumanActionParamsType.ST_HUMAN_ACTION_PARAM_HEAD_SEGMENT_INSTANCE, // 1.0f @@ -167,7 +169,7 @@ object SenseTimeBeautySDK { } open class BeautyConfig { - // 磨皮 + // Smoothing var smooth = 0.75f set(value) { field = value @@ -184,7 +186,7 @@ object SenseTimeBeautySDK { } } - // 美白 + // Whitening var whiten = 0.75f set(value) { field = value @@ -201,7 +203,7 @@ object SenseTimeBeautySDK { } } - // 瘦脸 + // Face thinning var thinFace = 0.3f set(value) { field = value @@ -214,8 +216,7 @@ object SenseTimeBeautySDK { } } - - // 大眼 + // Eye enlargement var enlargeEye = 0.0f set(value) { field = value @@ -228,7 +229,7 @@ object SenseTimeBeautySDK { } } - // 红润 + // Skin redness var redden = 0.0f set(value) { field = value @@ -241,8 +242,7 @@ object SenseTimeBeautySDK { } } - - // 瘦颧骨 + // Cheekbone thinning var shrinkCheekbone = 0.3f set(value) { field = value @@ -255,7 +255,7 @@ object SenseTimeBeautySDK { } } - // 下颌骨 + // Jawbone thinning var shrinkJawbone = 0.0f set(value) { field = value @@ -268,7 +268,7 @@ object SenseTimeBeautySDK { } } - // 美牙 + // Teeth whitening var whiteTeeth = 0.0f set(value) { field = value @@ -281,7 +281,7 @@ object SenseTimeBeautySDK { } } - // 额头 + // Hairline height var hairlineHeight = 0.0f set(value) { field = value @@ -294,7 +294,7 @@ object SenseTimeBeautySDK { } } - // 瘦鼻 + // Nose narrowing var narrowNose = 0.0f set(value) { field = value @@ -307,7 +307,7 @@ object SenseTimeBeautySDK { } } - // 嘴形 + // Mouth size var mouthSize = 0.0f set(value) { field = value @@ -320,8 +320,7 @@ object SenseTimeBeautySDK { } } - - // 下巴 + // Chin length var chinLength = 0.0f set(value) { field = value @@ -333,7 +332,7 @@ object SenseTimeBeautySDK { } } - // 亮眼 + // Bright eyes var brightEye = 0.0f set(value) { field = value @@ -346,7 +345,7 @@ object SenseTimeBeautySDK { } } - // 祛黑眼圈 + // Remove dark circles var darkCircles = 0.0f set(value) { field = value @@ -359,7 +358,7 @@ object SenseTimeBeautySDK { } } - // 祛法令纹 + // Remove nasolabial folds var nasolabialFolds = 0.0f set(value) { field = value @@ -372,7 +371,7 @@ object SenseTimeBeautySDK { } } - // 饱和度 + // Saturation var saturation = 0.0f set(value) { field = value @@ -385,7 +384,7 @@ object SenseTimeBeautySDK { } } - // 对比度 + // Contrast var contrast = 0.0f set(value) { field = value @@ -398,7 +397,7 @@ object SenseTimeBeautySDK { } } - // 锐化 + // Sharpen var sharpen = 0.0f set(value) { field = value @@ -411,8 +410,7 @@ object SenseTimeBeautySDK { } } - - // 清晰度 + // Clarity var clear = 0.0f set(value) { field = value @@ -425,7 +423,7 @@ object SenseTimeBeautySDK { } } - // 美妆 + // Makeup var makeUp: MakeUpItem? = null set(value) { field = value @@ -450,7 +448,7 @@ object SenseTimeBeautySDK { } } - // 贴纸 + // Sticker var sticker: StickerItem? = null set(value) { field = value diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/videoRender/GLTextureView.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/videoRender/GLTextureView.java index 5ee769b76..0372be4bd 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/videoRender/GLTextureView.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/videoRender/GLTextureView.java @@ -39,7 +39,7 @@ import javax.microedition.khronos.opengles.GL10; /** - * 参考 {@link GLSurfaceView} 实现 + * {@link android.opengl.GLSurfaceView} * * @author fkwl5 */ @@ -89,7 +89,7 @@ public class GLTextureView extends TextureView implements TextureView.SurfaceTex public final static int DEBUG_LOG_GL_CALLS = 2; /** - * 构造方法,必须调用 {@link #setRenderer} 才能进行渲染 + * Constructor, must call {@link #setRenderer} for rendering to occur * * @param context the context */ diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java index a5cd77878..8e70d72e7 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultPoolExecutor.java @@ -16,7 +16,7 @@ * Executors * * @version 1.0 - * @since 16 /4/28 下午4:07 + * @since 16 /4/28 PM 4:07 */ public final class DefaultPoolExecutor extends ThreadPoolExecutor { private static final String TAG = DefaultPoolExecutor.class.getSimpleName(); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java index 407dd71c4..02e5333b7 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/DefaultThreadFactory.java @@ -12,7 +12,7 @@ * * @author zhilong Contact me. * @version 1.0 - * @since 15 /12/25 上午10:51 + * @since 15/12/25 10:51 AM */ public class DefaultThreadFactory implements ThreadFactory { private static final String TAG = DefaultThreadFactory.class.getSimpleName(); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileKtUtils.kt b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileKtUtils.kt index 8b7f20ce6..9c729c2fa 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileKtUtils.kt +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileKtUtils.kt @@ -53,7 +53,7 @@ object FileKtUtils { val sb = StringBuilder() var isr: InputStreamReader? = null var br: BufferedReader? = null - // 读取license文件内容 + // Read license file content try { isr = InputStreamReader(context.resources.assets.open(path)) br = BufferedReader(isr) @@ -90,9 +90,9 @@ object FileKtUtils { * @param targetPath */ fun copyAssets(context: Context, assetsPath: String, targetPath: String) { - // 获取assets目录assetDir下一级所有文件以及文件夹 + // Get all files and folders in the assets directory val fileNames = context.resources.assets.list(assetsPath) - // 如果是文件夹(目录),则继续递归遍历 + // If it's a folder (directory), continue recursively traversing if (fileNames?.isNotEmpty() == true) { val targetFile = File(targetPath) if (!targetFile.exists() && !targetFile.mkdirs()) { diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileUtils.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileUtils.java index 7bd8cbeaf..df141589b 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileUtils.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/FileUtils.java @@ -53,27 +53,26 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin AssetManager assetManager = context.getAssets(); try { File file = new File(storagePath); - if (!file.exists()) { //如果文件夹不存在,则创建新的文件夹 + if (!file.exists()) { file.mkdirs(); } - // 获取assets目录下的所有文件及目录名 String[] fileNames = assetManager.list(assetsPath); - if (fileNames.length > 0) { //如果是目录 apk + if (fileNames.length > 0) { for (String fileName : fileNames) { if (!TextUtils.isEmpty(assetsPath)) { - temp = assetsPath + SEPARATOR + fileName; //补全assets资源路径 + temp = assetsPath + SEPARATOR + fileName; } String[] childFileNames = assetManager.list(temp); - if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) { //判断是文件还是文件夹:如果是文件夹 + if (!TextUtils.isEmpty(temp) && childFileNames.length > 0) { copyFilesFromAssets(context, temp, storagePath + SEPARATOR + fileName); - } else { //如果是文件 + } else { InputStream inputStream = assetManager.open(temp); readInputStream(storagePath + SEPARATOR + fileName, inputStream); } } - } else { //如果是文件 doc_test.txt或者apk/app_test.apk + } else { // doc_test.txt or apk/app_test.apk InputStream inputStream = assetManager.open(assetsPath); if (assetsPath.contains(SEPARATOR)) { //apk/app_test.apk assetsPath = assetsPath.substring(assetsPath.lastIndexOf(SEPARATOR), assetsPath.length()); @@ -87,27 +86,22 @@ public static void copyFilesFromAssets(Context context, String assetsPath, Strin } /** - * 读取输入流中的数据写入输出流 + * read InputStream * - * @param storagePath 目标文件路径 - * @param inputStream 输入流 + * @param storagePath storagePath + * @param inputStream inputStream */ public static void readInputStream(String storagePath, InputStream inputStream) { File file = new File(storagePath); try { if (!file.exists()) { - // 1.建立通道对象 FileOutputStream fos = new FileOutputStream(file); - // 2.定义存储空间 byte[] buffer = new byte[inputStream.available()]; - // 3.开始读文件 int lenght = 0; - while ((lenght = inputStream.read(buffer)) != -1) { // 循环从输入流读取buffer字节 - // 将Buffer中的数据写到outputStream对象中 + while ((lenght = inputStream.read(buffer)) != -1) { fos.write(buffer, 0, lenght); } - fos.flush(); // 刷新缓冲区 - // 4.关闭流 + fos.flush(); fos.close(); inputStream.close(); } @@ -151,11 +145,4 @@ public static String getAssetsString(@NotNull Context context, @NotNull String p } return sb.toString(); } -} - - - - - - - +} \ No newline at end of file diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/YUVUtils.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/YUVUtils.java index 131fc9656..cae6a13c1 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/YUVUtils.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/YUVUtils.java @@ -257,7 +257,7 @@ public static byte[] toWrappedI420(ByteBuffer bufferY, } /** - * I420转nv21 + * Convert I420 to NV21 * * @param data the data * @param width the width diff --git a/Android/APIExample/app/src/main/res/layout/dialog_spatial_sound.xml b/Android/APIExample/app/src/main/res/layout/dialog_spatial_sound.xml index 64d25b28a..036addae0 100644 --- a/Android/APIExample/app/src/main/res/layout/dialog_spatial_sound.xml +++ b/Android/APIExample/app/src/main/res/layout/dialog_spatial_sound.xml @@ -16,7 +16,7 @@ android:layout_gravity="end" android:paddingHorizontal="16dp" android:paddingVertical="8dp" - android:text="静音"/> + android:text="@string/audio_mute"/> + android:text="@string/voice_blur"/> + android:text="@string/airborne_simulation"/> + android:text="@string/attenuation"/> - - - - - - + android:text="@string/the_example_feature_tips"/> + android:text="@string/enable_transcoding"/> - + - - + - - - - - - - - - - - 外部EglContext设置 频道号为空 目标频道号为空 + 是否转码 + 此示例演示了如何使用SDK进行语音通话的功能。 + 静音 + 声音模糊 + 空气传播模拟 + 衰减系数 \ No newline at end of file diff --git a/Android/APIExample/app/src/main/res/values/strings.xml b/Android/APIExample/app/src/main/res/values/strings.xml index ac0f01057..145921c74 100644 --- a/Android/APIExample/app/src/main/res/values/strings.xml +++ b/Android/APIExample/app/src/main/res/values/strings.xml @@ -419,4 +419,10 @@ External EglContext Settings Channel is empty Destination Channel is empty + Transcoding + This example demonstrates how to use the SDK to implement voice call functionality. + Audio mute + Voice Blur + Airborne Simulation + Attenuation