diff --git a/.gitignore b/.gitignore
index a8b0d1d..fd3f0a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,6 @@ google-services.json
# Android Profiling
*.hprof
+#sdk files
+SellyCloudSDK/
+
diff --git a/example/build.gradle b/example/build.gradle
index 9cea37c..a16a48c 100644
--- a/example/build.gradle
+++ b/example/build.gradle
@@ -3,10 +3,10 @@ plugins {
id 'org.jetbrains.kotlin.android'
}
-def usePublishedSdk = (findProperty("usePublishedSdk")?.toString()?.toBoolean() ?: false)
def sdkGroupId = rootProject.findProperty("sellySdkGroupId") ?: "com.sellycloud"
def sdkArtifactId = rootProject.findProperty("sellySdkArtifactId") ?: "sellycloudsdk"
def sdkVersion = rootProject.findProperty("sellySdkVersion") ?: "1.0.0"
+def hasLocalSdk = rootProject.file("SellyCloudSDK").exists()
android {
namespace 'com.demo.SellyCloudSDK'
@@ -63,13 +63,30 @@ android {
}
dependencies {
-// SellyCloudSDK 需要的依赖(需要手动添加)
- implementation 'com.google.code.gson:gson:2.10.1'
- implementation 'com.github.pedroSG94.RootEncoder:library:2.6.6'
- implementation "com.squareup.okhttp3:okhttp:4.12.0"
- implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
-
+ if (hasLocalSdk) {
+ implementation project(':SellyCloudSDK')
+ } else {
+ implementation files(
+ "libs/${sdkArtifactId}-${sdkVersion}.aar",
+ "libs/ijkplayer-cmake-release.aar",
+ "libs/Kiwi.aar",
+ "libs/libwebrtc.aar"
+ )
+ implementation 'com.google.code.gson:gson:2.10.1'
+ implementation 'com.github.pedroSG94.RootEncoder:library:2.6.6'
+ implementation "com.squareup.okhttp3:okhttp:4.12.0"
+ }
+ implementation fileTree(
+ dir: "libs",
+ include: ["*.jar", "*.aar"],
+ exclude: [
+ "${sdkArtifactId}-${sdkVersion}.aar",
+ "ijkplayer-cmake-release.aar",
+ "Kiwi.aar",
+ "libwebrtc.aar"
+ ]
+ )
implementation 'androidx.appcompat:appcompat:1.7.0-alpha03'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0-alpha13'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
@@ -81,6 +98,4 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.4'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
-
-
}
diff --git a/example/libs/fu_core_all_feature_release.aar b/example/libs/fu_core_all_feature_release.aar
index 0262d7e..de4ee01 100644
Binary files a/example/libs/fu_core_all_feature_release.aar and b/example/libs/fu_core_all_feature_release.aar differ
diff --git a/example/libs/ijkplayer-cmake-release.aar b/example/libs/ijkplayer-cmake-release.aar
new file mode 100644
index 0000000..33797f6
Binary files /dev/null and b/example/libs/ijkplayer-cmake-release.aar differ
diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml
index 231e78a..0b53929 100644
--- a/example/src/main/AndroidManifest.xml
+++ b/example/src/main/AndroidManifest.xml
@@ -11,6 +11,7 @@
+
@@ -55,7 +56,7 @@
+ android:foregroundServiceType="camera|microphone|mediaProjection" />
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/beauty/authpack.kt b/example/src/main/java/com/demo/SellyCloudSDK/beauty/authpack.kt
index e4119cc..ac86162 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/beauty/authpack.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/beauty/authpack.kt
@@ -4,5 +4,5 @@ package com.demo.SellyCloudSDK.beauty
* 请将相芯提供的证书密钥填充到此处的 AUTH_ARRAYS 字节数组中
*/
object authpack {
- val A: ByteArray = byteArrayOf(79, 120, -34, -73, -66, -116, 90, 16, -26, -94, -75, 3, 119, 83, 41, -46, -50, 46, 81, 72, 78, 80, -7, 110, -61, -31, 55, -90, -123, 96, -57, -79, 38, -45, -63, -8, 51, 103, 112, -83, -44, -16, -36, 101, 49, -82, 43, -33, -21, 4, -28, 10, -91, -23, -67, -27, -19, 75, 66, -44, -128, -41, -66, 65, 81, -118, -85, -69, 56, -80, 6, 8, 87, -114, -27, 96, 28, -39, -68, -10, -92, -67, 118, -119, 18, -87, 116, -94, -9, -42, -19, -30, -12, 86, 56, -90, -21, 69, 67, 61, 26, 101, -45, 77, 51, 111, 17, -10, 33, 57, -28, 80, 56, 31, -97, -106, -6, 71, 95, -119, -90, -15, 43, 10, 104, 45, 98, -91, -13, -14, -24, 3, 43, -18, -45, -5, -74, 47, -119, -6, -39, 60, 87, 0, -126, -99, -92, 122, 43, 94, 107, -34, 8, 29, -83, 91, -76, 31, 14, -113, -69, -125, 110, -69, -87, -60, 87, 112, 125, 99, -120, -18, 107, 101, 93, 99, -30, -51, -8, -72, -42, 106, 99, -30, -9, -94, -120, -41, 0, -17, -66, 93, -103, 79, -77, -62, 97, 95, -86, -113, 4, -11, 10, -67, 91, 1, -84, 76, -56, 127, 41, 7, -78, 79, 71, 28, 100, 123, -37, -47, -107, -92, -126, -39, 69, -83, -38, 104, -58, -36, 63, -101, 2, 82, -63, 63, -50, 104, -48, 46, -84, 124, 63, -73, 21, -2, 101, 73, -116, -90, -63, -104, 75, -75, -76, -85, -24, -69, 31, -107, -51, -42, 9, -112, -12, 74, 2, -17, -62, -58, 107, 96, 21, 70, -103, 69, -101, 99, -97, 59, 53, 111, -64, -25, 112, -69, 122, 84, -89, -63, -116, 35, 111, 2, 121, -67, 5, 106, 34, -50, 79, 116, 17, 83, 79, 22, -126, 5, -26, 84, -68, -35, 53, 0, -87, -6, 75, -57, -29, 92, 98, 13, 32, -21, 20, 93, -107, 109, -21, -110, -78, -121, -26, -65, -88, 76, 100, -82, -32, -96, 95, 77, -88, -59, -47, 78, -47, -124, -24, 127, 39, -115, 78, -101, -109, 97, 120, -113, 95, -59, -91, 88, -67, 80, -63, -67, 35, -79, -77, 58, 118, -27, -13, 67, -125, 107, 9, -54, 107, -18, 5, 93, -7, 67, 117, -79, 80, 82, -61, -96, 39, -128, -64, -86, -22, -34, -19, 103, -8, -32, 56, 110, -83, 113, -26, 69, -122, -22, 55, -74, 124, 25, -83, -28, -11, 66, -17, 3, 94, 105, -83, 57, 23, 37, 109, 13, -39, 26, -127, -85, 9, -43, 17, -35, -36, 113, 72, -126, -108, 49, 2, 123, 9, 51, -42, 89, 84, -1, -46, -83, -59, 111, 21, 125, 11, 94, 54, -120, -20, -52, 90, -16, 55, -107, -77, -59, 76, 82, -45, 117, 113, -43, 71, 58, 11, 96, 94, 123, 11, 65, -67, -8, -114, -95, 104, -13, 8, 46, 15, -84, -118, -63, -14, 58, 75, 64, 2, 90, -35, 31, -110, 0, -78, 93, -83, 73, 55, 24, -46, 105, 70, 98, 110, 22, -17, -52, 120, 7, -103, -83, -78, -51, -60, -114, 55, -1, -59, 3, 92, -85, 4, 42, -105, 101, -117, 38, 23, -60, -119, 88, -111, -33, -66, -48, -59, -64, -51, 9, -35, -79, -12, 32, -123, 75, -107, 42, -88, -68, 82, -6, -88, -21, 122, 26, -108, 19, -1, 119, -5, -120, 95, 112, 88, 51, 112, -49, -94, 63, 51, -38, 15, -68, -25, 81, -69, -15, -87, -16, -84, 36, 107, -88, 43, -105, 78, -3, -11, -128, -37, -112, 7, -59, 25, 110, 32, -11, -79, -58, -34, -53, 12, -9, -32, -14, -7, -113, -37, 90, 126, 78, -112, -51, 52, 4, 95, -4, -45, 116, -62, -15, -37, -125, 62, 20, -90, 104, 72, -96, -61, -127, 6, 92, -77, 100, -32, -15, -76, -85, 92, -128, -107, 100, 71, 90, -96, 108, -121, -38, 110, 95, 99, 24, -70, 112, -84, 12, -35, 84, 46, 63, -66, -35, 12, 29, -6, -4, 11, -52, -119, -70, 12, -109, 103, 4, -128, -103, 70, 116, 17, 126, -113, -121, -66, 64, -3, 11, 59, -84, 74, 40, 11, -48, 43, -30, -27, -36, -16, 121, -54, 126, -12, -113, -10, 70, 96, 80, -108, 39, 85, -80, -51, 32, 85, -14, -117, -54, 115, -94, 68, -46, -120, 27, 48, 43, -15, 31, -72, 96, -68, -70, 109, -43, -37, 61, 71, -88, 88, 44, -113, -58, 86, 6, -73, -86, 20, -94, 39, 101, 113, -128, -105, 26, -124, -101, -124, 67, -106, -98, 6, 54, -91, -51, -28, 80, 107, -106, 86, 108, 44, 127, -9, -51, 112, -56, 47, 3, 95, -50, -60, -50, -116, 70, -34, 59, 97, -30, -77, -94, 118, -27, -104, 70, 84, 36, 72, 69, 22, -97, -88, -102, 74, -10, -29, 48, 57, 50, 126, 117, 34, -48, 78, -12, 17, 52, -82, -36, -22, 113, -90, -75, 26, 56, 25, 88, 54, -37, 95, -77, 52, -38, 21, -32, 43, 2, 58, -48, 118, 118, -108, 101, 64, 30, -1, -74, -44, 76, -45, 92, -64, -46, 84, -22, -110, 20, 31, -44, -128, -47, -35, 2, -119, -7, 50, 49, 108, -107, 107, -65, 12, 83, 65, -106, 16, 29, 77, -100, 49, 122, 49, -112, 111, 29, -38, 79, 63, -69, -41, 54, 26, -38, -120, 60, 43, 88, 80, -1, 72, 13, 79, -31, -47, 20, -115, -124, -73, -56, 123, 28, -28, -72, -101, 70, 91, 40, -43, -42, -75, -47, 17, -106, -86, -90, -9, -38, -114, 87, 84, 12, 96, -83, -97, 99, 83, 22, 118, -66, 108, -126, 60, -101, 90, 102, 105, 127, 71, 127, 81, 23, -102, -114, -43, 32, -108, -64, -66, -5, 57, -67, 17, 73, 51, -64, 28, 17, -19, -7, 118, 6, -5, -67, -74, -54, -113, -111, 118, 19, 87, -30, 92, -24, 105, -126, 22, 117, 21, 103, -35, -54, 65, 119, 116, -24, 101, -128, -91, 111, 62, -63, 61, 77, -110, 8, -114, 4, -40, 10, 79, 100, 34, -127, 38, -33, 96, 71, -101, 108, 70, -112, 99, 112, -61, -63, 40, -93, -21, -104, -118, 68, 77, -87, -105, -66, -37, -82, -115, 108, 4, 58, -112, -91, 35, -57, 1, -115, 97, 16, -104, -55, -14, 69, 87, -20, 41, -113, -92, 10, 87, -91, 103, 45, 81, 118, 70, 104, 108, -44, -45, 55, 0, -111, 107, 80, 46, -80, 127, -114, -19, -6, 109, 31, -112, 69, 57, 122, -108, 33, 64, 117, 115, 5, -108, -35, 70, -65, 106, -8, -64, 11, 110, 111, 74, 82, 112, 112, 59, -57, -70, -67, -107, -57, -46, 5, 24, 63, -90, -47, -22, 70, -107, 90, 17, 13, -68, 85, -23, -41, -26, -125, -83, 49, -5, -74, 111, 55, 120, 15, -15, -105, -99, -64, -72, -4, -51, 114, 80, 107, 63, 22, -53, -109, -76, -32, 25, 99, -61, -47, -41, 76, 57, -42, 104, -67, -111, 114, -109, -99, -71, -42, 10, 61, 103, 116, 64, -37, 51, -68, -31, -48, 89, -99, 11, -6, 42, 125, -123, 81, 115, -124, 90, 81, -117, -32, -88, -30, -86, -51, -49, 60, 57, -75, -25, 105, -2, -39, -49, -79, -53, -28, -23, -105, 5, 12, 71, 58, 17, 114, 70, -12, -128, 119, 101, 105, -32, -122, 56, -25, 19, 10, 15, -73, 12, 65, 22, 1, -44, 41, 67, 122, -69, -23, 80, 79, 90, -100, -93, -77, 125, 102, -102, 99, -82, -93, 92, -4, 57, -100, -84, 121, 118, 72, -124, -23, 110, 56, 75, 8, -63, 70, 78, -5, -32, -11, 110, -43, -112, -102, 115, 17, 103, -117, -48, -88, 23, -57, 89, -47, -15, -14, 76, -68, -76, -80, -21, -39, 58, 32, 71, -23, 11, 24, -51, -10, -88, -1, 97, -7, 43, 126, -45, -91, -48, 48, -53, 38, -95, -1, 69, -22, -17, 76, 58, 108, 39, 11, 127, 43, -75, 126, -24, -72, -9, -28, -31, -64, 93, -74, -96, 57, -42, 4, 37, -89, -109, 58, -92, -18, 59, -77, -82, -66, 69, -79, -120, 96, 45, 73, -32, 110, 53, 115, -69, 27, -47, -21, -50, -45, -65, -45, 95, 117, 121, -18, -2, 54, 75, -72, -89, -81, 87, -67, -66, 80, -100, 48, -29, -52, 56, -100, 21, -102, -122, -9, 60, 83, -40, 127, -76, -122, 7, 6, 6, -38, 119, -102, -27, -65, -76, -3, -63, -90, 123, 6, 20, 125, 69, -25)
+ val A: ByteArray = byteArrayOf(72, 127, 51, -98, -26, -60, -5, -10, 52, -88, 8, -55, -7, 75, 97, -32, -33, -3, 58, 4, -15, -104, 10, -86, 24, -107, -127, 41, -90, 81, 31, 32, 15, -18, 84, 113, -113, 46, 17, 98, 18, 33, 45, -32, -124, -108, 109, -95, -109, -2, -122, 38, -3, 76, -111, 99, -110, 76, -4, -122, 23, -30, -73, -104, -24, 0, -122, 102, -83, 92, 111, -11, 42, 90, 37, -97, 24, 11, 73, -30, 107, -58, -103, -2, -37, -56, 31, 125, 40, 57, -13, -118, 19, 25, -52, -16, 45, 68, -3, 67, 115, 100, -28, -100, 76, -53, -35, -43, -36, 28, 38, 47, -111, 118, 27, 10, -103, -44, -53, -1, 70, -58, 110, -119, 16, -10, -77, 62, 31, 56, -26, 113, 111, 122, 124, 125, 34, -120, -100, -66, -8, -125, 44, 104, 55, -49, -42, -128, 86, 2, 26, -109, -4, 7, -69, 109, -73, 58, -2, 97, -52, -82, -114, -99, -27, -37, -50, -79, 125, -125, -83, -61, 4, 75, -26, -89, -58, -52, 86, 71, -28, 55, 1, -24, 0, 125, -99, -115, 50, -14, 123, 75, 97, -77, 24, 73, -123, 122, 35, 33, 58, -9, -23, -47, -126, -8, -72, 124, -105, 75, -88, 69, -82, 54, 4, -43, 73, 78, 47, 40, -52, 37, 119, 32, 33, -36, -125, 111, -99, 11, -121, -49, 19, -115, 42, 113, -94, -65, -120, -79, 75, -62, -68, 4, 4, -53, 106, -4, 96, -84, 10, 108, 16, -11, 87, 43, 5, -17, 69, -64, 47, -15, 97, -119, 1, -47, 113, -12, 13, -25, 22, 27, -2, 23, -103, -123, 125, 38, -46, -103, 62, 101, -85, -87, -105, 0, 82, -89, 0, -8, -105, -114, -82, -83, -83, 117, -38, -116, 89, 104, -48, 37, 47, -86, 116, -64, -72, -14, -1, -75, 0, 92, -87, -26, -113, 9, 117, -85, 15, -99, 61, -27, -89, -31, -29, 72, -60, 61, 116, 92, -113, -111, 99, 90, -124, 71, 78, 109, 115, 52, -92, -117, 32, -102, -115, 46, -93, -17, -122, 83, -6, -56, 101, 88, 50, 85, -64, 2, 74, 63, -35, -94, -120, -90, 2, 115, -86, -104, 127, -12, -123, -117, -106, -4, 78, -106, 37, 56, 125, 82, 43, -114, -88, 1, 31, -49, -115, 96, 88, 121, 10, -105, -17, -19, 78, 102, 36, 32, 113, 67, 47, -127, 105, -116, -58, 93, 108, -52, -81, 94, -2, 96, -104, 104, -18, -8, 110, 65, 76, 22, -87, 76, 59, -56, 102, -49, 29, -102, 43, -29, 27, 100, 34, 23, -96, -68, 81, -107, 96, -106, -86, -90, -104, 28, 83, -51, 66, 99, 59, -12, 22, -36, -30, 66, 44, -73, -43, 68, -81, -104, 16, 48, -126, 8, 6, -47, -62, 107, 103, -88, -93, 63, 125, 55, 88, -100, -111, -28, 109, 42, 33, 107, -116, -97, -80, -37, 84, 30, 76, 65, 20, 42, 6, 111, 49, 70, -66, 102, -36, -25, 106, 117, -60, 23, 90, 59, 48, -40, 56, 35, -3, -82, 29, -113, -64, 127, 58, 126, 12, 60, -20, 21, 5, 13, -103, -109, 97, -54, -61, 30, -7, 114, -124, -36, -80, -120, 81, -15, -45, 30, 23, 33, 106, 124, -118, 109, -115, 65, 44, -117, 38, -125, 40, 115, -85, -119, 116, -20, 20, -63, 127, 79, -96, 111, 18, -104, -104, -77, -56, -107, 121, 122, 127, -62, 82, -37, -87, 71, -83, 118, -11, 22, -9, -107, 31, -77, -13, 39, -6, 36, -91, 30, -40, -64, -37, 59, 56, 117, -112, 92, -29, 48, -43, -1, -5, -24, 3, 97, 62, 85, -19, 29, 116, 107, 123, 103, -82, -16, -90, 5, -61, 27, -63, -55, 102, 45, 17, 47, 116, 30, 94, 14, -123, 116, -67, -94, 16, 4, 109, -67, 65, -45, -93, -72, 73, 78, 77, -45, -53, 121, 40, -43, -60, 74, 77, -53, 15, 6, 31, 34, 22, 11, -41, 26, 20, 100, -7, -106, 11, -49, 74, -73, 48, -121, 67, -51, -72, 84, -104, 103, -84, -84, 83, 101, -123, -79, 65, -111, 105, -49, 42, -96, -87, -78, 2, 9, -18, 83, 17, 34, -30, 11, 5, -85, -92, 81, 126, 81, -80, -12, 30, 27, -126, -107, 31, -62, 39, 59, 88, -94, 55, 31, -7, -45, 123, 96, 16, -117, -9, 48, -62, 14, -10, 84, -66, -123, -4, 86, 64, 27, -20, 71, 82, -20, 28, 85, 19, -80, 120, 9, 23, -119, 21, 98, -14, -62, -68, 43, 69, -39, 110, -86, 113, 122, 116, 2, -109, -3, -100, 46, 44, -112, -102, 100, -62, 4, 84, 122, -128, 29, 91, -127, 113, -65, -123, 45, 33, 100, -59, 74, 123, 25, -9, 59, 54, 31, 94, 86, 118, 120, -32, 28, -28, 91, 81, 89, -69, 64, -117, 77, -37, 110, -37, -90, -80, -91, 14, 17, 86, 77, -119, 74, 45, -117, -26, -98, -28, -73, 24, 72, 57, 113, 36, 61, 27, 74, 72, 112, 59, -61, -56, -48, 8, -32, -29, -74, -80, 106, -106, 102, -128, 72, 41, -115, 9, -51, -84, -41, -97, -98, 86, 5, -127, 13, -61, 17, -68, 33, 23, 122, -118, -125, -61, 117, -73, -107, 90, -36, -33, 109, -8, -63, 15, 101, -30, 5, -67, 1, 8, -99, -26, -102, -67, -56, -101, 64, 116, 48, -112, -21, -15, 78, -27, 82, 10, 72, 46, 30, 70, -83, 89, -27, -117, 122, 80, -28, -84, 84, 84, -108, -29, 116, 3, -114, -1, -115, -57, 36, -111, 44, -70, -60, 56, 61, -98, -54, -95, -127, -59, 96, 49, -92, 119, -50, -80, -23, 39, 9, 107, 79, -110, -115, -123, -93, 68, -72, -90, -26, -102, 6, 51, -38, 19, 123, -28, -61, -122, -12, -95, 111, 114, 72, -55, 115, -88, -32, 12, -99, -36, -112, 90, -28, 122, 47, 119, -86, 10, 18, -89, -8, -52, 86, -30, -128, 109, 74, 45, 37, -72, -26, 43, 2, -88, 49, -4, 124, 13, -87, 100, 28, 123, 31, -36, -122, 57, -75, -31)
}
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveForegroundService.kt b/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveForegroundService.kt
index a043b7c..e32cf3a 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveForegroundService.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveForegroundService.kt
@@ -9,6 +9,7 @@ import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
+import androidx.core.app.ServiceCompat
import com.demo.SellyCloudSDK.R
/**
@@ -18,7 +19,27 @@ import com.demo.SellyCloudSDK.R
class InteractiveForegroundService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- startForeground(NOTIFICATION_ID, buildNotification())
+ val includeMediaProjection = intent?.getBooleanExtra(EXTRA_MEDIA_PROJECTION, false) == true
+ val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ val base = android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA or
+ android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
+ if (includeMediaProjection) {
+ base or android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
+ } else {
+ base
+ }
+ } else 0
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ ServiceCompat.startForeground(
+ this,
+ NOTIFICATION_ID,
+ buildNotification(),
+ serviceType
+ )
+ } else {
+ startForeground(NOTIFICATION_ID, buildNotification())
+ }
return START_STICKY
}
@@ -61,9 +82,11 @@ class InteractiveForegroundService : Service() {
companion object {
private const val CHANNEL_ID = "interactive_call_foreground"
private const val NOTIFICATION_ID = 0x101
+ private const val EXTRA_MEDIA_PROJECTION = "extra_media_projection"
- fun start(context: Context) {
+ fun start(context: Context, includeMediaProjection: Boolean = false) {
val intent = Intent(context, InteractiveForegroundService::class.java)
+ intent.putExtra(EXTRA_MEDIA_PROJECTION, includeMediaProjection)
ContextCompat.startForegroundService(context, intent)
}
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveLiveActivity.kt b/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveLiveActivity.kt
index e2a3ffa..2064a73 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveLiveActivity.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveLiveActivity.kt
@@ -1,11 +1,14 @@
package com.demo.SellyCloudSDK.interactive
import android.Manifest
+import android.app.Activity
import android.content.Context
+import android.content.Intent
import android.content.pm.PackageManager
+import android.media.projection.MediaProjectionManager
import android.os.Bundle
-import android.view.inputmethod.InputMethodManager
import android.util.Log
+import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
@@ -63,6 +66,7 @@ class InteractiveLiveActivity : AppCompatActivity() {
private var pendingJoinRequest: JoinRequest? = null
private var currentCallId: String? = null
@Volatile private var selfUserId: String? = null
+ private var isScreenSharing: Boolean = false
private val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
@@ -78,6 +82,17 @@ class InteractiveLiveActivity : AppCompatActivity() {
if (!granted) setJoinButtonEnabled(true)
}
+ private val screenShareLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ startScreenShareInternal(result.resultCode, result.data!!)
+ } else {
+ Toast.makeText(this, "已取消屏幕共享授权", Toast.LENGTH_SHORT).show()
+ updateControlButtons()
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityInteractiveLiveBinding.inflate(layoutInflater)
@@ -151,7 +166,7 @@ class InteractiveLiveActivity : AppCompatActivity() {
setEventHandler(rtcEventHandler)
setClientRole(InteractiveRtcEngine.ClientRole.BROADCASTER)
// setVideoEncoderConfiguration(InteractiveVideoEncoderConfig()) 使用默认值
- setVideoEncoderConfiguration(InteractiveVideoEncoderConfig(640, 480 , fps = 20, minBitrateKbps = 150, maxBitrateKbps = 350))
+ setVideoEncoderConfiguration(InteractiveVideoEncoderConfig(640, 480 , fps = 20, minBitrateKbps = 150, maxBitrateKbps = 850))
setDefaultAudioRoutetoSpeakerphone(true)
setCaptureVideoFrameInterceptor { frame ->
if (!beautyEnabled) return@setCaptureVideoFrameInterceptor frame
@@ -277,6 +292,10 @@ class InteractiveLiveActivity : AppCompatActivity() {
val tip = "onStreamStateChanged[$peerId] state=$state code=$code ${message ?: ""}"
Log.d(TAG, tip)
Toast.makeText(this@InteractiveLiveActivity, tip, Toast.LENGTH_SHORT).show()
+ if (peerId == currentUserId && message?.contains("screen_share_stopped") == true) {
+ isScreenSharing = false
+ updateControlButtons()
+ }
}
}
}
@@ -360,6 +379,24 @@ class InteractiveLiveActivity : AppCompatActivity() {
}
}
}
+ binding.btnScreenShare.setOnClickListener {
+ if (currentCallId == null) {
+ Toast.makeText(this, "请先加入频道", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ if (isScreenSharing) {
+ stopScreenShareInternal(true)
+ } else {
+ // Android 14+ 屏幕捕获需要先开启包含 mediaProjection 类型的前台服务
+ InteractiveForegroundService.start(this, includeMediaProjection = true)
+ val mgr = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as? MediaProjectionManager
+ if (mgr == null) {
+ Toast.makeText(this, "当前设备不支持屏幕捕获", Toast.LENGTH_SHORT).show()
+ } else {
+ screenShareLauncher.launch(mgr.createScreenCaptureIntent())
+ }
+ }
+ }
updateControlButtons()
}
@@ -390,6 +427,14 @@ class InteractiveLiveActivity : AppCompatActivity() {
} else {
getString(R.string.ctrl_camera_on)
}
+
+ binding.btnScreenShare.text = if (isScreenSharing) {
+ getString(R.string.stop_screen_share)
+ } else {
+ getString(R.string.start_screen_share)
+ }
+ binding.btnSwitchCamera.isEnabled = !isScreenSharing
+ binding.btnToggleBeauty.isEnabled = !isScreenSharing
}
private fun applyLocalPreviewVisibility() {
@@ -402,6 +447,36 @@ class InteractiveLiveActivity : AppCompatActivity() {
updateLocalStatsLabel()
}
+ private fun startScreenShareInternal(resultCode: Int, data: Intent) {
+ // Android 14+ 需开启包含 mediaProjection 类型的前台服务
+ InteractiveForegroundService.start(this, includeMediaProjection = true)
+ val started = rtcEngine?.startScreenShare(
+ resultCode,
+ data,
+ width = 720,
+ height = 1280,
+ fps = 15
+ ) == true
+ if (started) {
+ isScreenSharing = true
+ } else {
+ Toast.makeText(this, "屏幕共享启动失败", Toast.LENGTH_LONG).show()
+ }
+ updateControlButtons()
+ }
+
+ private fun stopScreenShareInternal(showToast: Boolean = false) {
+ val stopped = rtcEngine?.stopScreenShare() == true
+ if (stopped) {
+ isScreenSharing = false
+ ensureBeautySessionReady()
+ fuFrameInterceptor?.setEnabled(beautyEnabled)
+ } else if (showToast) {
+ Toast.makeText(this, "停止屏幕共享失败", Toast.LENGTH_SHORT).show()
+ }
+ updateControlButtons()
+ }
+
private fun attemptJoin() {
hideKeyboard()
val callId = binding.etCallId.text.toString().trim()
@@ -643,6 +718,7 @@ class InteractiveLiveActivity : AppCompatActivity() {
callDurationSeconds = 0
lastMessage = null
binding.tvMessageLog.text = getString(R.string.message_none)
+ isScreenSharing = false
updateControlButtons()
updateLocalStatsLabel()
updateCallInfo()
diff --git a/example/src/main/res/layout/activity_interactive_live.xml b/example/src/main/res/layout/activity_interactive_live.xml
index 8088f9e..9444295 100644
--- a/example/src/main/res/layout/activity_interactive_live.xml
+++ b/example/src/main/res/layout/activity_interactive_live.xml
@@ -222,6 +222,13 @@
android:layout_weight="1"
android:text="@string/ctrl_mic_off" />
+
+
开启麦克风
关闭摄像头
开启摄像头
+ 开始屏幕共享
+ 停止屏幕共享
发送频道广播消息
发送
美颜开启
diff --git a/settings.gradle b/settings.gradle
index e454d65..ccba548 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,6 +5,10 @@ pluginManagement {
gradlePluginPortal()
}
}
+
+def sdkDir = file('SellyCloudSDK')
+def hasLocalSdk = sdkDir.exists()
+
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
@@ -12,11 +16,19 @@ dependencyResolutionManagement {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
- // Local AARs for SellyCloudSDK
- flatDir { dirs file('SellyCloudSDK/libs') }
+ // Local AARs for the demo or the SDK when present
+ flatDir {
+ dirs file('example/libs')
+ if (hasLocalSdk) {
+ dirs sdkDir.toPath().resolve('libs').toFile()
+ }
+ }
}
}
rootProject.name = "SellyCLoudSDKExample"
include ':example'
-include ':SellyCloudSDK'
+// Use the SDK module only when it exists locally; otherwise rely on the published/prebuilt AAR.
+if (hasLocalSdk) {
+ include ':SellyCloudSDK'
+}