樱花动漫第三方安卓Android客户端,免费开源,目的是学习Android开发。(仅支持Android 5及以上版本)
++ (Android 5用户请尽快升级到6及以上,后续可能会将最低支持版本提高为Android 6) +
- ---- +## Discord频道:https://discord.gg/MyaRtRGEzr + +### 可以选择将自制数据源共享到[DataSourceRepository](https://github.com/SkyD666/DataSourceRepository)仓库,自制数据源/后端[帮助文档](doc/customdatasource/RV_ITEM.md) ## [>>必看安全说明<<](#安全说明) @@ -36,15 +44,18 @@ 3. 支持**分类查看**动漫 4. 支持**双指缩放**、**移动**、**旋转**视频 5. 支持视频**投屏**到电视 +5. 支持**WebDAV**备份恢复数据 6. 支持部分视频**显示**、**发送弹幕**(需要数据源支持弹幕) -7. 支持**缓存视频**到本地(暂不支持m3u8格式资源缓存) -8. 支持**追番**(数据保存在本地) -9. 支持显示**观看历史**记录 -10. 支持显示**搜索历史**记录 -11. 支持改变视频**播放速度** -12. 支持改变**视频**显示**比例**(16:9, 4:3, 全屏等) -13. [支持**自定义**显示**数据源**](doc/customdatasource/README.md) -14. ...... +7. 支持输入某站弹幕链接播放网络弹幕(例如https://api.bilibili.com/x/v1/dm/list.so?oid=97495910) +8. 支持**缓存视频**到本地 +9. 支持**追番**(数据保存在本地) +10. 支持显示**观看历史**记录 +11. 支持显示**搜索历史**记录 +12. 支持改变视频**播放速度** +13. 支持改变**视频**显示**比例**(16:9, 4:3, 全屏等) +14. 支持**本地记忆**视频**播放进度** +15. 支持**播放本地音视频** +16. ...... ## 运行截图 @@ -58,11 +69,27 @@   - +
+
+## 主要技术栈
+
+- MVVM
+- ViewModel
+- Flow
+- Kotlin Coroutine
+- Hilt
+- Room
+- Jetpack Compose
+- SplashScreen
+- DiffUtil
+- Retrofit
+- OkHttp
+- Jsoup
+- ......
## 安全说明
-**请勿**私自**传播APK**安装包,Github仓库为唯一长期仓库,**请仅在Github仓库下载安装包**,请勿下载来历不明的应用与Jar包,谨防隐私泄露,谨防受骗!
+**请勿**私自**传播APK**安装包,GitHub仓库为唯一长期仓库,**请仅在GitHub仓库下载安装包**,请勿下载来历不明的应用与ads包,谨防隐私泄露,谨防受骗!
### 已发现未知来源的APK
@@ -88,13 +115,9 @@
1. 读取存储卡中的内容:缓存动漫功能需要读取本地存储卡中缓存的视频文件
2. 修改或删除存储卡中的内容:缓存动漫功能需要修改记录缓存信息的xml文件
-### 电话
-
-1. 读取设备通话状态和识别码:友盟+SDK需要收集您的设备Mac地址、唯一设备识别码以提供统计分析服务
-
### 位置信息
-1. 访问大致、确切位置:友盟+SDK会通过地理位置校准报表数据准确性,提供基础反作弊能力
+1. 访问大致、确切位置:Flurry SDK会通过地理位置校准报表数据准确性,提供基础反作弊能力
### 其它应用功能
@@ -103,7 +126,7 @@
## 附加说明
-默认数据源来自http://www.yhdm.io/
+App内不提供默认数据源,需要用户自行导入或从APP内的数据源商店下载使用。
## 免责声明
@@ -112,6 +135,10 @@
3. 此软件**仅可用作学习交流**,未经授权,**禁止用于其他用途**,请在下载**24小时内删除**。
4. 因使用此软件产生的版权问题,软件作者概不负责。
+## Star History
+
+[](https://star-history.com/)
+
## 许可证
使用此软件代码需**遵循以下许可证协议**
diff --git a/andresguard.gradle b/andresguard.gradle
deleted file mode 100644
index ab0e2b0e..00000000
--- a/andresguard.gradle
+++ /dev/null
@@ -1,46 +0,0 @@
-def andresguard = [:]
-
-def whiteList = [
- // skin
- "R.drawable.*_skin*",
- "R.color.*_skin*",
- // for your icon
- "R.mipmap.ic_launcher",
- "R.mipmap.ic_launcher_round",
- // for fabric
- "R.string.com.crashlytics.*",
- // for google-services
- "R.string.google_app_id",
- "R.string.gcm_defaultSenderId",
- "R.string.default_web_client_id",
- "R.string.ga_trackingId",
- "R.string.firebase_database_url",
- "R.string.google_api_key",
- "R.string.google_crash_reporting_api_key",
-
- // 友盟sdk
- "R.anim.umeng*",
- "R.string.umeng*",
- "R.string.UM*",
- "R.string.tb_*",
- "R.layout.umeng*",
- "R.layout.socialize_*",
- "R.layout.*messager*",
- "R.layout.tb_*",
- "R.color.umeng*",
- "R.color.tb_*",
- "R.style.*UM*",
- "R.style.umeng*",
- "R.drawable.umeng*",
- "R.drawable.tb_*",
- "R.drawable.sina*",
- "R.drawable.qq_*",
- "R.drawable.tb_*",
- "R.id.umeng*",
- "R.id.*messager*",
- "R.id.progress_bar_parent",
- "R.id.socialize_*",
- "R.id.webView"
-]
-andresguard.whiteList = whiteList
-ext.andresguard = andresguard
diff --git a/app/.gitignore b/app/.gitignore
index 52ffe7c1..b53043ca 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -1,2 +1,2 @@
/build
-/src/main/res/raw/notice.txt
+/src/main/res/raw/notice.html
diff --git a/app/build.gradle b/app/build.gradle
index 11aa080b..9c170445 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,20 +2,26 @@ plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
- id 'AndResGuard'
- id 'com.efs.sdk.plugin'
+ id 'dagger.hilt.android.plugin'
+ id 'com.google.devtools.ksp'
+// id 'com.flurry.android.symbols'
}
apply from: secret
-apply from: andresguard
+
+def buildTime = new Date().format("YYYY-MM-dd HH:mm:ss", TimeZone.getTimeZone("GMT+8:00"))
android.defaultConfig {
secret.buildConfigField.forEach({ k, v ->
buildConfigField("String", k, "\"${v}\"")
})
+ buildConfigField("String", "BUILD_TIME", "\"${buildTime}\"")
secret.shieldTextList.forEach({ k, v ->
buildConfigField("String[]", k, v)
})
+ secret.dataSource.forEach({ k, v ->
+ buildConfigField("String", k, "\"${v}\"")
+ })
}
android {
@@ -35,19 +41,21 @@ android {
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
- javaCompileOptions {
- annotationProcessorOptions {
- arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
- }
+ ksp {
+ arg("room.schemaLocation", "$projectDir/schemas".toString())
}
ndk {
- abiFilters 'armeabi'
+ abiFilters 'armeabi', 'arm64-v8a'
}
manifestPlaceholders = secret.manifestPlaceholders
resConfigs "xxxhdpi", "anydpi-v26"
+
+ vectorDrawables {
+ useSupportLibrary true
+ }
}
signingConfigs {
@@ -60,9 +68,7 @@ android {
}
productFlavors {
- Github {
- manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Github"]
- }
+ Github
}
applicationVariants.all { variant ->
@@ -75,21 +81,21 @@ android {
debug {
minifyEnabled false
zipAlignEnabled false
- shrinkResources false // 使用keep.xml,keep住皮肤文件
+ shrinkResources false // 使用keep.xml,keep住某些资源文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
applicationIdSuffix '.debug' // 一台手机debug release共存
ndk {
- abiFilters 'armeabi', 'x86', 'x86_64'
+ abiFilters 'armeabi', 'x86', 'x86_64', 'arm64-v8a'
}
}
release {
signingConfig signingConfigs.release //签名
minifyEnabled true
zipAlignEnabled true
- shrinkResources true // 使用keep.xml,keep住皮肤文件
+ shrinkResources true // 使用keep.xml,keep住某些资源文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
ndk {
- abiFilters 'armeabi'
+ abiFilters 'armeabi', 'arm64-v8a'
}
}
}
@@ -117,11 +123,23 @@ android {
exclude 'org/seamless/**'
exclude 'org/eclipse/jetty/**'
exclude 'org/fourthline/cling/**'
- exclude 'okhttp3/internal/**'
+ exclude 'okhttp3/internal/publicsuffix/NOTICE'
+ exclude 'com/badlogic/**'
+ exclude 'XPP3_1.1.3.2_VERSION'
+ exclude 'XPP3_1.1.3.3_VERSION'
+ exclude 'kotlin-tooling-metadata.json'
+ exclude 'build-data.properties'
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
}
buildFeatures {
viewBinding true
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion '1.2.0'
}
}
@@ -131,137 +149,122 @@ dependencies {
implementation deps.kotlin.core_ktx
implementation deps.support.appcompat
implementation deps.support.material
+ implementation deps.support.recyclerview
implementation deps.support.swiperefreshlayout
+ implementation deps.support.coordinatorlayout
implementation deps.support.constraintlayout
+ implementation deps.support.fragment_ktx
+ implementation deps.support.viewpager2
+ implementation deps.support.preference
+ implementation deps.support.security_crypto
+ implementation deps.support.core_splashscreen
+ implementation deps.support.profileinstaller
+ implementation deps.compose.ui
+ implementation deps.compose.constraintlayout_compose
+ implementation deps.compose.material3
+ implementation deps.compose.ui_viewbinding
+ implementation deps.compose.ui_tooling_preview
+ implementation deps.compose.runtime_livedata
+ implementation deps.compose.compose_theme_adapter
+ implementation deps.compose.material3_window_size_class
+ implementation deps.accompanist.systemuicontroller
+ implementation deps.accompanist.swiperefresh
implementation deps.jsoup.jsoup
- implementation deps.lifecycle.lifecycle_livedata_ktx
implementation deps.lifecycle.lifecycle_viewmodel_ktx
implementation deps.lifecycle.lifecycle_runtime_ktx
- implementation deps.support.viewpager2
+ implementation deps.lifecycle.lifecycle_extensions
+ implementation deps.hilt.hilt_android
+ implementation deps.hilt.hilt_navigation_compose
+ kapt deps.hilt.hilt_android_compiler
implementation deps.okhttp3.okhttp
- implementation deps.shuyu.GSYVideoPlayer
+ implementation deps.okhttp3.logging_interceptor
+ implementation deps.shuyu.gsyVideoPlayer_java
+ implementation deps.shuyu.gsyVideoPlayer_exo2
implementation deps.retrofit2.retrofit
implementation deps.retrofit2.converter_gson
implementation deps.getActivity.XXPermissions
implementation deps.kotlinx.kotlinx_coroutines_android
- implementation deps.material_dialogs.core
- implementation deps.material_dialogs.input
implementation deps.room.room_runtime
implementation deps.room.room_ktx
- kapt deps.room.room_compiler
- implementation deps.filedownloader.library
+ implementation deps.support.legacy_support_v4
+ ksp deps.room.room_compiler
+ implementation deps.aria.core
+ kapt deps.aria.compiler
+ implementation deps.aria.m3u8Component
implementation deps.cling.cling_core
implementation deps.cling.cling_support
implementation deps.jetty.jetty_server
implementation deps.jetty.jetty_servlet
implementation deps.jetty.jetty_client
implementation deps.nanohttpd.nanohttpd
- compileOnly files ('libs/cdi-api.jar') // DLNACastService编译需要javax.enterprise.inject.Alternative类
-// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
+ compileOnly files('libs/cdi-api.jar')
+ // DLNACastService编译需要javax.enterprise.inject.Alternative类
+// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
implementation deps.greenrobot.eventbus
- implementation deps.umsdk.common
- implementation deps.umsdk.asms
- implementation deps.umsdk.apm
- implementation deps.umsdk.push
+ implementation deps.flurry.analytics
implementation deps.smart.refresh_layout_kernel
implementation deps.smart.refresh_header_material
implementation deps.smart.refresh_footer_ball
- implementation deps.ctiao.DanmakuFlameMaster
implementation deps.coil_kt.coil
- implementation project(':skin')
- implementation project(':skin_blue')
- implementation project(':skin_dark')
- implementation project(':skin_lemon')
- implementation project(':skin_sweat_soybean')
-}
-
-// UM U-APM性能报告
-efs {
- //是否对启动过程进程插桩的开关,如果使用自动集成监控则必须开启
- isAutoTrack = true
- //您自定义Application的类名称,必填项,如没有自定义则填写系统Application
- applicationName = "App"
- //您自定义Activity的类名称,必填项,将您所有Activity的类名按如下格式填写
- activityList = [
- "AboutActivity",
- "AnimeDetailActivity",
- "AnimeDownloadActivity",
- "ClassifyActivity",
- "CrashActivity",
- "DlnaActivity",
- "DlnaControlActivity",
- "FavoriteActivity",
- "HistoryActivity",
- "LicenseActivity",
- "MainActivity",
- "MonthAnimeActivity",
- "PlayActivity",
- "RankActivity",
- "SearchActivity",
- "SettingActivity",
- "SimplePlayActivity",
- "DetailPlayerActivity",
- "WebViewActivity",
- "SkinActivity",
- "NoticeActivity"
- ]
+ implementation deps.coil_kt.coil_compose
+ implementation deps.kuaishou.akdanmaku
+ implementation deps.vadiole.colorpicker
+ implementation deps.commons.commons_text
+ implementation deps.okhttp3.okhttp_dnsoverhttps
+ implementation deps.thegrizzlylabs.sardine_android
}
-//AndResGuard资源混淆工具
-andResGuard {
- // 使用mappingFile,防止需要换肤的资源id被替换
- mappingFile = file("./resource_mapping.txt")
-// mappingFile = null
- use7zip = true
- useSign = true
- // 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字
- keepRoot = false
- // 设置这个值,会把arsc name列混淆成相同的名字,减少string常量池的大小
- fixedResName = "arg"
- // 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源
- mergeDuplicatedRes = true
- whiteList = andresguard.whiteList
- compressFilePattern = [
- "*.png",
- "*.jpg",
- "*.jpeg",
- "*.gif",
- "resources.arsc"
- ]
- sevenzip {
- artifact = 'com.tencent.mm:SevenZip:1.2.20'
- //path = "/usr/local/bin/7za"
- }
-
- /**
- * 可选: 如果不设置则会默认覆盖assemble输出的apk
- **/
- // finalApkBackupPath = "${project.rootDir}/final.apk"
-
- /**
- * 可选: 指定v1签名时生成jar文件的摘要算法
- * 默认值为“SHA-1”
- **/
- // digestalg = "SHA-256"
-}
+//flurryCrash {
+// apiKey secret.buildConfigField.FLURRY_API_KEY
+// useEnvVar false
+// token secret.buildConfigField.PROGRAMMATIC_TOKEN
+//}
-//class转jar
-//删除之前打出的包,默认将包打在'build/libs/'下
+/**
+ * 下面是生成数据源Jar的过程。保证生成了数据源的class文件后,再直接运行makeAds任务即可
+ */
+// 1.删除之前打出的包,默认将包打在'build/libs/'下
task deleteOldJar(type: Delete) {
delete 'build/libs/CustomDataSource.jar'
}
-//自定义数据源打包为普通的jar包操作
+
+// 2.使用d8将class打包为dex文件
+// 要保证已经将.../Android/Sdk/build-tools/xx.x.x加入环境变量
+task makeDex(type: Exec) {
+ project.file('build/dex/').mkdirs()
+ // 根据需求更改
+ commandLine 'cmd', "/c", "d8 --output build/dex/ build/tmp/kotlin-classes/GithubDebug/com/skyd/imomoe/model/impls/custom/*.class"
+}
+
+// 3.将dex和CustomInfo文件一起打入jar
task makeJar(type: Jar) {
//要打成的包的名字
baseName 'CustomDataSource'
//选取要打包的文件夹
- from('build\\tmp\\kotlin-classes\\GithubDebug\\com\\skyd\\imomoe\\model\\impls\\custom')
- //需要跟实际类的包名路径一样
- into('com/skyd/imomoe/model/impls/custom')
- //排除在外的文件
- exclude('BuildConfig.class', 'R.class', 'MainActivity.class', 'TestClass.class')
- //排除以R$开头的文件
- exclude { it.name.startsWith('R$') }
+ from(
+ 'build/dex/',
+ 'src/main/java/com/skyd/imomoe/model/impls/custom/CustomInfo'
+ )
+ // dex文件和CustomInfo文件都存放在根目录即可
+ into('/')
}
-//打包~
-makeJar.dependsOn(deleteOldJar)
\ No newline at end of file
+
+// 4.命名为ads
+task makeAds(type: Sync) {
+ from('build/libs/')
+ into('build/libs/')
+ include '*.jar'
+ rename { String filename ->
+ filename.replace(".jar", ".ads")
+ }
+}
+
+task openDirectory(type: Exec) {
+ println project.projectDir
+ commandLine 'cmd', "/c", "explorer.exe /root,\"${project.projectDir}\\build\\libs\""
+}
+
+// 打包~
+makeDex.dependsOn(deleteOldJar)
+makeJar.dependsOn(makeDex)
+makeAds.dependsOn(makeJar)
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 5dfc3fc6..6fbeea46 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -24,48 +24,27 @@
-keep class * implements java.io.Serializable { *;}
-keep class * implements android.os.Parcelable { *;}
-#-------------------------Umeng
--keep class com.umeng.** {*;}
--keep class com.uc.** {*;}
--keep class com.efs.** { *; }
-
--keepclassmembers class * {
- public