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" /> + +