├── .github └── workflows │ └── android.yml ├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── compiler.xml ├── jarRepositories.xml └── misc.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── JavaMD5.jar │ ├── RootTools.jar │ └── tools.jar ├── proguard-class.txt ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── UnblockNeteaseMusic.zip │ └── xposed_init │ ├── java │ └── com │ │ └── raincat │ │ └── dolby_beta │ │ ├── Hook.java │ │ ├── HookerDispatcher.java │ │ ├── Hooklite.java │ │ ├── MainHook.java │ │ ├── db │ │ ├── CloudDao.java │ │ ├── CloudDbOpenHelper.java │ │ ├── ExtraDao.java │ │ ├── ExtraDbOpenHelper.java │ │ ├── SignDao.java │ │ └── SignDbOpenHelper.java │ │ ├── helper │ │ ├── ClassHelper.java │ │ ├── EAPIHelper.java │ │ ├── ExtraHelper.java │ │ ├── FileHelper.java │ │ ├── MessageHelper.java │ │ ├── NotificationHelper.java │ │ ├── ScriptHelper.java │ │ ├── SettingHelper.java │ │ ├── SignSongHelper.java │ │ └── UserHelper.java │ │ ├── hook │ │ ├── AdAndUpdateHook.java │ │ ├── AdExtraHook.java │ │ ├── AutoSignInHook.java │ │ ├── BlackHook.java │ │ ├── CdnHook.java │ │ ├── CommentHotClickHook.java │ │ ├── DownloadMD5Hook.java │ │ ├── EAPIHook.java │ │ ├── GrayHook.java │ │ ├── HideBannerHook.java │ │ ├── HideBubbleHook.java │ │ ├── HideSidebarHook.java │ │ ├── HideTabHook.java │ │ ├── InternalDialogHook.java │ │ ├── ListentogetherHook.java │ │ ├── LoginFixHook.java │ │ ├── MagiskFixHook.java │ │ ├── NightModeHook.java │ │ ├── PlayerActivityHook.java │ │ ├── ProxyHook.java │ │ ├── SettingHook.java │ │ ├── TestHook.java │ │ └── UserProfileHook.java │ │ ├── model │ │ ├── CloudHeader.java │ │ ├── DailyRecommendListBean.java │ │ ├── NeteaseSongListBean.java │ │ ├── PlaylistDetailBean.java │ │ ├── SidebarEnum.java │ │ ├── UserInfoBean.java │ │ └── UserPrivilegeBean.java │ │ ├── net │ │ ├── HTTPSTrustManager.java │ │ ├── Http.java │ │ ├── Https.java │ │ └── Request.java │ │ ├── utils │ │ ├── LogUtils.java │ │ ├── NeteaseAES.java │ │ ├── NeteaseAES2.java │ │ ├── NeteaseBase64.java │ │ └── Tools.java │ │ └── view │ │ ├── BaseDialogInputItem.java │ │ ├── BaseDialogItem.java │ │ ├── BaseDialogTextItem.java │ │ ├── beauty │ │ ├── BeautyBannerHideView.java │ │ ├── BeautyBlackHideView.java │ │ ├── BeautyBubbleHideView.java │ │ ├── BeautyCommentHotView.java │ │ ├── BeautyKSongHideView.java │ │ ├── BeautyNightModeView.java │ │ ├── BeautyRotationView.java │ │ ├── BeautySidebarHideItem.java │ │ ├── BeautySidebarHideView.java │ │ ├── BeautyTabHideView.java │ │ └── BeautyTitleView.java │ │ ├── proxy │ │ ├── ProxyCoverView.java │ │ ├── ProxyFlacView.java │ │ ├── ProxyGrayView.java │ │ ├── ProxyHttpView.java │ │ ├── ProxyMasterView.java │ │ ├── ProxyOriginalView.java │ │ ├── ProxyPortView.java │ │ ├── ProxyPriorityView.java │ │ ├── ProxyServerView.java │ │ └── ProxyTitleView.java │ │ ├── setting │ │ ├── AboutView.java │ │ ├── BeautyView.java │ │ ├── BlackView.java │ │ ├── DexView.java │ │ ├── FixCommentView.java │ │ ├── ListenView.java │ │ ├── MasterView.java │ │ ├── ProxyView.java │ │ ├── SignSongDailyView.java │ │ ├── SignSongSelfView.java │ │ ├── SignView.java │ │ ├── TitleView.java │ │ ├── UpdateView.java │ │ └── WarnView.java │ │ └── sign │ │ ├── SignCountView.java │ │ ├── SignIdView.java │ │ ├── SignStartView.java │ │ └── SignTitleView.java │ ├── jniLibs │ └── arm64-v8a │ │ └── libnode.so │ └── res │ ├── drawable │ └── ic_launcher_background.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hotxposed ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── androidwing │ │ └── hotxposed │ │ ├── HotXposed.java │ │ └── IHookerDispatcher.java │ └── res │ └── values │ └── strings.xml ├── image └── img_01.png └── settings.gradle /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout source code 16 | uses: actions/checkout@v2 17 | 18 | - name: set up JDK 1.8 19 | uses: actions/setup-java@v1 20 | with: 21 | java-version: 1.8 22 | 23 | - name: Grant execute permission for gradlew 24 | run: chmod +x gradlew 25 | 26 | - name: Build with Gradle 27 | run: ./gradlew app:assembleRelease 28 | 29 | - name: Upload APK 30 | uses: actions/upload-artifact@v2 31 | with: 32 | name: app-release 33 | path: ${{github.workspace}}/app/build/outputs/apk/release/*.apk 34 | if-no-files-found: warn 35 | retention-days: 30 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | release/ 7 | debug/ 8 | 9 | # Files for the ART/Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | !/app/libnode/bin/ 18 | gen/ 19 | out/ 20 | # Uncomment the following line in case you need and you don't have the release build type files in your app 21 | # release/ 22 | 23 | # Gradle files 24 | .gradle/ 25 | build/ 26 | 27 | # Local configuration file (sdk path, etc) 28 | local.properties 29 | 30 | # Proguard folder generated by Eclipse 31 | proguard/ 32 | 33 | # Log Files 34 | *.log 35 | 36 | # Android Studio Navigation editor temp files 37 | .navigation/ 38 | 39 | # Android Studio captures folder 40 | captures/ 41 | 42 | # IntelliJ 43 | *.iml 44 | .idea/workspace.xml 45 | .idea/tasks.xml 46 | .idea/gradle.xml 47 | .idea/assetWizardSettings.xml 48 | .idea/dictionaries 49 | .idea/libraries 50 | # Android Studio 3 in .gitignore file. 51 | .idea/caches 52 | .idea/modules.xml 53 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 54 | .idea/navEditor.xml 55 | 56 | # Keystore files 57 | # Uncomment the following lines if you do not want to check your keystore files in. 58 | #*.jks 59 | #*.keystore 60 | 61 | # External native build folder generated in Android Studio 2.2 and later 62 | .externalNativeBuild 63 | .cxx/ 64 | 65 | # Google Services (e.g. APIs or Firebase) 66 | # google-services.json 67 | 68 | # Freeline 69 | freeline.py 70 | freeline/ 71 | freeline_project_description.json 72 | 73 | # fastlane 74 | fastlane/report.xml 75 | fastlane/Preview.html 76 | fastlane/screenshots 77 | fastlane/test_output 78 | fastlane/readme.md 79 | 80 | # Version control 81 | vcs.xml 82 | 83 | # lint 84 | lint/intermediates/ 85 | lint/generated/ 86 | lint/outputs/ 87 | lint/tmp/ 88 | # lint/reports/ 89 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 20 | 21 | 22 | 23 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | xmlns:android 32 | 33 | ^$ 34 | 35 | 36 | 37 |
38 |
39 | 40 | 41 | 42 | xmlns:.* 43 | 44 | ^$ 45 | 46 | 47 | BY_NAME 48 | 49 |
50 |
51 | 52 | 53 | 54 | .*:id 55 | 56 | http://schemas.android.com/apk/res/android 57 | 58 | 59 | 60 |
61 |
62 | 63 | 64 | 65 | .*:name 66 | 67 | http://schemas.android.com/apk/res/android 68 | 69 | 70 | 71 |
72 |
73 | 74 | 75 | 76 | name 77 | 78 | ^$ 79 | 80 | 81 | 82 |
83 |
84 | 85 | 86 | 87 | style 88 | 89 | ^$ 90 | 91 | 92 | 93 |
94 |
95 | 96 | 97 | 98 | .* 99 | 100 | ^$ 101 | 102 | 103 | BY_NAME 104 | 105 |
106 |
107 | 108 | 109 | 110 | .* 111 | 112 | http://schemas.android.com/apk/res/android 113 | 114 | 115 | ANDROID_ATTRIBUTE_ORDER 116 | 117 |
118 |
119 | 120 | 121 | 122 | .* 123 | 124 | .* 125 | 126 | 127 | BY_NAME 128 | 129 |
130 |
131 |
132 |
133 |
134 |
-------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 nining377 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 杜比大喇叭β版 2 | 3 | [![Stars](https://img.shields.io/github/stars/nining377/dolby_beta?label=Stars)](https://github.com/nining377) 4 | [![Release](https://img.shields.io/github/v/release/nining377/dolby_beta?label=Release)](https://github.com/nining377/dolby_beta/releases/latest) 5 | [![Download](https://img.shields.io/github/downloads/nining377/dolby_beta/total)](https://github.com/nining377/dolby_beta/releases/latest) 6 | [![License](https://img.shields.io/github/license/nining377/dolby_beta?label=License)](https://choosealicense.com/licenses/mit/) 7 | 8 | #### 杜比大喇叭β是一款网易云音乐的音源代理模块,初衷只是我对网易云音乐的热爱,希望让更多的人使用网易云。 9 | #### 模块工作原理为音源替换而非破解,所以单曲付费与无版权歌曲有几率匹配错误,真心支持歌手请付费! 10 | #### 模块工作原理为音源替换而非破解,所以单曲付费与无版权歌曲有几率匹配错误,真心支持歌手请付费! 11 | #### 模块工作原理为音源替换而非破解,所以单曲付费与无版权歌曲有几率匹配错误,真心支持歌手请付费! 12 | #### 重要事情得说三遍,不要再因为不匹配而提交issue了。 13 | 14 | 杜比大喇叭β 3.X会有以下改变: 15 | - 编译版本提高至29并采用AndroidX API 16 | - 模块被嵌入到网易云音乐的设置中 17 | - 由于Android R对可执行文件的进一步限制,摒弃了2.X手动选择脚本与Node的方式 18 | - 当前版本以稳定为主,杜比大喇叭β将能无缝适配最新版网易云音乐,如有问题请提交issue 19 | - 因本人不使用太极,所以不保证太极等非root框架可以顺利运行,如非必要请使用内嵌版本 20 | 21 | *网易云在7.X版本后对非会员暗降了音质,由标准128K、较高192K、极高320K降低为标准96K、较高128K、极高256K,导致匹配逻辑出现问题,鉴于后续版本都在添加无用功能,推荐只听音乐的云村居民使用431或者600版本以获得最佳体验。* 22 | 23 | [快帮我点小星星呀,我要好多好多的小星星!](https://github.com/nining377/dolby_beta) 24 | 25 | ## 下载方式 26 | 27 | [GitHub Release](https://github.com/nining377/dolby_beta/releases/latest) 28 | 29 | [杜比大喇叭β版](https://wwi.lanzoui.com/b0cqxgwje) 访问密码:brdb 30 | 31 | [网易云音乐模块内嵌版①](https://wwu.lanzouw.com/b0crkhyzg) 访问密码:3qvw 32 | 33 | [网易云音乐模块内嵌版②](https://www.123pan.com/s/8qHrVv-hk1r) 访问密码:Wp2p 34 | 35 | [网易云音乐模块内嵌版制作教程](https://github.com/nining377/dolby_beta/issues/142) 36 | 37 | ## TODO 38 | 39 | - 尽可能保证不因模块造成crash(改版网易云往往经过二次混淆,将得不到适配) 40 | - ~~部分美化功能的添加~~(已完成) 41 | - ~~更稳定的代理方式~~(已完成) 42 | 43 | ## 主要功能 44 | 45 | 46 | 47 | ## 致谢 48 | 49 | [nondanee/UnblockNeteaseMusic](https://github.com/nondanee/UnblockNeteaseMusic) 50 | 51 | [Unblock Netease Music 维护小组](https://github.com/UnblockNeteaseMusic/server) 52 | 53 | [bin456789/Unblock163MusicClient-Xposed](https://github.com/bin456789/Unblock163MusicClient-Xposed) 54 | 55 | [Flysky12138/UnblockNeteaseMusic-Android](https://github.com/Flysky12138/UnblockNeteaseMusic-Android) 56 | 57 | ## 许可 58 | 59 | The MIT License 60 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | !/app/libnode/bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | # release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | .idea/workspace.xml 42 | .idea/tasks.xml 43 | .idea/gradle.xml 44 | .idea/assetWizardSettings.xml 45 | .idea/dictionaries 46 | .idea/libraries 47 | # Android Studio 3 in .gitignore file. 48 | .idea/caches 49 | .idea/modules.xml 50 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 51 | .idea/navEditor.xml 52 | 53 | # Keystore files 54 | # Uncomment the following lines if you do not want to check your keystore files in. 55 | #*.jks 56 | #*.keystore 57 | 58 | # External native build folder generated in Android Studio 2.2 and later 59 | .externalNativeBuild 60 | .cxx/ 61 | 62 | # Google Services (e.g. APIs or Firebase) 63 | # google-services.json 64 | 65 | # Freeline 66 | freeline.py 67 | freeline/ 68 | freeline_project_description.json 69 | 70 | # fastlane 71 | fastlane/report.xml 72 | fastlane/Preview.html 73 | fastlane/screenshots 74 | fastlane/test_output 75 | fastlane/readme.md 76 | 77 | # Version control 78 | vcs.xml 79 | 80 | # lint 81 | lint/intermediates/ 82 | lint/generated/ 83 | lint/outputs/ 84 | lint/tmp/ 85 | # lint/reports/ -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.raincat.dolby_beta" 9 | minSdkVersion 21 10 | targetSdkVersion 29 11 | versionCode 354 12 | versionName "3.5.4" 13 | 14 | ndk { 15 | abiFilters "arm64-v8a" 16 | } 17 | } 18 | 19 | buildTypes { 20 | release { 21 | buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log 22 | shrinkResources false //资源压缩 23 | minifyEnabled false //混淆 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | 28 | applicationVariants.all { 29 | variant -> 30 | variant.outputs.all { 31 | //只处理生产版本 32 | if (buildType.name == 'release') { 33 | def createTime = new Date().format("YYYYMMdd", TimeZone.getTimeZone("GMT+08:00")) 34 | // app包名称 35 | outputFileName = "dolby_beta_" + defaultConfig.versionName + "_" + createTime + "-" + buildType.name + ".apk" 36 | } 37 | } 38 | } 39 | 40 | compileOptions { 41 | sourceCompatibility JavaVersion.VERSION_1_8 42 | targetCompatibility JavaVersion.VERSION_1_8 43 | } 44 | 45 | lintOptions { 46 | abortOnError false 47 | } 48 | } 49 | 50 | dependencies { 51 | implementation fileTree(dir: "libs", include: ["*.jar"]) 52 | implementation 'androidx.appcompat:appcompat:1.2.0' 53 | implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' 54 | //xposed库 55 | compileOnly 'de.robv.android.xposed:api:82' 56 | compileOnly 'de.robv.android.xposed:api:82:sources' 57 | implementation 'com.annimon:stream:1.2.2' 58 | implementation 'org.smali:dexlib2:2.3.4' 59 | implementation 'com.google.guava:guava:28.2-android' 60 | implementation 'com.google.code.gson:gson:2.8.9' 61 | 62 | implementation project(':hotxposed') 63 | } 64 | -------------------------------------------------------------------------------- /app/libs/JavaMD5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/libs/JavaMD5.jar -------------------------------------------------------------------------------- /app/libs/RootTools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/libs/RootTools.jar -------------------------------------------------------------------------------- /app/libs/tools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/libs/tools.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Bin\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -keep class net.androidwing.hotxposed.* {*;} 20 | -keep class com.raincat.dolby_beta.MainHook 21 | -keep class com.raincat.dolby_beta.helper.ScriptHelper 22 | 23 | # 跳过所有Json实体类 24 | -keep public class **.*model*.** {*;} 25 | 26 | -keep class com.raincat.dolby_beta.HookerDispatcher* { 27 | void dispatch(*); 28 | } 29 | 30 | -keep public class android.app.** 31 | -keep class com.gyf.barlibrary.* {*;} 32 | -dontwarn com.gyf.barlibrary.** 33 | 34 | -dontwarn sun.misc.Unsafe 35 | -dontwarn com.google.common.collect.MinMaxPriorityQueue 36 | -dontwarn com.google.common.util.concurrent.FuturesGetChecked** 37 | -dontwarn javax.lang.model.element.Modifier 38 | -dontwarn afu.org.checkerframework.** 39 | -dontwarn org.checkerframework.** 40 | -dontwarn android.app.** 41 | -dontwarn org.jf.dexlib2.dexbacked.** 42 | 43 | #混淆变量和函数 44 | -obfuscationdictionary proguard-class.txt 45 | #混淆类名 46 | -classobfuscationdictionary proguard-class.txt 47 | # 指定class 48 | -packageobfuscationdictionary proguard-class.txt 49 | # 将包里的类混淆成n个再重新打包到一个统一的package中 会覆盖flattenpackagehierarchy选项 50 | -repackageclasses com.raincat.dolby_beta 51 | # 删除日志 52 | -assumenosideeffects class android.util.Log { 53 | public static boolean isLoggable(java.lang.String, int); 54 | public static int d(...); 55 | public static int w(...); 56 | public static int v(...); 57 | public static int i(...); 58 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | 19 | 23 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/assets/UnblockNeteaseMusic.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/src/main/assets/UnblockNeteaseMusic.zip -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.raincat.dolby_beta.MainHook -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/HookerDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta; 2 | 3 | import net.androidwing.hotxposed.IHookerDispatcher; 4 | 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 6 | 7 | /** 8 | *
 9 |  *     author : RainCat
10 |  *     e-mail : nining377@gmail.com
11 |  *     time   : 2019/10/23
12 |  *     desc   : Hook入口
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | 17 | public class HookerDispatcher implements IHookerDispatcher { 18 | @Override 19 | public void dispatch(XC_LoadPackage.LoadPackageParam lpparam) { 20 | new Hook(lpparam); 21 | new Hooklite(lpparam); 22 | } 23 | } 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/MainHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.raincat.dolby_beta.helper.ScriptHelper; 6 | 7 | import net.androidwing.hotxposed.HotXposed; 8 | 9 | import de.robv.android.xposed.IXposedHookLoadPackage; 10 | import de.robv.android.xposed.IXposedHookZygoteInit; 11 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2019/10/23
18 |  *     desc   : hook入口
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | public class MainHook implements IXposedHookLoadPackage, IXposedHookZygoteInit { 23 | @Override 24 | public void handleLoadPackage(final LoadPackageParam lpparam) throws Exception { 25 | if (!TextUtils.isEmpty(lpparam.packageName) && lpparam.packageName.equals("com.netease.cloudmusic")) { 26 | // HotXposed.hook(HookerDispatcher.class, lpparam); 27 | new Hook(lpparam); 28 | }else if (!TextUtils.isEmpty(lpparam.packageName) && lpparam.packageName.equals("com.netease.cloudmusic.lite")) { 29 | new Hooklite(lpparam); 30 | } 31 | } 32 | 33 | @Override 34 | public void initZygote(StartupParam startupParam) { 35 | ScriptHelper.modulePath = startupParam.modulePath; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/CloudDao.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     e-mail : nining377@gmail.com
12 |  *     time   : 2020/03/24
13 |  *     desc   : 云盘歌曲缓存
14 |  *     version: 1.0
15 |  * 
16 | */ 17 | public class CloudDao { 18 | static final String TABLE_NAME = "cloud"; 19 | static final String SONG_ID = "song_id"; 20 | static final String SONG_VALUE = "song_value"; 21 | 22 | private CloudDbOpenHelper dbHelper; 23 | static private CloudDao dao; 24 | 25 | private CloudDao(Context context) { 26 | dbHelper = CloudDbOpenHelper.getInstance(context); 27 | } 28 | 29 | public static synchronized CloudDao getInstance(Context context) { 30 | if (dao == null) { 31 | dao = new CloudDao(context); 32 | } 33 | return dao; 34 | } 35 | 36 | /** 37 | * 保存歌曲记录 38 | */ 39 | public void saveSong(int id, String value) { 40 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 41 | if (db.isOpen()) { 42 | ContentValues values = new ContentValues(); 43 | values.put(SONG_ID, id); 44 | values.put(SONG_VALUE, value); 45 | db.replace(TABLE_NAME, null, values); 46 | } 47 | db.close(); 48 | } 49 | 50 | /** 51 | * 获取某个歌曲记录 52 | */ 53 | public String getSong(int id) { 54 | String song = ""; 55 | SQLiteDatabase db = dbHelper.getReadableDatabase(); 56 | if (db.isOpen()) { 57 | Cursor cursor = db.rawQuery("select * from " + TABLE_NAME + " where " + SONG_ID + " = " + id, null); 58 | if (cursor.moveToNext()) { 59 | song = cursor.getString(cursor.getColumnIndex(SONG_VALUE)); 60 | } 61 | deleteSong(id); 62 | cursor.close(); 63 | } 64 | db.close(); 65 | return song; 66 | } 67 | 68 | /** 69 | * 删除一个人的某条歌曲记录 70 | */ 71 | private void deleteSong(int id) { 72 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 73 | if (db.isOpen()) { 74 | db.delete(TABLE_NAME, SONG_ID + " = ?", new String[]{id + ""}); 75 | } 76 | db.close(); 77 | } 78 | 79 | /** 80 | * 删除所有歌曲记录 81 | */ 82 | public void deleteAllSong() { 83 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 84 | if (db.isOpen()) { 85 | db.delete(TABLE_NAME, null, null); 86 | } 87 | db.close(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/CloudDbOpenHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | /** 8 | *
 9 |  *     author : RainCat
10 |  *     e-mail : nining377@gmail.com
11 |  *     time   : 2020/03/24
12 |  *     desc   : 云盘缓存
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | public class CloudDbOpenHelper extends SQLiteOpenHelper { 17 | private static final int DATABASE_VERSION = 1; 18 | private static CloudDbOpenHelper instance; 19 | 20 | private static final String CLOUD_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " 21 | + CloudDao.TABLE_NAME + " (" 22 | + CloudDao.SONG_ID + " INTEGER PRIMARY KEY, " 23 | + CloudDao.SONG_VALUE + " TEXT)"; 24 | 25 | 26 | @Override 27 | public void onCreate(SQLiteDatabase db) { 28 | db.execSQL(CLOUD_TABLE_CREATE); 29 | } 30 | 31 | private CloudDbOpenHelper(Context context) { 32 | super(context, getUserDatabaseName(), null, DATABASE_VERSION); 33 | } 34 | 35 | static CloudDbOpenHelper getInstance(Context context) { 36 | if (instance == null) { 37 | instance = new CloudDbOpenHelper(context); 38 | } 39 | return instance; 40 | } 41 | 42 | private static String getUserDatabaseName() { 43 | return "Cloud_" + DATABASE_VERSION + ".db"; 44 | } 45 | 46 | @Override 47 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 48 | } 49 | 50 | @Override 51 | public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { 52 | } 53 | 54 | @Override 55 | public void close() { 56 | if (instance != null) { 57 | try { 58 | SQLiteDatabase db = instance.getWritableDatabase(); 59 | db.close(); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | instance = null; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/ExtraDao.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     time   : 2020/03/30
12 |  *     desc   : 额外信息
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | public class ExtraDao { 17 | static final String TABLE_NAME = "extra"; 18 | static final String EXTRA_KEY = "extra_key"; 19 | static final String EXTRA_VALUE = "extra_value"; 20 | 21 | private ExtraDbOpenHelper dbHelper; 22 | static private ExtraDao dao; 23 | 24 | private ExtraDao(Context context) { 25 | dbHelper = ExtraDbOpenHelper.getInstance(context); 26 | } 27 | 28 | public static synchronized ExtraDao getInstance() { 29 | return dao; 30 | } 31 | 32 | public static void init(Context context) { 33 | dao = new ExtraDao(context); 34 | } 35 | 36 | /** 37 | * 保存额外记录 38 | */ 39 | public synchronized void saveExtra(String key, String value) { 40 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 41 | if (db.isOpen()) { 42 | ContentValues values = new ContentValues(); 43 | values.put(EXTRA_KEY, key); 44 | values.put(EXTRA_VALUE, value); 45 | db.replace(TABLE_NAME, null, values); 46 | } 47 | db.close(); 48 | } 49 | 50 | /** 51 | * 获取某个额外记录 52 | */ 53 | public synchronized String getExtra(String key) { 54 | String extra = "-1"; 55 | SQLiteDatabase db = dbHelper.getReadableDatabase(); 56 | if (db.isOpen()) { 57 | Cursor cursor = db.rawQuery("select * from " + TABLE_NAME + " where " + EXTRA_KEY + " = '" + key + "'", null); 58 | if (cursor.moveToNext()) 59 | extra = cursor.getString(cursor.getColumnIndex(EXTRA_VALUE)); 60 | cursor.close(); 61 | } 62 | db.close(); 63 | return extra; 64 | } 65 | 66 | /** 67 | * 删除一个人的某条额外记录 68 | */ 69 | public synchronized void deleteExtra(String key) { 70 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 71 | if (db.isOpen()) { 72 | db.delete(TABLE_NAME, EXTRA_KEY + " = ? ", new String[]{key}); 73 | } 74 | db.close(); 75 | } 76 | 77 | /** 78 | * 删除所有额外记录 79 | */ 80 | public synchronized void deleteAllExtra() { 81 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 82 | if (db.isOpen()) { 83 | db.delete(TABLE_NAME, null, null); 84 | } 85 | db.close(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/ExtraDbOpenHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     time   : 2020/03/30
12 |  *     desc   : 额外信息
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | public class ExtraDbOpenHelper extends SQLiteOpenHelper { 17 | private static final int DATABASE_VERSION = 1; 18 | private static ExtraDbOpenHelper instance; 19 | 20 | private static final String EXTRA_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " 21 | + ExtraDao.TABLE_NAME + " (" 22 | + ExtraDao.EXTRA_KEY + " VARCHAR(20) PRIMARY KEY, " 23 | + ExtraDao.EXTRA_VALUE + " TEXT ); "; 24 | 25 | 26 | @Override 27 | public void onCreate(SQLiteDatabase db) { 28 | db.execSQL(EXTRA_TABLE_CREATE); 29 | } 30 | 31 | private ExtraDbOpenHelper(Context context) { 32 | super(context, getUserDatabaseName(), null, DATABASE_VERSION); 33 | } 34 | 35 | static ExtraDbOpenHelper getInstance(Context context) { 36 | if (instance == null) { 37 | instance = new ExtraDbOpenHelper(context); 38 | } 39 | return instance; 40 | } 41 | 42 | private static String getUserDatabaseName() { 43 | return "Extra_" + DATABASE_VERSION + ".db"; 44 | } 45 | 46 | @Override 47 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 48 | } 49 | 50 | @Override 51 | public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { 52 | } 53 | 54 | @Override 55 | public void close() { 56 | if (instance != null) { 57 | try { 58 | SQLiteDatabase db = instance.getWritableDatabase(); 59 | db.close(); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | instance = null; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/SignDao.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     time   : 2020/04/16
15 |  *     desc   : 歌曲打卡
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | public class SignDao { 20 | static final String TABLE_NAME = "signed_song"; 21 | static final String SIGNED_USER_ID = "signed_user_id"; 22 | static final String SIGNED_SONG_ID = "signed_song_id"; 23 | 24 | private SignDbOpenHelper dbHelper; 25 | static private SignDao dao; 26 | 27 | private SignDao(Context context) { 28 | dbHelper = SignDbOpenHelper.getInstance(context); 29 | } 30 | 31 | public static synchronized SignDao getInstance(Context context) { 32 | if (dao == null) { 33 | dao = new SignDao(context); 34 | } 35 | return dao; 36 | } 37 | 38 | /** 39 | * 保存已打卡歌曲记录 40 | */ 41 | public void saveSongList(List songIdList, String userId) { 42 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 43 | if (db.isOpen()) { 44 | for (long songId : songIdList) { 45 | ContentValues values = new ContentValues(); 46 | values.put(SIGNED_SONG_ID, songId); 47 | values.put(SIGNED_USER_ID, userId); 48 | db.replace(TABLE_NAME, null, values); 49 | } 50 | } 51 | db.close(); 52 | } 53 | 54 | /** 55 | * 获取已打卡歌曲 56 | */ 57 | public HashMap getSong(String userId) { 58 | SQLiteDatabase db = dbHelper.getReadableDatabase(); 59 | HashMap longMap = new HashMap<>(); 60 | if (db.isOpen()) { 61 | Cursor cursor = db.rawQuery("select " + SIGNED_SONG_ID + " from " + TABLE_NAME + " where " + SIGNED_USER_ID + " = '" + userId + "'", null); 62 | while (cursor.moveToNext()) { 63 | longMap.put(cursor.getLong(cursor.getColumnIndex(SIGNED_SONG_ID)), 1); 64 | } 65 | cursor.close(); 66 | } 67 | db.close(); 68 | return longMap; 69 | } 70 | 71 | /** 72 | * 删除一个人的某条额外记录 73 | */ 74 | public void deleteSong(String userId) { 75 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 76 | if (db.isOpen()) { 77 | db.delete(TABLE_NAME, SIGNED_USER_ID + " = ?", new String[]{userId}); 78 | } 79 | db.close(); 80 | } 81 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/db/SignDbOpenHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | /** 8 | *
 9 |  *     author : RainCat
10 |  *     time   : 2020/04/16
11 |  *     desc   : 歌曲打卡
12 |  *     version: 1.0
13 |  * 
14 | */ 15 | public class SignDbOpenHelper extends SQLiteOpenHelper { 16 | private static final int DATABASE_VERSION = 1; 17 | private static SignDbOpenHelper instance; 18 | 19 | private static final String SONG_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " 20 | + SignDao.TABLE_NAME + " (" 21 | + SignDao.SIGNED_SONG_ID + " BIGINT PRIMARY KEY, " 22 | + SignDao.SIGNED_USER_ID + " VARCHAR(20) ); "; 23 | 24 | 25 | @Override 26 | public void onCreate(SQLiteDatabase db) { 27 | db.execSQL(SONG_TABLE_CREATE); 28 | } 29 | 30 | private SignDbOpenHelper(Context context) { 31 | super(context, getUserDatabaseName(), null, DATABASE_VERSION); 32 | } 33 | 34 | static SignDbOpenHelper getInstance(Context context) { 35 | if (instance == null) { 36 | instance = new SignDbOpenHelper(context); 37 | } 38 | return instance; 39 | } 40 | 41 | private static String getUserDatabaseName() { 42 | return "SignedSong_" + DATABASE_VERSION + ".db"; 43 | } 44 | 45 | @Override 46 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 47 | } 48 | 49 | @Override 50 | public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { 51 | } 52 | 53 | @Override 54 | public void close() { 55 | if (instance != null) { 56 | try { 57 | SQLiteDatabase db = instance.getWritableDatabase(); 58 | db.close(); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | instance = null; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/helper/ExtraHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.helper; 2 | 3 | import android.content.Context; 4 | 5 | import com.raincat.dolby_beta.db.ExtraDao; 6 | 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     e-mail : nining377@gmail.com
12 |  *     time   : 2021/04/14
13 |  *     desc   : 额外数据帮助类
14 |  *     version: 1.0
15 |  * 
16 | */ 17 | 18 | public class ExtraHelper { 19 | //脚本运行情况,运行中1,未运行0 20 | public static final String SCRIPT_STATUS = "script_status"; 21 | //APP版本号 22 | public static final String APP_VERSION = "app_version"; 23 | 24 | //用户id 25 | public static final String USER_ID = "user_id"; 26 | //cookie 27 | public static final String COOKIE = "cookie"; 28 | //我喜欢的音乐的id 29 | public static final String LOVE_PLAY_LIST = "play_list"; 30 | //签到时间 31 | public static final String SIGN_TIME = "sign_time"; 32 | //打卡时间 33 | public static final String SIGN_SONG_TIME = "sign_song_time"; 34 | 35 | //初始化数据库 36 | public static void init(Context context) { 37 | ExtraDao.init(context); 38 | } 39 | 40 | public static String getExtraDate(String key) { 41 | return ExtraDao.getInstance().getExtra(key); 42 | } 43 | 44 | public static void setExtraDate(String key, Object value) { 45 | ExtraDao.getInstance().saveExtra(key, value.toString()); 46 | } 47 | 48 | /** 49 | * 清除当前用户的数据 50 | */ 51 | public static void cleanUserData() { 52 | setExtraDate(COOKIE, "-1"); 53 | setExtraDate(USER_ID, "-1"); 54 | setExtraDate(LOVE_PLAY_LIST, "-1"); 55 | setExtraDate(SIGN_TIME, "-1"); 56 | setExtraDate(SIGN_SONG_TIME, "-1"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/helper/MessageHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.helper; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Build; 6 | 7 | import de.robv.android.xposed.XposedBridge; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/25
14 |  *     desc   : 通知帮助类
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class MessageHelper { 20 | public static void sendNotification(Context context, int code) { 21 | if (!SettingHelper.getInstance().isEnable(SettingHelper.warn_key)) 22 | return; 23 | Intent intent = new Intent(); 24 | intent.putExtra("title", "错误"); 25 | switch (code) { 26 | case cookieClassNotFoundCode: 27 | intent.putExtra("code", cookieClassNotFoundCode); 28 | intent.putExtra("message", cookieClassNotFoundMessage); 29 | break; 30 | case transferClassNotFoundCode: 31 | intent.putExtra("code", transferClassNotFoundCode); 32 | intent.putExtra("message", transferClassNotFoundMessage); 33 | break; 34 | case coreClassNotFoundCode: 35 | intent.putExtra("code", coreClassNotFoundCode); 36 | intent.putExtra("message", coreClassNotFoundMessage); 37 | break; 38 | case tabClassNotFoundCode: 39 | intent.putExtra("code", tabClassNotFoundCode); 40 | intent.putExtra("message", tabClassNotFoundMessage); 41 | break; 42 | case sidebarClassNotFoundCode: 43 | intent.putExtra("code", sidebarClassNotFoundCode); 44 | intent.putExtra("message", sidebarClassNotFoundMessage); 45 | break; 46 | } 47 | 48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 49 | NotificationHelper.getInstance(context).sendUnLockNotification(context, intent.getIntExtra("code", 0x10), 50 | intent.getStringExtra("title"), intent.getStringExtra("title"), intent.getStringExtra("message")); 51 | XposedBridge.log(intent.getStringExtra("title") + ":" + intent.getStringExtra("message")); 52 | } 53 | 54 | private final static String normalMessage = "请确保已使用官方版网易云。"; 55 | 56 | public final static int cookieClassNotFoundCode = 1000; 57 | private final static String cookieClassNotFoundMessage = "找不到Cookie类,这将导致签到、打卡、收藏等功能失效," + normalMessage; 58 | 59 | public final static int transferClassNotFoundCode = 1001; 60 | private final static String transferClassNotFoundMessage = "找不到DownloadTransfer类,这将导致下载校验功能失效," + normalMessage; 61 | 62 | public final static int coreClassNotFoundCode = 1002; 63 | private final static String coreClassNotFoundMessage = "找不到核心类,这将导致音源代理功能失效," + normalMessage; 64 | 65 | public final static int tabClassNotFoundCode = 1003; 66 | private final static String tabClassNotFoundMessage = "找不到Tab类,这将导致Tab精简功能失效," + normalMessage; 67 | 68 | public final static int sidebarClassNotFoundCode = 1004; 69 | private final static String sidebarClassNotFoundMessage = "找不到Sidebar类,这将导致侧边栏精简功能失效," + normalMessage; 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/helper/NotificationHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.helper; 2 | 3 | import android.app.Notification; 4 | import android.app.NotificationChannel; 5 | import android.app.NotificationManager; 6 | import android.app.PendingIntent; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.pm.ApplicationInfo; 10 | import android.graphics.Bitmap; 11 | import android.graphics.Canvas; 12 | import android.graphics.PixelFormat; 13 | import android.graphics.drawable.Drawable; 14 | import android.graphics.drawable.Icon; 15 | import android.media.RingtoneManager; 16 | import android.os.Build; 17 | 18 | import androidx.annotation.RequiresApi; 19 | 20 | /** 21 | * 一个通用的Notification工具 22 | *

23 | * Created by Administrator on 2018/3/29 0029. 24 | */ 25 | 26 | public class NotificationHelper { 27 | private NotificationManager mNotificationManager; 28 | private static NotificationHelper mNotificationHelper; 29 | 30 | public static NotificationHelper getInstance(Context context) { 31 | if (mNotificationHelper == null) { 32 | mNotificationHelper = new NotificationHelper(context); 33 | } 34 | return mNotificationHelper; 35 | } 36 | 37 | private NotificationHelper(Context context) { 38 | if (mNotificationManager == null) 39 | mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 40 | } 41 | 42 | /** 43 | * 设置一个不常驻通知栏的Notification 44 | * 45 | * @param appId 标识符 46 | * @param ticker 通知首次出现在通知栏时提醒的文字 47 | * @param title 标题 48 | * @param content 详细内容 49 | */ 50 | @RequiresApi(api = Build.VERSION_CODES.M) 51 | public void sendUnLockNotification(Context context, int appId, String ticker, String title, String content) { 52 | Notification.Builder builder = new Notification.Builder(context); 53 | ApplicationInfo applicationInfo = context.getApplicationInfo(); 54 | Drawable drawable = applicationInfo.loadIcon(context.getPackageManager()); 55 | Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), 56 | drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); 57 | Canvas canvas = new Canvas(bitmap); 58 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 59 | drawable.draw(canvas); 60 | Icon icon = Icon.createWithBitmap(bitmap); 61 | builder.setSmallIcon(icon) 62 | .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0)) 63 | .setContentTitle(title) 64 | .setTicker(ticker) 65 | .setAutoCancel(true) 66 | .setDefaults(Notification.DEFAULT_LIGHTS); 67 | if (Build.VERSION.SDK_INT >= 26) { 68 | NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName() + appId, "UnblockNeteaseMusic", NotificationManager.IMPORTANCE_HIGH); 69 | notificationChannel.enableLights(true); 70 | notificationChannel.enableVibration(true); 71 | notificationChannel.setVibrationPattern(new long[]{200L, 200L, 200L, 200L}); 72 | notificationChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), Notification.AUDIO_ATTRIBUTES_DEFAULT); 73 | builder.setChannelId(context.getPackageName() + appId); 74 | mNotificationManager.createNotificationChannel(notificationChannel); 75 | } else { 76 | builder.setVibrate(new long[]{200L, 200L, 200L, 200L}); 77 | builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); 78 | } 79 | 80 | Notification notification = new Notification.BigTextStyle(builder).bigText(content).build(); 81 | mNotificationManager.notify(appId, notification); 82 | } 83 | 84 | /** 85 | * 取消该通知 86 | * 87 | * @param appId 通知标识符 88 | */ 89 | public void cancelNotification(int appId) { 90 | mNotificationManager.cancel(appId); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/helper/UserHelper.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.helper; 2 | 3 | import com.google.gson.Gson; 4 | import com.raincat.dolby_beta.model.UserInfoBean; 5 | import com.raincat.dolby_beta.net.Http; 6 | 7 | import java.util.HashMap; 8 | 9 | /** 10 | *

11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/04/15
14 |  *     desc   : 用户状态帮助类
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class UserHelper { 20 | /** 21 | * 通过cookie获取用户信息 22 | */ 23 | public static void getUserInfo() { 24 | HashMap headers = new HashMap<>(); 25 | headers.put("cookie", ExtraHelper.getExtraDate(ExtraHelper.COOKIE)); 26 | String userInfo = new Http("GET", "https://music.163.com/api/nuser/account/get", headers, (String) null).getResult(); 27 | Gson gson = new Gson(); 28 | UserInfoBean userInfoBean = gson.fromJson(userInfo, UserInfoBean.class); 29 | ExtraHelper.setExtraDate(ExtraHelper.USER_ID, userInfoBean.getProfile().getUserId()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/AdAndUpdateHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | 9 | import java.lang.reflect.Field; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XposedHelpers; 13 | 14 | import static de.robv.android.xposed.XposedBridge.hookAllMethods; 15 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 16 | import static de.robv.android.xposed.XposedHelpers.findClassIfExists; 17 | 18 | /** 19 | *
20 |  *     author : RainCat
21 |  *     time   : 2019/10/23
22 |  *     desc   : 去广告和升级
23 |  *     version: 1.0
24 |  * 
25 | */ 26 | 27 | public class AdAndUpdateHook { 28 | private static String okHttpClientClassString = "okhttp3.OkHttpClient"; 29 | private static String newCallMethodString = "newCall"; 30 | private static String httpUrlFieldString = "url"; 31 | private static String urlFieldString = "url"; 32 | 33 | public AdAndUpdateHook(Context context, final int versionCode) { 34 | if (versionCode < 138) { 35 | okHttpClientClassString = "okhttp3.x"; 36 | newCallMethodString = "a"; 37 | httpUrlFieldString = "a"; 38 | urlFieldString = "j"; 39 | } 40 | 41 | //去广告和升级 42 | Class okHttpClientClass = findClassIfExists(okHttpClientClassString, context.getClassLoader()); 43 | if (okHttpClientClass != null) 44 | hookAllMethods(okHttpClientClass, newCallMethodString, new XC_MethodHook() { 45 | @Override 46 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 47 | if (param.args != null && param.args.length == 1 && param.args[0].getClass().getName().contains("okhttp")) { 48 | Object request = param.args[0]; 49 | Field httpUrl = request.getClass().getDeclaredField(httpUrlFieldString); 50 | httpUrl.setAccessible(true); 51 | Object urlObj = httpUrl.get(request); 52 | //加了一个反营销版权保护的URL,暂时作用未知 53 | if (urlObj.toString().contains("appcustomconfig/get") 54 | //去广告 55 | || (SettingHelper.getInstance().isEnable(SettingHelper.black_key) && !urlObj.toString().contains("music.126.net") && (urlObj.toString().contains("resource-exposure/config") || urlObj.toString().contains("api/ad") || urlObj.toString().endsWith(".jpg") || urlObj.toString().endsWith(".mp4"))) 56 | //去升级 57 | || (SettingHelper.getInstance().isEnable(SettingHelper.update_key) && (urlObj.toString().contains("android/version") || urlObj.toString().contains("android/upgrade")))) { 58 | Field url = urlObj.getClass().getDeclaredField(urlFieldString); 59 | boolean urlAccessible = url.isAccessible(); 60 | url.setAccessible(true); 61 | url.set(urlObj, "https://999.0.0.1/"); 62 | url.setAccessible(urlAccessible); 63 | param.args[0] = request; 64 | } 65 | } 66 | } 67 | }); 68 | 69 | if (SettingHelper.getInstance().isEnable(SettingHelper.black_key) && XposedHelpers.findClassIfExists("com.netease.cloudmusic.activity.LoadingAdActivity", context.getClassLoader()) != null) 70 | findAndHookMethod("com.netease.cloudmusic.activity.LoadingAdActivity", context.getClassLoader(), 71 | "onCreate", Bundle.class, new XC_MethodHook() { 72 | @Override 73 | protected void afterHookedMethod(MethodHookParam param) { 74 | ((Activity) param.thisObject).finish(); 75 | param.setResult(null); 76 | } 77 | }); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/AdExtraHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import com.raincat.dolby_beta.helper.ClassHelper; 4 | import com.raincat.dolby_beta.helper.SettingHelper; 5 | 6 | import org.json.JSONObject; 7 | 8 | import java.lang.reflect.Method; 9 | import java.util.List; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XposedBridge; 13 | 14 | /** 15 | *
16 |  *     author : RainCat
17 |  *     e-mail : nining377@gmail.com
18 |  *     time   : 2022/06/12
19 |  *     desc   : 广告移除增强
20 |  *     version: 1.0
21 |  * 
22 | */ 23 | public class AdExtraHook { 24 | public AdExtraHook() { 25 | if (SettingHelper.getInstance().isEnable(SettingHelper.black_key)) { 26 | List methods = ClassHelper.Ad.getAdMethod(); 27 | if (methods != null) { 28 | for (Method method : methods) { 29 | XposedBridge.hookMethod(method, new XC_MethodHook() { 30 | @Override 31 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 32 | super.beforeHookedMethod(param); 33 | for (int i = 0; i < param.args.length; i++) { 34 | if (param.args[i] instanceof JSONObject) { 35 | param.args[i] = new JSONObject(); 36 | return; 37 | } 38 | } 39 | } 40 | }); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/AutoSignInHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.widget.TextView; 5 | 6 | import com.raincat.dolby_beta.helper.ExtraHelper; 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | import com.raincat.dolby_beta.helper.SignSongHelper; 9 | import com.raincat.dolby_beta.net.Http; 10 | import com.raincat.dolby_beta.utils.Tools; 11 | 12 | import java.lang.reflect.Field; 13 | import java.util.HashMap; 14 | 15 | import de.robv.android.xposed.XC_MethodHook; 16 | import de.robv.android.xposed.XC_MethodReplacement; 17 | 18 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 19 | import static de.robv.android.xposed.XposedHelpers.findClassIfExists; 20 | 21 | /** 22 | *
 23 |  *     author : RainCat
 24 |  *     e-mail : nining377@gmail.com
 25 |  *     time   : 2020/09/26
 26 |  *     desc   : 自动签到hook
 27 |  *     version: 1.0
 28 |  * 
29 | */ 30 | 31 | public class AutoSignInHook { 32 | private String methodInitDrawerHeader = "initDrawerHeader"; 33 | private String valueDrawerUserSignIn = "drawerUserSignIn"; 34 | 35 | public AutoSignInHook(Context context, int versionCode) { 36 | //每天0点签到 37 | findAndHookMethod("com.netease.cloudmusic.activity.MainActivity", context.getClassLoader(), 38 | "onStart", new XC_MethodHook() { 39 | @Override 40 | protected void afterHookedMethod(MethodHookParam param) { 41 | if (SettingHelper.getInstance().isEnable(SettingHelper.sign_key) || SettingHelper.getInstance().isEnable(SettingHelper.sign_song_key)) { 42 | String userId = ExtraHelper.getExtraDate(ExtraHelper.USER_ID); 43 | String cookie = ExtraHelper.getExtraDate(ExtraHelper.COOKIE); 44 | if (userId.equals("-1") || cookie.equals("-1")) 45 | return; 46 | if (SettingHelper.getInstance().isEnable(SettingHelper.sign_key)) { 47 | long lastSignInTime = Long.parseLong(ExtraHelper.getExtraDate(ExtraHelper.SIGN_TIME + userId)); 48 | if (lastSignInTime < Tools.getTodayStartTime()) { 49 | sign(context, cookie); 50 | ExtraHelper.setExtraDate(ExtraHelper.SIGN_TIME + userId, System.currentTimeMillis()); 51 | } 52 | } 53 | if (SettingHelper.getInstance().isEnable(SettingHelper.sign_song_key)) { 54 | long lastSignInTime = Long.parseLong(ExtraHelper.getExtraDate(ExtraHelper.SIGN_SONG_TIME + userId)); 55 | if (lastSignInTime < Tools.getTodayStartTime()) { 56 | SignSongHelper.showSignStatusDialog((Context) param.thisObject, SettingHelper.sign_song_title, null); 57 | ExtraHelper.setExtraDate(ExtraHelper.SIGN_SONG_TIME + userId, System.currentTimeMillis()); 58 | } 59 | } 60 | } 61 | } 62 | }); 63 | 64 | //更改当前签到状态 65 | Class userProfileClass = findClassIfExists("com.netease.cloudmusic.meta.Profile", context.getClassLoader()); 66 | if (userProfileClass != null) { 67 | findAndHookMethod(userProfileClass, "isMobileSign", XC_MethodReplacement.returnConstant(true)); 68 | } 69 | 70 | Class mainDrawerClass = findClassIfExists("com.netease.cloudmusic.ui.MainDrawer", context.getClassLoader()); 71 | if (mainDrawerClass == null) { 72 | mainDrawerClass = findClassIfExists("com.netease.cloudmusic.ui.l", context.getClassLoader()); 73 | methodInitDrawerHeader = "r"; 74 | valueDrawerUserSignIn = "t"; 75 | } 76 | 77 | //更改当前签到状态文字 78 | if (versionCode < 7003000 && mainDrawerClass != null) { 79 | findAndHookMethod(mainDrawerClass, methodInitDrawerHeader, new XC_MethodHook() { 80 | @Override 81 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 82 | Field drawerUserSignInField = param.thisObject.getClass().getDeclaredField(valueDrawerUserSignIn); 83 | drawerUserSignInField.setAccessible(true); 84 | TextView drawerUserSignIn = (TextView) drawerUserSignInField.get(param.thisObject); 85 | drawerUserSignIn.setText("已签到"); 86 | drawerUserSignIn.setEnabled(false); 87 | drawerUserSignIn.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); 88 | } 89 | }); 90 | } 91 | } 92 | 93 | /** 94 | * 签到 95 | */ 96 | private void sign(Context context, String cookie) { 97 | HashMap header = new HashMap<>(); 98 | header.put("Cookie", cookie); 99 | 100 | HashMap param = new HashMap<>(); 101 | param.put("type", "1"); 102 | new Http("POST", "http://music.163.com/api/point/dailyTask", param, header).getResult(); 103 | 104 | param.put("type", "0"); 105 | String result = new Http("POST", "http://music.163.com/api/point/dailyTask", param, header).getResult(); 106 | if (result.contains("200") && !result.contains("msg")) 107 | Tools.showToastOnLooper(context, "自动签到成功"); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/CdnHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | 5 | import com.raincat.dolby_beta.helper.ClassHelper; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | import de.robv.android.xposed.XC_MethodHook; 10 | import de.robv.android.xposed.XposedBridge; 11 | import de.robv.android.xposed.XposedHelpers; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2021/09/13
18 |  *     desc   : 绕过CDN责任链拦截器检测
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | 23 | public class CdnHook { 24 | public CdnHook(Context context, int versionCode) { 25 | if (versionCode < 138) 26 | return; 27 | for (Method m : ClassHelper.HttpInterceptor.getMethodList(context)) 28 | XposedBridge.hookMethod(m, new XC_MethodHook() { 29 | @Override 30 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 31 | super.beforeHookedMethod(param); 32 | param.setResult(param.args[2]); 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/CommentHotClickHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | 5 | import com.raincat.dolby_beta.helper.ClassHelper; 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | 8 | import org.json.JSONArray; 9 | 10 | import java.lang.reflect.Field; 11 | import java.lang.reflect.Modifier; 12 | 13 | import de.robv.android.xposed.XC_MethodHook; 14 | import de.robv.android.xposed.XposedBridge; 15 | import de.robv.android.xposed.XposedHelpers; 16 | 17 | /** 18 | *
19 |  *     author : RainCat
20 |  *     e-mail : nining377@gmail.com
21 |  *     time   : 2020/05/30
22 |  *     desc   : 评论区优先显示“最热”内容
23 |  *     version: 1.0
24 |  * 
25 | */ 26 | public class CommentHotClickHook { 27 | public CommentHotClickHook(Context context) { 28 | if (!SettingHelper.getInstance().isEnable(SettingHelper.beauty_comment_hot_key)) 29 | return; 30 | Class commentDataClass = ClassHelper.CommentDataClass.getClazz(); 31 | if (commentDataClass != null) { 32 | XposedBridge.hookAllConstructors(commentDataClass, new XC_MethodHook() { 33 | @Override 34 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 35 | super.afterHookedMethod(param); 36 | Object object = param.thisObject; 37 | Field[] fields = object.getClass().getDeclaredFields(); 38 | for (Field field : fields) { 39 | if (Modifier.isPrivate(field.getModifiers()) && !Modifier.isFinal(field.getModifiers()) && field.getType() == int.class) { 40 | field.setAccessible(true); 41 | Object o = field.get(object); 42 | if ((int) o == 0) 43 | field.set(object, 2); 44 | } 45 | } 46 | } 47 | }); 48 | 49 | Class sortTypeListClass = XposedHelpers.findClassIfExists("com.netease.cloudmusic.module.comment2.meta.SortTypeList", context.getClassLoader()); 50 | if (sortTypeListClass == null) 51 | sortTypeListClass = XposedHelpers.findClassIfExists("com.netease.cloudmusic.music.biz.comment.meta.SortTypeList", context.getClassLoader()); 52 | if (sortTypeListClass != null) 53 | XposedHelpers.findAndHookMethod(sortTypeListClass, "parseList", JSONArray.class, new XC_MethodHook() { 54 | @Override 55 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 56 | super.beforeHookedMethod(param); 57 | JSONArray array = (JSONArray) param.args[0]; 58 | JSONArray array2 = new JSONArray(); 59 | array2.put(array.getJSONObject(1)); 60 | array2.put(array.getJSONObject(2)); 61 | array2.put(array.getJSONObject(0)); 62 | param.args[0] = array2; 63 | } 64 | }); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/DownloadMD5Hook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import com.raincat.dolby_beta.helper.ClassHelper; 7 | 8 | import java.io.FileInputStream; 9 | import java.io.InputStream; 10 | import java.lang.reflect.Method; 11 | import java.security.MessageDigest; 12 | 13 | import de.robv.android.xposed.XC_MethodHook; 14 | import de.robv.android.xposed.XposedHelpers; 15 | 16 | import static de.robv.android.xposed.XposedBridge.hookMethod; 17 | 18 | /** 19 | *
20 |  *     author : RainCat
21 |  *     time   : 2019/10/23
22 |  *     desc   : 下载强制返回正确MD5
23 |  *     version: 1.0
24 |  * 
25 | */ 26 | 27 | public class DownloadMD5Hook { 28 | public DownloadMD5Hook(Context context) { 29 | hookMethod(ClassHelper.DownloadTransfer.getCheckMd5Method(context), new XC_MethodHook() { 30 | @Override 31 | protected void beforeHookedMethod(MethodHookParam param) { 32 | final Object[] array = (Object[]) param.args[3]; 33 | String path = param.args[0].toString(); 34 | array[5] = fileToMD5(path); 35 | param.args[3] = array; 36 | } 37 | }); 38 | 39 | hookMethod(ClassHelper.DownloadTransfer.getCheckDownloadStatusMethod(context), new XC_MethodHook() { 40 | @Override 41 | protected void beforeHookedMethod(MethodHookParam param) { 42 | Method[] methods = param.args[0].getClass().getDeclaredMethods(); 43 | for (Method m : methods) { 44 | if (m.getReturnType() == long.class) { 45 | long length = (long) XposedHelpers.callMethod(param.args[0], m.getName()); 46 | param.setResult(length); 47 | break; 48 | } 49 | } 50 | } 51 | }); 52 | } 53 | 54 | private String fileToMD5(String filePath) { 55 | try (InputStream inputStream = new FileInputStream(filePath)) { 56 | byte[] buffer = new byte[1024]; 57 | MessageDigest digest = MessageDigest.getInstance("MD5"); 58 | int numRead = 0; 59 | while (numRead != -1) { 60 | numRead = inputStream.read(buffer); 61 | if (numRead > 0) 62 | digest.update(buffer, 0, numRead); 63 | } 64 | byte[] md5Bytes = digest.digest(); 65 | return convertHashToString(md5Bytes); 66 | } catch (Exception e) { 67 | return null; 68 | } 69 | } 70 | 71 | /** 72 | * Convert the hash bytes to hex digits string 73 | * 74 | * @return The converted hex digits string 75 | */ 76 | private String convertHashToString(byte[] hashBytes) { 77 | StringBuilder returnVal = new StringBuilder(); 78 | for (byte hashByte : hashBytes) { 79 | returnVal.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1)); 80 | } 81 | return returnVal.toString().toLowerCase(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/GrayHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.Method; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XC_MethodReplacement; 13 | import de.robv.android.xposed.XposedBridge; 14 | import de.robv.android.xposed.XposedHelpers; 15 | 16 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 17 | import static de.robv.android.xposed.XposedHelpers.findClass; 18 | 19 | /** 20 | *
21 |  *     author : RainCat
22 |  *     time   : 2019/10/23
23 |  *     desc   : 不变灰
24 |  *     version: 1.0
25 |  * 
26 | */ 27 | 28 | public class GrayHook { 29 | public GrayHook(Context context) { 30 | if (SettingHelper.getInstance().isEnable(SettingHelper.proxy_gray_key)) 31 | findAndHookMethod(findClass("com.netease.cloudmusic.meta.MusicInfo", context.getClassLoader()), 32 | "hasCopyRight", XC_MethodReplacement.returnConstant(true)); 33 | 34 | if (SettingHelper.getInstance().isEnable(SettingHelper.proxy_master_key)) { 35 | Class songPrivilegeClass = XposedHelpers.findClassIfExists("com.netease.cloudmusic.meta.virtual.SongPrivilege", context.getClassLoader()); 36 | if (songPrivilegeClass != null) { 37 | Method method = null; 38 | try { 39 | method = songPrivilegeClass.getMethod("setDownloadMaxbr", int.class); 40 | } catch (NoSuchMethodException e) { 41 | try { 42 | method = songPrivilegeClass.getMethod("setFreeLevel", int.class); 43 | } catch (NoSuchMethodException ex) { 44 | Log.w("error", ex.getMessage()); 45 | } 46 | } 47 | if (method != null) 48 | XposedBridge.hookMethod(method, new XC_MethodHook() { 49 | @Override 50 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 51 | super.beforeHookedMethod(param); 52 | Object object = param.thisObject; 53 | long id = (long) XposedHelpers.callMethod(object, "getId"); 54 | if (id == 0) 55 | return; 56 | 57 | Field[] fields = object.getClass().getDeclaredFields(); 58 | int maxbr = 0; 59 | for (Field field : fields) { 60 | if (field.getType() == int.class && field.getName().equals("maxbr")) { 61 | field.setAccessible(true); 62 | maxbr = (int) field.get(object); 63 | break; 64 | } 65 | } 66 | if (maxbr == 0) 67 | maxbr = 999000; 68 | 69 | try { 70 | param.args[0] = maxbr; 71 | XposedHelpers.callMethod(object, "setSubPriv", 1); 72 | XposedHelpers.callMethod(object, "setSharePriv", 1); 73 | XposedHelpers.callMethod(object, "setCommentPriv", 1); 74 | XposedHelpers.callMethod(object, "setDownMaxLevel", maxbr); 75 | XposedHelpers.callMethod(object, "setPlayMaxLevel", maxbr); 76 | if (object.getClass().getDeclaredMethod("setPlayMaxbr", int.class) != null) 77 | XposedHelpers.callMethod(object, "setPlayMaxbr", maxbr); 78 | } catch (Exception e) { 79 | Log.w("error", e.getMessage()); 80 | } 81 | } 82 | }); 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/HideBannerHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | 10 | import de.robv.android.xposed.XC_MethodHook; 11 | import de.robv.android.xposed.XposedHelpers; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2021/10/23
18 |  *     desc   : 移除Banner
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | public class HideBannerHook { 23 | private String mainBannerContainerClassString = "com.netease.cloudmusic.ui.MainBannerContainer"; 24 | public HideBannerHook(Context context, final int versionCode) { 25 | if (!SettingHelper.getInstance().isEnable(SettingHelper.beauty_banner_hide_key)) 26 | return; 27 | if (versionCode < 138) 28 | mainBannerContainerClassString = "com.netease.cloudmusic.ui.NeteaseMusicViewFlipper"; 29 | 30 | if (XposedHelpers.findClassIfExists(mainBannerContainerClassString, context.getClassLoader()) != null) 31 | XposedHelpers.findAndHookMethod(mainBannerContainerClassString, context.getClassLoader(), "onAttachedToWindow", new XC_MethodHook() { 32 | @Override 33 | protected void beforeHookedMethod(MethodHookParam param) { 34 | View view = (View) param.thisObject; 35 | ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); 36 | layoutParams.height = 1;//改成0将导致无法下滑刷新 37 | view.setLayoutParams(layoutParams); 38 | view.setVisibility(View.GONE); 39 | } 40 | }); 41 | 42 | String playlistBannerContainerClassString = "com.netease.cloudmusic.ui.PlaylistBanner"; 43 | if (XposedHelpers.findClassIfExists(playlistBannerContainerClassString, context.getClassLoader()) != null) 44 | XposedHelpers.findAndHookConstructor(playlistBannerContainerClassString, context.getClassLoader(), Context.class, AttributeSet.class, new XC_MethodHook() { 45 | @Override 46 | protected void beforeHookedMethod(MethodHookParam param) { 47 | final View view = (View) param.thisObject; 48 | view.post(() -> { 49 | ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); 50 | layoutParams.height = 0; 51 | view.setLayoutParams(layoutParams); 52 | view.setVisibility(View.GONE); 53 | }); 54 | } 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/HideBubbleHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | 10 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 11 | import static de.robv.android.xposed.XposedHelpers.findClassIfExists; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2020/05/23
18 |  *     desc   : 隐藏小红点
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | public class HideBubbleHook { 23 | public HideBubbleHook(Context context) { 24 | if (!SettingHelper.getInstance().isEnable(SettingHelper.beauty_bubble_hide_key)) 25 | return; 26 | final Class messageBubbleView = findClassIfExists("com.netease.cloudmusic.ui.MessageBubbleView", context.getClassLoader()); 27 | final Class messageBubbleView_800 = findClassIfExists("com.netease.cloudmusic.theme.ui.MessageBubbleView", context.getClassLoader()); 28 | findAndHookMethod(View.class, "setVisibility", int.class, new XC_MethodHook() { 29 | @Override 30 | protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) { 31 | if ((messageBubbleView != null && param.thisObject.getClass() == messageBubbleView) || (messageBubbleView_800 != null && param.thisObject.getClass() == messageBubbleView_800)) { 32 | param.args[0] = View.GONE; 33 | } 34 | } 35 | }); 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/HideTabHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.raincat.dolby_beta.helper.ClassHelper; 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | 9 | import java.lang.reflect.Method; 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | import de.robv.android.xposed.XC_MethodHook; 15 | 16 | import static de.robv.android.xposed.XposedBridge.hookMethod; 17 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 18 | 19 | /** 20 | *
21 |  *     author : RainCat
22 |  *     time   : 2019/12/21
23 |  *     desc   : 隐藏头部hook
24 |  *     version: 1.0
25 |  * 
26 | */ 27 | 28 | public class HideTabHook { 29 | public HideTabHook(Context context, int versionCode) { 30 | if (!SettingHelper.getInstance().isEnable(SettingHelper.beauty_tab_hide_key) || versionCode < 138) 31 | return; 32 | 33 | List setTabItemMethods = ClassHelper.MainActivitySuperClass.getTabItemStringMethods(context); 34 | if (setTabItemMethods != null && setTabItemMethods.size() != 0) { 35 | for (Method method : setTabItemMethods) { 36 | hookMethod(method, new XC_MethodHook() { 37 | @Override 38 | protected void beforeHookedMethod(final MethodHookParam param) { 39 | if (param.args[0] == null || ((String[]) param.args[0]).length < 2) 40 | return; 41 | String[] tabNames = (String[]) param.args[0]; 42 | String tabName = Arrays.toString(tabNames); 43 | if ((tabName.contains("我的") && tabName.contains("发现")) || (tabName.contains("mine") && tabName.contains("main"))) { 44 | String[] strings = new String[2]; 45 | System.arraycopy(tabNames, 0, strings, 0, 2); 46 | param.args[0] = strings; 47 | } 48 | } 49 | }); 50 | } 51 | 52 | hookMethod(ClassHelper.MainActivitySuperClass.getViewPagerInitMethod(context), new XC_MethodHook() { 53 | @Override 54 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 55 | super.beforeHookedMethod(param); 56 | Intent intent = (Intent) param.args[0]; 57 | intent.putExtra("SELECT_PAGE_INDEX", 0); 58 | } 59 | }); 60 | } 61 | 62 | if (versionCode >= 8000010) { 63 | Class bottomTabViewClass = ClassHelper.BottomTabView.getClazz(context); 64 | if (bottomTabViewClass != null) { 65 | findAndHookMethod(bottomTabViewClass, ClassHelper.BottomTabView.getTabInitMethod(context).getName(), new XC_MethodHook() { 66 | @Override 67 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 68 | super.afterHookedMethod(param); 69 | List list = new ArrayList<>(); 70 | list.add("mine"); 71 | list.add("main"); 72 | list.add("follow"); 73 | param.setResult(list); 74 | } 75 | }); 76 | 77 | findAndHookMethod(bottomTabViewClass, ClassHelper.BottomTabView.getTabRefreshMethod(context).getName(), List.class, new XC_MethodHook() { 78 | @Override 79 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 80 | super.beforeHookedMethod(param); 81 | List list = new ArrayList<>(); 82 | list.add("mine"); 83 | list.add("main"); 84 | list.add("follow"); 85 | param.args[0] = list; 86 | } 87 | }); 88 | } 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/InternalDialogHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | import android.content.Context; 3 | 4 | import de.robv.android.xposed.XC_MethodHook; 5 | import de.robv.android.xposed.XposedBridge; 6 | 7 | import static de.robv.android.xposed.XposedHelpers.findClassIfExists; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     time   : 2019/12/11
13 |  *     desc   : 内测与听歌识曲弹窗
14 |  *     version: 1.0
15 |  * 
16 | */ 17 | 18 | public class InternalDialogHook { 19 | public InternalDialogHook(Context context, int versionCode) { 20 | if (versionCode < 138) 21 | return; 22 | 23 | Class materialDialogHelperClass = findClassIfExists("com.netease.cloudmusic.ui.MaterialDiloagCommon.MaterialDialogHelper", context.getClassLoader()); 24 | if (materialDialogHelperClass != null) { 25 | XposedBridge.hookAllMethods(materialDialogHelperClass, "materialDialog", new XC_MethodHook() { 26 | @Override 27 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 28 | super.beforeHookedMethod(param); 29 | if (param.args[0].getClass().getName().contains("MainActivity")||param.args[0].getClass().getName().contains("IdentifyActivity")) 30 | param.setResult(null); 31 | } 32 | }); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/ListentogetherHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import de.robv.android.xposed.XC_MethodReplacement; 5 | 6 | 7 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 8 | import static de.robv.android.xposed.XposedHelpers.findClass; 9 | 10 | 11 | public class ListentogetherHook { 12 | public ListentogetherHook(Context context, int versionCode) { 13 | if (versionCode > 8007090) { 14 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.f2", context.getClassLoader()), 15 | "v", XC_MethodReplacement.returnConstant(true)); 16 | }else if (versionCode > 8007075) { 17 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.x", context.getClassLoader()), 18 | "v", XC_MethodReplacement.returnConstant(true)); 19 | }else if (versionCode > 8007070) { 20 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.y", context.getClassLoader()), 21 | "u", XC_MethodReplacement.returnConstant(true)); 22 | }else if (versionCode > 8007055) { 23 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.x", context.getClassLoader()), 24 | "u", XC_MethodReplacement.returnConstant(true)); 25 | }else if (versionCode > 8007026) { 26 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.w", context.getClassLoader()), 27 | "o", XC_MethodReplacement.returnConstant(true)); 28 | }else if (versionCode > 8007004) { 29 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.w", context.getClassLoader()), 30 | "n", XC_MethodReplacement.returnConstant(true)); 31 | }else if (versionCode > 8006076) { 32 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.u", context.getClassLoader()), 33 | "m", XC_MethodReplacement.returnConstant(true)); 34 | }else if (versionCode > 8006045) { 35 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.r", context.getClassLoader()), 36 | "l1", XC_MethodReplacement.returnConstant(true)); 37 | }else if (versionCode > 8006040) { 38 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.p", context.getClassLoader()), 39 | "h1", XC_MethodReplacement.returnConstant(true)); 40 | }else if (versionCode > 8006019) { 41 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.x", context.getClassLoader()), 42 | "n1", XC_MethodReplacement.returnConstant(true)); 43 | }else if (versionCode >= 8006000){ 44 | findAndHookMethod(findClass("com.netease.cloudmusic.module.listentogether.x", context.getClassLoader()), 45 | "m1", XC_MethodReplacement.returnConstant(true)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/LoginFixHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodHook; 6 | import de.robv.android.xposed.XposedHelpers; 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     e-mail : nining377@gmail.com
12 |  *     time   : 2022/05/03
13 |  *     desc   : 修复登录
14 |  *     version: 1.0
15 |  * 
16 | */ 17 | 18 | public class LoginFixHook { 19 | public LoginFixHook(Context context) { 20 | Class neteaseMusicUtilsClass = XposedHelpers.findClassIfExists("com.netease.cloudmusic.utils.NeteaseMusicUtils", context.getClassLoader()); 21 | if (neteaseMusicUtilsClass != null) { 22 | XposedHelpers.findAndHookMethod(neteaseMusicUtilsClass, "serialdata", String.class, String.class, new XC_MethodHook() { 23 | @Override 24 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 25 | super.beforeHookedMethod(param); 26 | if (param.args[0].equals("/api/login/cellphone") 27 | || param.args[0].equals("/api/login") 28 | || param.args[0].equals("/api/login/sns")) { 29 | if (((String) param.args[1]).contains("\"checkToken\":\"\"")) { 30 | Class watchmanClass = XposedHelpers.findClassIfExists("com.netease.mobsecurity.rjsb.watchman", context.getClassLoader()); 31 | if (watchmanClass == null) 32 | watchmanClass = XposedHelpers.findClassIfExists("com.netease.mobsec.rjsb.watchman", context.getClassLoader()); 33 | if (watchmanClass != null) { 34 | XposedHelpers.callStaticMethod(watchmanClass, "init", context, "YD00000558929251"); 35 | String checkToken = (String) XposedHelpers.callStaticMethod(watchmanClass, "getToken", "30b0cdd23ed1144a0b78de049edc09824", 500, 2); 36 | param.args[1] = ((String) param.args[1]).replaceAll("\"checkToken\":\"\"", "\"checkToken\":\"" + checkToken + "\""); 37 | } 38 | } 39 | } 40 | } 41 | }); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/MagiskFixHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | import android.os.storage.StorageManager; 6 | 7 | import com.annimon.stream.Stream; 8 | 9 | import java.lang.reflect.Method; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import de.robv.android.xposed.XC_MethodHook; 14 | import de.robv.android.xposed.XposedBridge; 15 | import de.robv.android.xposed.XposedHelpers; 16 | 17 | public class MagiskFixHook { 18 | public MagiskFixHook(Context context) { 19 | Method[] methods = XposedHelpers.findMethodsByExactParameters( 20 | XposedHelpers.findClass("com.netease.cloudmusic.utils.NeteaseMusicUtils", context.getClassLoader()), List.class, boolean.class); 21 | Method method = Stream.of(methods).sortBy(Method::getName).findFirst().get(); 22 | XposedBridge.hookMethod(method, new XC_MethodHook() { 23 | @Override 24 | protected void beforeHookedMethod(MethodHookParam param) { 25 | List list = new ArrayList<>(); 26 | list.add(Environment.getExternalStorageDirectory().getAbsolutePath()); 27 | 28 | //外置卡 29 | String sdCard = getSecondaryStoragePath(context); 30 | if (sdCard != null) { 31 | String state = getStorageState(context, sdCard); 32 | if (state.contains(Environment.MEDIA_MOUNTED)) 33 | list.add(sdCard); 34 | } 35 | param.setResult(list); 36 | } 37 | }); 38 | } 39 | 40 | // 获取主存储卡路径(不要根据系统推荐改黄色的东西!) 41 | public String getPrimaryStoragePath(Context context) { 42 | try { 43 | StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 44 | Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths"); 45 | String[] paths = (String[]) getVolumePathsMethod.invoke(sm); 46 | return paths[0]; 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | return null; 50 | } 51 | } 52 | 53 | // 获取次存储卡路径,一般就是外置 TF 卡了. 不过也有可能是 USB OTG (Environment.MEDIA_MOUNTED_READ_ONLY),OTG为只读 54 | public String getSecondaryStoragePath(Context context) { 55 | try { 56 | StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 57 | Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths"); 58 | String[] paths = (String[]) getVolumePathsMethod.invoke(sm); 59 | return (paths == null || paths.length <= 1) ? null : paths[1]; 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | return null; 63 | } 64 | } 65 | 66 | // 获取存储卡的挂载状态. path 参数传入上两个方法得到的路径 67 | public String getStorageState(Context context, String path) { 68 | try { 69 | StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 70 | Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", String.class); 71 | return (String) getVolumeStateMethod.invoke(sm, path); 72 | } catch (Exception e) { 73 | e.printStackTrace(); 74 | return null; 75 | } 76 | } 77 | } 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/NightModeHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.content.res.Configuration; 5 | import android.util.Pair; 6 | 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | 9 | import de.robv.android.xposed.XC_MethodHook; 10 | import de.robv.android.xposed.XposedHelpers; 11 | 12 | import static de.robv.android.xposed.XposedHelpers.findClass; 13 | 14 | /** 15 | *
16 |  *     author : RainCat
17 |  *     e-mail : nining377@gmail.com
18 |  *     time   : 2021/12/03
19 |  *     desc   : 夜间模式
20 |  *     version: 1.0
21 |  * 
22 | */ 23 | 24 | public class NightModeHook { 25 | private String resourceRouterInstanceMethodString = "getInstance"; 26 | private String resourceRouterIsNightThemeMethodString = "isNightTheme"; 27 | private String themeAgentInstanceMethodString = "getInstance"; 28 | private String themeAgentSwitchTheme = "switchTheme"; 29 | 30 | public NightModeHook(Context context, int versionCode) { 31 | if (!SettingHelper.getInstance().isEnable(SettingHelper.beauty_night_mode_key)) 32 | return; 33 | Class superActivityClass = findClass("com.netease.cloudmusic.activity.MainActivity", context.getClassLoader()); 34 | while (superActivityClass != null && !superActivityClass.getName().contains("AppCompatActivity")) 35 | superActivityClass = superActivityClass.getSuperclass(); 36 | 37 | String resourceRouterClassString = "com.netease.cloudmusic.theme.core.ResourceRouter"; 38 | String themeAgentClassString = "com.netease.cloudmusic.theme.core.ThemeAgent"; 39 | String themeConfigClassString = "com.netease.cloudmusic.theme.core.ThemeConfig"; 40 | String themeInfoClassString = "com.netease.cloudmusic.theme.core.ThemeInfo"; 41 | 42 | if (versionCode == 110) { 43 | resourceRouterClassString = "com.netease.cloudmusic.theme.core.b"; 44 | themeAgentClassString = "com.netease.cloudmusic.theme.core.c"; 45 | themeConfigClassString = "com.netease.cloudmusic.theme.core.f"; 46 | resourceRouterInstanceMethodString = "a"; 47 | resourceRouterIsNightThemeMethodString = "d"; 48 | themeAgentInstanceMethodString = "a"; 49 | themeAgentSwitchTheme = "a"; 50 | } 51 | 52 | final Class resourceRouterClass = XposedHelpers.findClassIfExists(resourceRouterClassString, context.getClassLoader()); 53 | final Class themeAgentClass = XposedHelpers.findClassIfExists(themeAgentClassString, context.getClassLoader()); 54 | final Class themeConfigClass = XposedHelpers.findClassIfExists(themeConfigClassString, context.getClassLoader()); 55 | final Class themeInfoClass = XposedHelpers.findClassIfExists(themeInfoClassString, context.getClassLoader()); 56 | 57 | XposedHelpers.findAndHookMethod(superActivityClass, "onStart", new XC_MethodHook() { 58 | @Override 59 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 60 | super.afterHookedMethod(param); 61 | Context c = (Context) param.thisObject; 62 | Object resourceRouter = XposedHelpers.callStaticMethod(resourceRouterClass, resourceRouterInstanceMethodString); 63 | boolean isNight = (boolean) XposedHelpers.callMethod(resourceRouter, resourceRouterIsNightThemeMethodString); 64 | int nightModeFlags = c.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; 65 | if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES && !isNight) { 66 | Object themeAgent = XposedHelpers.callStaticMethod(themeAgentClass, themeAgentInstanceMethodString); 67 | Object themeInfo = XposedHelpers.newInstance(themeInfoClass, -3); 68 | XposedHelpers.callMethod(themeAgent, themeAgentSwitchTheme, c, themeInfo, true); 69 | } else if (nightModeFlags == Configuration.UI_MODE_NIGHT_NO && isNight) { 70 | Object themeAgent = XposedHelpers.callStaticMethod(themeAgentClass, themeAgentInstanceMethodString); 71 | if (versionCode == 110) { 72 | int prevThemeInfo = (int) XposedHelpers.callStaticMethod(themeConfigClass, "m"); 73 | Object themeInfo = XposedHelpers.newInstance(themeInfoClass, prevThemeInfo); 74 | XposedHelpers.callMethod(themeAgent, themeAgentSwitchTheme, c, themeInfo, true); 75 | } else { 76 | Pair prevThemeInfo = (Pair) XposedHelpers.callStaticMethod(themeConfigClass, "getPrevThemeInfo"); 77 | Object themeInfo = XposedHelpers.newInstance(themeInfoClass, prevThemeInfo.first); 78 | XposedHelpers.callMethod(themeAgent, themeAgentSwitchTheme, c, themeInfo, true); 79 | } 80 | } 81 | } 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/TestHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | *
 7 |  *     author : RainCat
 8 |  *     e-mail : nining377@gmail.com
 9 |  *     time   : 2019/10/24
10 |  *     desc   : 测试
11 |  *     version: 1.0
12 |  * 
13 | */ 14 | 15 | public class TestHook { 16 | public TestHook(Context context) { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/hook/UserProfileHook.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.hook; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | 6 | import com.raincat.dolby_beta.helper.ClassHelper; 7 | import com.raincat.dolby_beta.helper.ExtraHelper; 8 | import com.raincat.dolby_beta.helper.UserHelper; 9 | 10 | import de.robv.android.xposed.XC_MethodHook; 11 | import de.robv.android.xposed.XposedHelpers; 12 | 13 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 14 | import static de.robv.android.xposed.XposedHelpers.findClassIfExists; 15 | 16 | /** 17 | *
18 |  *     author : RainCat
19 |  *     e-mail : nining377@gmail.com
20 |  *     time   : 2021/04/17
21 |  *     desc   : 获取账号信息
22 |  *     version: 1.0
23 |  * 
24 | */ 25 | 26 | public class UserProfileHook { 27 | public UserProfileHook(Context context) { 28 | //获取用户id 29 | Class userProfileClass = findClassIfExists("com.netease.cloudmusic.meta.Profile", context.getClassLoader()); 30 | if (userProfileClass != null) { 31 | findAndHookMethod(userProfileClass, "setNickname", String.class, new XC_MethodHook() { 32 | @Override 33 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 34 | super.afterHookedMethod(param); 35 | String nickName = (String) param.args[0]; 36 | if (nickName.equals("未登录") || nickName.length() == 0) 37 | return; 38 | if ((boolean) XposedHelpers.callMethod(param.thisObject, "isMe") && ExtraHelper.getExtraDate(ExtraHelper.USER_ID).equals("-1")) 39 | ExtraHelper.setExtraDate(ExtraHelper.USER_ID, XposedHelpers.callMethod(param.thisObject, "getUserId")); 40 | } 41 | }); 42 | } 43 | 44 | Class mainActivityClass = findClassIfExists("com.netease.cloudmusic.activity.MainActivity", context.getClassLoader()); 45 | if (mainActivityClass != null) { 46 | findAndHookMethod(mainActivityClass, "onResume", new XC_MethodHook() { 47 | @Override 48 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 49 | super.afterHookedMethod(param); 50 | new Thread(() -> { 51 | if (ExtraHelper.getExtraDate(ExtraHelper.COOKIE).equals("-1")) 52 | ExtraHelper.setExtraDate(ExtraHelper.COOKIE, ClassHelper.Cookie.getCookie(context)); 53 | if (ExtraHelper.getExtraDate(ExtraHelper.USER_ID).equals("-1")) 54 | UserHelper.getUserInfo(); 55 | }).start(); 56 | } 57 | }); 58 | } 59 | 60 | //登录页被创建的时候说明用户数据需要被刷新 61 | Class loginActivityClass = findClassIfExists("com.netease.cloudmusic.activity.LoginActivity", context.getClassLoader()); 62 | if (loginActivityClass != null) { 63 | findAndHookMethod(loginActivityClass, "onCreate", Bundle.class, new XC_MethodHook() { 64 | @Override 65 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 66 | super.afterHookedMethod(param); 67 | ExtraHelper.cleanUserData(); 68 | } 69 | }); 70 | } 71 | 72 | //获取我喜欢的歌单id 73 | Class playListClass = findClassIfExists("com.netease.cloudmusic.meta.PlayList", context.getClassLoader()); 74 | if (playListClass != null) { 75 | findAndHookMethod(playListClass, "setSpecialType", int.class, new XC_MethodHook() { 76 | @Override 77 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 78 | super.afterHookedMethod(param); 79 | if ((int) param.args[0] == 5 && ExtraHelper.getExtraDate(ExtraHelper.LOVE_PLAY_LIST).equals("-1")) 80 | ExtraHelper.setExtraDate(ExtraHelper.LOVE_PLAY_LIST, XposedHelpers.callMethod(param.thisObject, "getId")); 81 | } 82 | }); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/CloudHeader.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | *
 7 |  *     author : RainCat
 8 |  *     e-mail : nining377@gmail.com
 9 |  *     time   : 2020/03/24
10 |  *     desc   : 上传云盘的请求头
11 |  *     version: 1.0
12 |  * 
13 | */ 14 | public class CloudHeader { 15 | private String os; 16 | private String appver; 17 | private String deviceId; 18 | private String requestId; 19 | private String clientSign; 20 | private String osver; 21 | @SerializedName("batch-method") 22 | private String batchmethod; 23 | private String MUSIC_U; 24 | 25 | public String getOs() { 26 | return os; 27 | } 28 | 29 | public void setOs(String os) { 30 | this.os = os; 31 | } 32 | 33 | public String getAppver() { 34 | return appver; 35 | } 36 | 37 | public void setAppver(String appver) { 38 | this.appver = appver; 39 | } 40 | 41 | public String getDeviceId() { 42 | return deviceId; 43 | } 44 | 45 | public void setDeviceId(String deviceId) { 46 | this.deviceId = deviceId; 47 | } 48 | 49 | public String getRequestId() { 50 | return requestId; 51 | } 52 | 53 | public void setRequestId(String requestId) { 54 | this.requestId = requestId; 55 | } 56 | 57 | public String getClientSign() { 58 | return clientSign; 59 | } 60 | 61 | public void setClientSign(String clientSign) { 62 | this.clientSign = clientSign; 63 | } 64 | 65 | public String getOsver() { 66 | return osver; 67 | } 68 | 69 | public void setOsver(String osver) { 70 | this.osver = osver; 71 | } 72 | 73 | public String getBatchmethod() { 74 | return batchmethod; 75 | } 76 | 77 | public void setBatchmethod(String batchmethod) { 78 | this.batchmethod = batchmethod; 79 | } 80 | 81 | public String getMUSIC_U() { 82 | return MUSIC_U; 83 | } 84 | 85 | public void setMUSIC_U(String MUSIC_U) { 86 | this.MUSIC_U = MUSIC_U; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/DailyRecommendListBean.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | *
 8 |  *     author : RainCat
 9 |  *     time   : 2020/04/15
10 |  *     desc   : 每日推荐歌单
11 |  *     version: 1.0
12 |  * 
13 | */ 14 | public class DailyRecommendListBean { 15 | private List recommend; 16 | 17 | public List getRecommend() { 18 | if (recommend == null) 19 | recommend = new ArrayList<>(); 20 | return recommend; 21 | } 22 | 23 | public void setRecommend(List recommend) { 24 | this.recommend = recommend; 25 | } 26 | 27 | public static class RecommendBean { 28 | private long id = 0L; 29 | private String name = ""; 30 | 31 | public long getId() { 32 | return id; 33 | } 34 | 35 | public void setId(long id) { 36 | this.id = id; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/NeteaseSongListBean.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | *
  8 |  *     author : RainCat
  9 |  *     e-mail : nining377@gmail.com
 10 |  *     time   : 2019/10/23
 11 |  *     desc   : 网易云返回的歌曲信息
 12 |  *     version: 1.0
 13 |  * 
14 | */ 15 | 16 | public class NeteaseSongListBean { 17 | private int code; 18 | private List data; 19 | 20 | public int getCode() { 21 | return code; 22 | } 23 | 24 | public void setCode(int code) { 25 | this.code = code; 26 | } 27 | 28 | public List getData() { 29 | if (data == null) 30 | data = new ArrayList<>(); 31 | return data; 32 | } 33 | 34 | public void setData(List data) { 35 | this.data = data; 36 | } 37 | 38 | public static class DataBean { 39 | private long id; 40 | private String url; 41 | private int br; 42 | private int size; 43 | private String md5; 44 | private int code; 45 | private int expi; 46 | private String type; 47 | private float gain; 48 | private int fee; 49 | private Object uf; 50 | private int payed; 51 | private int flag; 52 | private boolean canExtend; 53 | private FreeTrialInfoBean freeTrialInfo; 54 | private String level; 55 | private String encodeType; 56 | private int peak; 57 | private int time; 58 | 59 | public long getId() { 60 | return id; 61 | } 62 | 63 | public void setId(long id) { 64 | this.id = id; 65 | } 66 | 67 | public String getUrl() { 68 | return url; 69 | } 70 | 71 | public void setUrl(String url) { 72 | this.url = url; 73 | } 74 | 75 | public int getBr() { 76 | return br; 77 | } 78 | 79 | public void setBr(int br) { 80 | this.br = br; 81 | } 82 | 83 | public int getSize() { 84 | return size; 85 | } 86 | 87 | public void setSize(int size) { 88 | this.size = size; 89 | } 90 | 91 | public String getMd5() { 92 | return md5; 93 | } 94 | 95 | public void setMd5(String md5) { 96 | this.md5 = md5; 97 | } 98 | 99 | public int getCode() { 100 | return code; 101 | } 102 | 103 | public void setCode(int code) { 104 | this.code = code; 105 | } 106 | 107 | public int getExpi() { 108 | return expi; 109 | } 110 | 111 | public void setExpi(int expi) { 112 | this.expi = expi; 113 | } 114 | 115 | public String getType() { 116 | return type; 117 | } 118 | 119 | public void setType(String type) { 120 | this.type = type; 121 | } 122 | 123 | public float getGain() { 124 | return gain; 125 | } 126 | 127 | public void setGain(float gain) { 128 | this.gain = gain; 129 | } 130 | 131 | public int getFee() { 132 | return fee; 133 | } 134 | 135 | public void setFee(int fee) { 136 | this.fee = fee; 137 | } 138 | 139 | public Object getUf() { 140 | return uf; 141 | } 142 | 143 | public void setUf(Object uf) { 144 | this.uf = uf; 145 | } 146 | 147 | public int getPayed() { 148 | return payed; 149 | } 150 | 151 | public void setPayed(int payed) { 152 | this.payed = payed; 153 | } 154 | 155 | public int getFlag() { 156 | return flag; 157 | } 158 | 159 | public void setFlag(int flag) { 160 | this.flag = flag; 161 | } 162 | 163 | public boolean isCanExtend() { 164 | return canExtend; 165 | } 166 | 167 | public void setCanExtend(boolean canExtend) { 168 | this.canExtend = canExtend; 169 | } 170 | 171 | public FreeTrialInfoBean getFreeTrialInfo() { 172 | return freeTrialInfo; 173 | } 174 | 175 | public void setFreeTrialInfo(FreeTrialInfoBean freeTrialInfo) { 176 | this.freeTrialInfo = freeTrialInfo; 177 | } 178 | 179 | public String getLevel() { 180 | return level; 181 | } 182 | 183 | public void setLevel(String level) { 184 | this.level = level; 185 | } 186 | 187 | public String getEncodeType() { 188 | return encodeType; 189 | } 190 | 191 | public void setEncodeType(String encodeType) { 192 | this.encodeType = encodeType; 193 | } 194 | 195 | public int getPeak() { 196 | return peak; 197 | } 198 | 199 | public void setPeak(int peak) { 200 | this.peak = peak; 201 | } 202 | 203 | public int getTime() { 204 | return time; 205 | } 206 | 207 | public void setTime(int time) { 208 | this.time = time; 209 | } 210 | 211 | public static class FreeTrialInfoBean { 212 | private int start; 213 | private int end; 214 | 215 | public int getStart() { 216 | return start; 217 | } 218 | 219 | public void setStart(int start) { 220 | this.start = start; 221 | } 222 | 223 | public int getEnd() { 224 | return end; 225 | } 226 | 227 | public void setEnd(int end) { 228 | this.end = end; 229 | } 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/PlaylistDetailBean.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | *
 8 |  *     author : RainCat
 9 |  *     time   : 2020/04/15
10 |  *     desc   : 播放列表bean
11 |  *     version: 1.0
12 |  * 
13 | */ 14 | public class PlaylistDetailBean { 15 | private PlaylistBean playlist; 16 | 17 | public PlaylistBean getPlaylist() { 18 | if (playlist == null) 19 | playlist = new PlaylistBean(); 20 | return playlist; 21 | } 22 | 23 | public void setPlaylist(PlaylistBean playlist) { 24 | this.playlist = playlist; 25 | } 26 | 27 | public static class PlaylistBean { 28 | private long id = 0L; 29 | private List trackIds; 30 | 31 | public long getId() { 32 | return id; 33 | } 34 | 35 | public void setId(long id) { 36 | this.id = id; 37 | } 38 | 39 | public List getTrackIds() { 40 | if (trackIds == null) 41 | trackIds = new ArrayList<>(); 42 | return trackIds; 43 | } 44 | 45 | public void setTrackIds(List trackIds) { 46 | this.trackIds = trackIds; 47 | } 48 | 49 | public static class TrackIdsBean { 50 | private long id = 0L; 51 | 52 | public long getId() { 53 | return id; 54 | } 55 | 56 | public void setId(long id) { 57 | this.id = id; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/SidebarEnum.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | *
 9 |  *     author : RainCat
10 |  *     e-mail : nining377@gmail.com
11 |  *     time   : 2021/10/22
12 |  *     desc   : 侧边栏枚举
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | 17 | public class SidebarEnum { 18 | //所有枚举Map 19 | private static LinkedHashMap enumMap; 20 | //当前版本枚举Map 21 | private static LinkedHashMap sidebarMap; 22 | 23 | public static void setSidebarEnum(Object[] objectList) { 24 | sidebarMap = new LinkedHashMap<>(); 25 | HashMap tempMap = new HashMap<>(); 26 | for (Object object : objectList) { 27 | tempMap.put(object.toString(), object.toString()); 28 | } 29 | for (Map.Entry entry : enumMap.entrySet()) { 30 | if (tempMap.get(entry.getKey()) != null) { 31 | sidebarMap.put(entry.getKey(), entry.getValue()); 32 | tempMap.remove(entry.getKey()); 33 | } 34 | } 35 | if (tempMap.size() != 0) { 36 | for (String key : tempMap.values()) { 37 | if (key.equals("SETTING") || key.equals("DYNAMIC_ITEM") || key.equals("PROFILE") || key.equals("CHILD_MODE") || 38 | key.equals("CLASSICAL") || key.equals("AVATAR") || key.equals("DYNAMIC_CONTAINER") || key.equals("SMALL_ICE")) 39 | continue; 40 | if (key.equals("GROUP")) { 41 | sidebarMap.put(key + "1", "音乐服务(组)"); 42 | sidebarMap.put(key + "2", "其他(组)"); 43 | } else 44 | sidebarMap.put(key, ""); 45 | } 46 | } 47 | } 48 | 49 | public static LinkedHashMap getSidebarEnum() { 50 | return sidebarMap; 51 | } 52 | 53 | static { 54 | enumMap = new LinkedHashMap<>(); 55 | enumMap.put("LOGIN", "登录"); 56 | enumMap.put("MESSAGE", "我的消息"); 57 | enumMap.put("VIP", "我的会员"); 58 | enumMap.put("CLOUD_SHELL_CENTER", "云贝中心"); 59 | enumMap.put("MUSICIAN", "音乐人中心"); 60 | enumMap.put("CREATOR_CENTER", "创作者中心"); 61 | enumMap.put("MUSICIAN_CREATOR_CENTER", "创作者中心"); 62 | enumMap.put("MUSICIAN_VIEWER", "加入网易音乐人"); 63 | enumMap.put("TICKET", "云村有票"); 64 | enumMap.put("NEARBY", "附近的人"); 65 | enumMap.put("STORE", "商城"); 66 | enumMap.put("BEAT", "Beat交易平台"); 67 | enumMap.put("GAME", "游戏专区"); 68 | enumMap.put("COLOR_RING", "口袋彩铃"); 69 | enumMap.put("SETTING", "设置"); 70 | enumMap.put("NIGHT_THEME_MODE", "夜间模式"); 71 | enumMap.put("CLOCK_PLAY", "定时停止播放"); 72 | enumMap.put("THEME", "个性装扮"); 73 | enumMap.put("IDENTIFY", "听歌识曲"); 74 | enumMap.put("SCAN", "扫一扫"); 75 | enumMap.put("CACHE_WHILE_LISTEN", "边听边存"); 76 | enumMap.put("FREE", "在线听歌免流量"); 77 | enumMap.put("MUSIC_BLACKLIST", "音乐黑名单"); 78 | enumMap.put("PRIVATE_CLOUD", "音乐云盘"); 79 | enumMap.put("YOUTH_MODE", "青少年模式"); 80 | enumMap.put("ALARM_CLOCK", "音乐闹钟"); 81 | enumMap.put("MY_ORDER", "我的订单"); 82 | enumMap.put("MY_FRIEND", "我的好友"); 83 | enumMap.put("VEHICLE_PLAYER", "驾驶模式"); 84 | enumMap.put("DISCOUNT_COUPON", "优惠券"); 85 | enumMap.put("RED_PACKET", "音乐红包"); 86 | enumMap.put("PROFIT", "赞赏收入"); 87 | enumMap.put("DYNAMIC_ITEM", "第三方隐私协议"); 88 | enumMap.put("FEEDBACK_HELP", "帮助与反馈"); 89 | enumMap.put("SHARE_APP", "分享网易云音乐"); 90 | enumMap.put("ABOUT", "关于"); 91 | enumMap.put("LOGOUT", "登出"); 92 | enumMap.put("DIV1", "分割线1"); 93 | enumMap.put("DIV2", "分割线2"); 94 | enumMap.put("DIV3", "分割线3"); 95 | enumMap.put("DIV4", "分割线4"); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/model/UserInfoBean.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.model; 2 | 3 | /** 4 | *
 5 |  *     author : RainCat
 6 |  *     e-mail : nining377@gmail.com
 7 |  *     time   : 2021/09/03
 8 |  *     desc   : 用户信息
 9 |  *     version: 1.0
10 |  * 
11 | */ 12 | 13 | public class UserInfoBean { 14 | private int code; 15 | private ProfileBean profile; 16 | 17 | public int getCode() { 18 | return code; 19 | } 20 | 21 | public void setCode(int code) { 22 | this.code = code; 23 | } 24 | 25 | public ProfileBean getProfile() { 26 | if (profile == null) 27 | profile = new ProfileBean(); 28 | return profile; 29 | } 30 | 31 | public void setProfile(ProfileBean profile) { 32 | this.profile = profile; 33 | } 34 | 35 | public static class ProfileBean { 36 | private long userId = -1; 37 | private int userType = 0; 38 | private String nickname = ""; 39 | 40 | public long getUserId() { 41 | return userId; 42 | } 43 | 44 | public void setUserId(long userId) { 45 | this.userId = userId; 46 | } 47 | 48 | public int getUserType() { 49 | return userType; 50 | } 51 | 52 | public void setUserType(int userType) { 53 | this.userType = userType; 54 | } 55 | 56 | public String getNickname() { 57 | return nickname; 58 | } 59 | 60 | public void setNickname(String nickname) { 61 | this.nickname = nickname; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/net/HTTPSTrustManager.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.net; 2 | 3 | import java.security.KeyManagementException; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.security.SecureRandom; 6 | import java.security.cert.X509Certificate; 7 | 8 | import javax.net.ssl.HttpsURLConnection; 9 | import javax.net.ssl.SSLContext; 10 | import javax.net.ssl.TrustManager; 11 | import javax.net.ssl.X509TrustManager; 12 | 13 | public class HTTPSTrustManager implements X509TrustManager { 14 | private static TrustManager[] trustManagers; 15 | private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{}; 16 | 17 | @Override 18 | public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException { 19 | } 20 | 21 | @Override 22 | public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException { 23 | } 24 | 25 | @Override 26 | public X509Certificate[] getAcceptedIssuers() { 27 | return _AcceptedIssuers; 28 | } 29 | 30 | public static void allowAllSSL() { 31 | HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true); 32 | 33 | SSLContext context = null; 34 | if (trustManagers == null) { 35 | trustManagers = new TrustManager[]{new HTTPSTrustManager()}; 36 | } 37 | 38 | try { 39 | context = SSLContext.getInstance("TLS"); 40 | context.init(null, trustManagers, new SecureRandom()); 41 | } catch (NoSuchAlgorithmException | KeyManagementException e) { 42 | e.printStackTrace(); 43 | } 44 | HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/net/Request.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.net; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 请求封装 7 | * Created by Administrator on 2018/3/29 0029. 8 | */ 9 | 10 | class Request { 11 | String method = ""; 12 | String url = ""; 13 | String param = ""; 14 | HashMap header = new HashMap<>(); 15 | 16 | int reTry = 0; 17 | int timeout = 10000; 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/utils/LogUtils.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.utils; 2 | 3 | import com.raincat.dolby_beta.BuildConfig; 4 | 5 | import de.robv.android.xposed.XposedBridge; 6 | 7 | /** 8 | *
 9 |  *     author : RainCat
10 |  *     e-mail : nining377@gmail.com
11 |  *     time   : 2022/06/25
12 |  *     desc   : 日志
13 |  *     version: 1.0
14 |  * 
15 | */ 16 | 17 | public class LogUtils { 18 | public static void log(String text) { 19 | if (BuildConfig.DEBUG) 20 | XposedBridge.log(text); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/utils/NeteaseAES.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.utils; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.spec.IvParameterSpec; 5 | import javax.crypto.spec.SecretKeySpec; 6 | 7 | public class NeteaseAES { 8 | /** 9 | * AES 加密的具体算法为:AES-128-CBC,输出格式为 base64 AES 加密时需要指定 iv:0102030405060708 10 | * 11 | * @param sSrc 加密后的参数值 12 | * @param sKey 随机数值 13 | */ 14 | public static String Encrypt(String sSrc, String sKey) throws Exception { 15 | if (sKey == null) { 16 | System.out.print("Key为空null"); 17 | return null; 18 | } 19 | // 判断Key是否为16位 20 | if (sKey.length() != 16) { 21 | System.out.print("Key长度不是16位"); 22 | return null; 23 | } 24 | byte[] raw = sKey.getBytes(); 25 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 26 | // AES CBC 加密 27 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式" 28 | // 偏移量 29 | IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度 30 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); 31 | byte[] encrypted = cipher.doFinal(sSrc.getBytes()); 32 | 33 | return NeteaseBase64.encode(encrypted);// 此处使用BASE64做转码功能,同时能起到2次加密的作用。 34 | } 35 | 36 | // 解密 37 | public static String Decrypt(String sSrc, String sKey) { 38 | try { 39 | // 判断Key是否正确 40 | if (sKey == null) { 41 | System.out.print("Key为空null"); 42 | return null; 43 | } 44 | // 判断Key是否为16位 45 | if (sKey.length() != 16) { 46 | System.out.print("Key长度不是16位"); 47 | return null; 48 | } 49 | byte[] raw = sKey.getBytes("UTF-8"); 50 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 51 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 52 | IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes()); 53 | cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); 54 | byte[] encrypted1 = NeteaseBase64.decode(sSrc);// 先用base64解密 55 | try { 56 | byte[] original = cipher.doFinal(encrypted1); 57 | return new String(original); 58 | } catch (Exception e) { 59 | System.out.println(e.toString()); 60 | return null; 61 | } 62 | } catch (Exception ex) { 63 | System.out.println(ex.toString()); 64 | return null; 65 | } 66 | } 67 | 68 | public static String get_params(String text) throws Exception { 69 | // 固定的参数值 70 | String first_key = "0CoJUm6Qyw8W8jud"; 71 | // 第二个参数实际上就是一个随机值.随便写一个16位的就可以了 72 | String second_key = "FFFFFFFFFFFFFFFF"; 73 | // AES 密钥需要随机,否则服务器会 dump 掉相同密钥的请求(数量多的话) 74 | // 密钥的形式为 16 位随机字母或数字,[0-9a-zA-Z] 75 | String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 76 | String h_encText = Encrypt(text, first_key); 77 | h_encText = Encrypt(h_encText, second_key); 78 | return h_encText; 79 | } 80 | 81 | /** 82 | * 这里的数其实就是相当于一个常量.因为输入的量都是固定了.所以没有必要进行修改. 83 | */ 84 | public static String get_encSecKey() { 85 | return "257348aecb5e556c066de214e531faadd1c55d814f9be95fd06d6bff9f4c7a41f831f6394d5a3fd2e3881736d94a02ca919d952872e7d0a50ebfa1769a7a62d512f5f1ca21aec60bc3819a9c3ffca5eca9a0dba6d6f7249b06f5965ecfff3695b54e1c28f3f624750ed39e7de08fc8493242e26dbc4484a01c76f739e135637c"; 86 | } 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/utils/NeteaseAES2.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.utils; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.spec.SecretKeySpec; 5 | 6 | /** 7 | *
 8 |  *     author : RainCat
 9 |  *     e-mail : nining377@gmail.com
10 |  *     time   : 2020/03/24
11 |  *     desc   : EAPI加解密
12 |  *     version: 1.0
13 |  * 
14 | */ 15 | public class NeteaseAES2 { 16 | private final static byte[] aesKey = "e82ckenh8dichen8".getBytes(); 17 | 18 | /** 19 | * AES 加密算法为:AES-128-ECB,输出格式为:Hex化字符串 20 | * 21 | * @param sSrc 参数值 22 | */ 23 | public static String Encrypt(String sSrc) { 24 | try { 25 | SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES"); 26 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// "算法/模式/补码方式" 27 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 28 | byte[] encrypted = cipher.doFinal(sSrc.getBytes()); 29 | return byteToHex(encrypted); 30 | } catch (Exception ex) { 31 | return null; 32 | } 33 | } 34 | 35 | /** 36 | * @param sSrc 参数值 37 | */ 38 | // 解密 39 | public static String Decrypt(String sSrc) { 40 | try { 41 | byte[] encrypted = hexToByte(sSrc); 42 | SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES"); 43 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 44 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 45 | byte[] original = cipher.doFinal(encrypted); 46 | return new String(original); 47 | } catch (Exception ex) { 48 | System.out.println(ex.toString()); 49 | return null; 50 | } 51 | } 52 | 53 | /** 54 | * hex转byte数组 55 | */ 56 | public static byte[] hexToByte(String hex) { 57 | int m = 0, n = 0; 58 | int byteLen = hex.length() / 2; // 每两个字符描述一个字节 59 | byte[] ret = new byte[byteLen]; 60 | for (int i = 0; i < byteLen; i++) { 61 | m = i * 2 + 1; 62 | n = m + 1; 63 | int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n)); 64 | ret[i] = (byte) intVal; 65 | } 66 | return ret; 67 | } 68 | 69 | /** 70 | * byte数组转hex 71 | */ 72 | public static String byteToHex(byte[] bytes) { 73 | String strHex = ""; 74 | StringBuilder sb = new StringBuilder(""); 75 | for (byte aByte : bytes) { 76 | strHex = Integer.toHexString(aByte & 0xFF); 77 | sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0 78 | } 79 | return sb.toString().trim().toUpperCase(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/utils/Tools.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.utils; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.Context; 5 | import android.os.Handler; 6 | import android.os.Looper; 7 | import android.widget.Toast; 8 | 9 | import com.stericson.RootShell.exceptions.RootDeniedException; 10 | import com.stericson.RootShell.execution.Command; 11 | import com.stericson.RootTools.RootTools; 12 | 13 | import java.io.IOException; 14 | import java.util.Calendar; 15 | import java.util.Date; 16 | import java.util.concurrent.TimeoutException; 17 | 18 | /** 19 | *
20 |  *     author : RainCat
21 |  *     e-mail : nining377@gmail.com
22 |  *     time   : 2019/09/08
23 |  *     desc   : 工具类
24 |  *     version: 1.0
25 |  * 
26 | */ 27 | 28 | public class Tools { 29 | /** 30 | * 获取线程名称 31 | */ 32 | public static String getCurrentProcessName(Context context) { 33 | int pid = android.os.Process.myPid(); 34 | ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 35 | if (mActivityManager != null) { 36 | for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) { 37 | if (appProcess.pid == pid) { 38 | return appProcess.processName; 39 | } 40 | } 41 | } 42 | return ""; 43 | } 44 | 45 | /** 46 | * 吐司 47 | */ 48 | public static void showToastOnLooper(final Context context, final String message) { 49 | try { 50 | Handler handler = new Handler(Looper.getMainLooper()); 51 | handler.post(() -> Toast.makeText(context, message, Toast.LENGTH_LONG).show()); 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | 57 | /** 58 | * dp2px 59 | */ 60 | public static int dp2px(Context context, float dpValue) { 61 | final float scale = context.getResources().getDisplayMetrics().density; 62 | return (int) (dpValue * scale + 0.5f); 63 | } 64 | 65 | /** 66 | * 获取今天0点的时间戳 67 | */ 68 | public static long getTodayStartTime() { 69 | Calendar calendar = Calendar.getInstance(); 70 | calendar.setTime(new Date()); 71 | calendar.set(Calendar.HOUR_OF_DAY, 0); 72 | calendar.set(Calendar.MINUTE, 0); 73 | calendar.set(Calendar.SECOND, 0); 74 | return calendar.getTime().getTime(); 75 | } 76 | 77 | /** 78 | * ADB命令 79 | */ 80 | public static void shell(Command command) { 81 | try { 82 | RootTools.closeAllShells(); 83 | RootTools.getShell(false).add(command); 84 | } catch (TimeoutException | RootDeniedException | IOException e) { 85 | e.printStackTrace(); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/BaseDialogInputItem.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.text.TextUtils; 6 | import android.util.AttributeSet; 7 | import android.util.TypedValue; 8 | import android.view.Gravity; 9 | import android.view.ViewGroup; 10 | import android.widget.EditText; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | 14 | import com.raincat.dolby_beta.utils.Tools; 15 | 16 | /** 17 | *
 18 |  *     author : RainCat
 19 |  *     e-mail : nining377@gmail.com
 20 |  *     time   : 2021/09/09
 21 |  *     desc   : 控件
 22 |  *     version: 1.0
 23 |  * 
24 | */ 25 | 26 | public class BaseDialogInputItem extends LinearLayout { 27 | private BaseDialogItem item; 28 | private Context context; 29 | 30 | protected TextView titleView, defaultView; 31 | protected EditText editView; 32 | 33 | protected String title, defaultText; 34 | 35 | public BaseDialogInputItem(Context context, AttributeSet attrs, int defStyle) { 36 | this(context, attrs); 37 | } 38 | 39 | public BaseDialogInputItem(Context context, AttributeSet attrs) { 40 | super(context, attrs); 41 | init(context, attrs); 42 | } 43 | 44 | public BaseDialogInputItem(Context context) { 45 | super(context); 46 | init(context, null); 47 | } 48 | 49 | protected void init(Context context, AttributeSet attrs) { 50 | this.context = context; 51 | 52 | int padding = Tools.dp2px(context, 10); 53 | setPadding(padding, 10, padding, 10); 54 | setMinimumHeight(Tools.dp2px(context, 40)); 55 | setOrientation(LinearLayout.HORIZONTAL); 56 | setGravity(Gravity.CENTER_VERTICAL); 57 | 58 | LinearLayout linearLayout = new LinearLayout(context); 59 | linearLayout.setOrientation(LinearLayout.VERTICAL); 60 | addView(linearLayout); 61 | LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f); 62 | linearLayout.setLayoutParams(layoutParams); 63 | 64 | titleView = new TextView(context); 65 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); 66 | titleView.setTextColor(Color.BLACK); 67 | editView = new EditText(context); 68 | editView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); 69 | editView.setTextColor(Color.BLACK); 70 | editView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 71 | linearLayout.addView(titleView); 72 | linearLayout.addView(editView); 73 | defaultView = new TextView(context); 74 | defaultView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); 75 | defaultView.setTextColor(Color.DKGRAY); 76 | defaultView.setText("恢复默认"); 77 | addView(defaultView); 78 | } 79 | 80 | @Override 81 | public void setEnabled(boolean enabled) { 82 | super.setEnabled(enabled); 83 | 84 | if (!enabled) { 85 | titleView.setTextColor(Color.LTGRAY); 86 | editView.setTextColor(Color.LTGRAY); 87 | defaultView.setTextColor(Color.LTGRAY); 88 | } else { 89 | titleView.setTextColor(Color.BLACK); 90 | editView.setTextColor(Color.BLACK); 91 | defaultView.setTextColor(Color.DKGRAY); 92 | } 93 | defaultView.setEnabled(enabled); 94 | editView.setEnabled(enabled); 95 | } 96 | 97 | protected void setData(String text, String defaultText) { 98 | this.defaultText = defaultText; 99 | 100 | if (title != null && title.length() != 0) 101 | titleView.setText(title); 102 | 103 | if (TextUtils.isEmpty(text)) 104 | editView.setText(defaultText); 105 | else 106 | editView.setText(text); 107 | editView.setSelection(editView.getText().length()); 108 | } 109 | 110 | /** 111 | * 依附于某个item,当该item未勾选时,本item为不可选状态 112 | */ 113 | public void setBaseOnView(BaseDialogItem item) { 114 | this.item = item; 115 | refresh(); 116 | } 117 | 118 | public void refresh() { 119 | if (item != null) { 120 | setEnabled(item.getCheckBoxStatus()); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/BaseDialogItem.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.graphics.Color; 6 | import android.util.AttributeSet; 7 | import android.util.TypedValue; 8 | import android.view.Gravity; 9 | import android.view.ViewGroup; 10 | import android.widget.CheckBox; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | 14 | import com.raincat.dolby_beta.helper.SettingHelper; 15 | import com.raincat.dolby_beta.utils.Tools; 16 | 17 | 18 | /** 19 | *
 20 |  *     author : RainCat
 21 |  *     e-mail : nining377@gmail.com
 22 |  *     time   : 2021/04/11
 23 |  *     desc   : 控件
 24 |  *     version: 1.0
 25 |  * 
26 | */ 27 | 28 | public class BaseDialogItem extends LinearLayout { 29 | private BaseDialogItem item; 30 | private Context context; 31 | 32 | protected CheckBox checkBox; 33 | protected TextView titleView, subView; 34 | 35 | protected String title, sub, key; 36 | 37 | public BaseDialogItem(Context context, AttributeSet attrs, int defStyle) { 38 | this(context, attrs); 39 | } 40 | 41 | public BaseDialogItem(Context context, AttributeSet attrs) { 42 | super(context, attrs); 43 | init(context, attrs); 44 | } 45 | 46 | public BaseDialogItem(Context context) { 47 | super(context); 48 | init(context, null); 49 | } 50 | 51 | protected void init(Context context, AttributeSet attrs) { 52 | this.context = context; 53 | 54 | int padding = Tools.dp2px(context, 10); 55 | setPadding(padding, 10, padding, 10); 56 | setMinimumHeight(Tools.dp2px(context, 40)); 57 | setOrientation(LinearLayout.HORIZONTAL); 58 | setGravity(Gravity.CENTER_VERTICAL); 59 | 60 | LinearLayout linearLayout = new LinearLayout(context); 61 | linearLayout.setOrientation(LinearLayout.VERTICAL); 62 | addView(linearLayout); 63 | LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f); 64 | linearLayout.setLayoutParams(layoutParams); 65 | 66 | titleView = new TextView(context); 67 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); 68 | titleView.setTextColor(Color.BLACK); 69 | subView = new TextView(context); 70 | subView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); 71 | subView.setTextColor(Color.DKGRAY); 72 | linearLayout.addView(titleView); 73 | linearLayout.addView(subView); 74 | checkBox = new CheckBox(context); 75 | checkBox.setClickable(false); 76 | addView(checkBox); 77 | 78 | titleView.setVisibility(GONE); 79 | subView.setVisibility(GONE); 80 | checkBox.setVisibility(GONE); 81 | } 82 | 83 | @Override 84 | public void setEnabled(boolean enabled) { 85 | super.setEnabled(enabled); 86 | 87 | if (!enabled) { 88 | titleView.setTextColor(Color.LTGRAY); 89 | subView.setTextColor(Color.LTGRAY); 90 | } else { 91 | titleView.setTextColor(Color.BLACK); 92 | subView.setTextColor(Color.DKGRAY); 93 | } 94 | checkBox.setEnabled(enabled); 95 | } 96 | 97 | protected void setData(boolean showCheck, boolean check) { 98 | if (title != null && title.length() != 0) { 99 | titleView.setText(title); 100 | titleView.setVisibility(VISIBLE); 101 | } 102 | if (sub != null && sub.length() != 0) { 103 | subView.setText(sub); 104 | subView.setVisibility(VISIBLE); 105 | } 106 | if (showCheck) { 107 | checkBox.setChecked(check); 108 | checkBox.setVisibility(VISIBLE); 109 | } 110 | } 111 | 112 | /** 113 | * 依附于某个item,当该item未勾选时,本item为不可选状态 114 | */ 115 | public void setBaseOnView(BaseDialogItem item) { 116 | this.item = item; 117 | refresh(); 118 | } 119 | 120 | protected boolean getCheckBoxStatus() { 121 | return checkBox.isChecked(); 122 | } 123 | 124 | public void refresh() { 125 | if (item != null) { 126 | setEnabled(item.getCheckBoxStatus()); 127 | } 128 | if (checkBox.getVisibility() == VISIBLE) 129 | checkBox.setChecked(SettingHelper.getInstance().getSetting(key)); 130 | } 131 | 132 | protected void sendBroadcast(String action) { 133 | context.sendBroadcast(new Intent(action)); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/BaseDialogTextItem.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | 8 | import com.raincat.dolby_beta.utils.Tools; 9 | 10 | import androidx.appcompat.widget.AppCompatTextView; 11 | 12 | /** 13 | *
14 |  *     author : RainCat
15 |  *     e-mail : nining377@gmail.com
16 |  *     time   : 2021/09/15
17 |  *     desc   : 控件
18 |  *     version: 1.0
19 |  * 
20 | */ 21 | 22 | public class BaseDialogTextItem extends AppCompatTextView { 23 | public BaseDialogTextItem(Context context, AttributeSet attrs, int defStyle) { 24 | this(context, attrs); 25 | } 26 | 27 | public BaseDialogTextItem(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | init(context, attrs); 30 | } 31 | 32 | public BaseDialogTextItem(Context context) { 33 | super(context); 34 | init(context, null); 35 | } 36 | 37 | protected void init(Context context, AttributeSet attrs) { 38 | int padding = Tools.dp2px(context, 10); 39 | setPadding(padding, 8, padding, 0); 40 | setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); 41 | setTextColor(Color.BLACK); 42 | setVisibility(GONE); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyBannerHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/23
14 |  *     desc   : 移除Banner
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyBannerHideView extends BaseDialogItem { 20 | public BeautyBannerHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyBannerHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyBannerHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_banner_hide_title; 36 | key = SettingHelper.beauty_banner_hide_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyBlackHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/16
14 |  *     desc   : 隐藏播放页黑胶
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyBlackHideView extends BaseDialogItem { 20 | public BeautyBlackHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyBlackHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyBlackHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_black_hide_title; 36 | key = SettingHelper.beauty_black_hide_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyBubbleHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/23
14 |  *     desc   : 移除小红点
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyBubbleHideView extends BaseDialogItem { 20 | public BeautyBubbleHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyBubbleHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyBubbleHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_bubble_hide_title; 36 | key = SettingHelper.beauty_bubble_hide_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyCommentHotView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/10
14 |  *     desc   : 评论区优先显示“最热”内容
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyCommentHotView extends BaseDialogItem { 20 | public BeautyCommentHotView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyCommentHotView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyCommentHotView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_comment_hot_title; 36 | key = SettingHelper.beauty_comment_hot_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyKSongHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/16
14 |  *     desc   : 隐藏播放页K歌图标
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyKSongHideView extends BaseDialogItem { 20 | public BeautyKSongHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyKSongHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyKSongHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_ksong_hide_title; 36 | key = SettingHelper.beauty_ksong_hide_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyNightModeView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/12/03
14 |  *     desc   : 夜间模式
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyNightModeView extends BaseDialogItem { 20 | public BeautyNightModeView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyNightModeView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyNightModeView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_night_mode_title; 36 | sub = SettingHelper.beauty_night_mode_sub; 37 | key = SettingHelper.beauty_night_mode_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyRotationView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/16
14 |  *     desc   : 播放页黑胶停止旋转
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyRotationView extends BaseDialogItem { 20 | public BeautyRotationView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyRotationView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyRotationView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_rotation_title; 36 | key = SettingHelper.beauty_rotation_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautySidebarHideItem.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | import java.util.HashMap; 10 | import java.util.LinkedHashMap; 11 | 12 | /** 13 | *
14 |  *     author : RainCat
15 |  *     e-mail : nining377@gmail.com
16 |  *     time   : 2021/10/22
17 |  *     desc   : 侧边栏精简
18 |  *     version: 1.0
19 |  * 
20 | */ 21 | 22 | public class BeautySidebarHideItem extends BaseDialogItem { 23 | public BeautySidebarHideItem(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | public BeautySidebarHideItem(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | public BeautySidebarHideItem(Context context) { 32 | super(context); 33 | } 34 | 35 | public void initData(LinkedHashMap sidebarMap, HashMap sidebarSettingMap, String sidebarKey) { 36 | title = sidebarMap.get(sidebarKey) + "(" + sidebarKey + ")"; 37 | key = sidebarKey; 38 | setData(true, sidebarSettingMap.get(sidebarKey)); 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSidebarSetting(key, !checkBox.isChecked()); 41 | setData(true, sidebarSettingMap.get(sidebarKey)); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautySidebarHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/22
14 |  *     desc   : 侧边栏精简
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautySidebarHideView extends BaseDialogItem { 20 | public BeautySidebarHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautySidebarHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautySidebarHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_sidebar_hide_title; 36 | key = SettingHelper.beauty_sidebar_hide_key; 37 | sub = SettingHelper.beauty_sidebar_hide_sub; 38 | setData(false, false); 39 | 40 | setOnClickListener(view -> { 41 | sendBroadcast(SettingHelper.sidebar_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyTabHideView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/21
14 |  *     desc   : tab隐藏
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BeautyTabHideView extends BaseDialogItem { 20 | public BeautyTabHideView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BeautyTabHideView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BeautyTabHideView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.beauty_tab_hide_title; 36 | sub = SettingHelper.beauty_tab_hide_sub; 37 | key = SettingHelper.beauty_tab_hide_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/beauty/BeautyTitleView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.beauty; 2 | 3 | import android.content.Context; 4 | import android.text.TextPaint; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | import com.raincat.dolby_beta.view.BaseDialogItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/04/13
16 |  *     desc   : 标题
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class BeautyTitleView extends BaseDialogItem { 22 | public BeautyTitleView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public BeautyTitleView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public BeautyTitleView(Context context) { 31 | super(context); 32 | } 33 | 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 37 | TextPaint paint = titleView.getPaint(); 38 | paint.setFakeBoldText(true); 39 | 40 | title = SettingHelper.beauty_title; 41 | setData(false, false); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyCoverView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.ScriptHelper; 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | import com.raincat.dolby_beta.utils.Tools; 9 | import com.raincat.dolby_beta.view.BaseDialogItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/09/10
16 |  *     desc   : 脚本释放
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class ProxyCoverView extends BaseDialogItem { 22 | public ProxyCoverView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public ProxyCoverView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public ProxyCoverView(Context context) { 31 | super(context); 32 | } 33 | 34 | @Override 35 | public void init(Context context, AttributeSet attrs) { 36 | super.init(context, attrs); 37 | title = SettingHelper.proxy_cover_title; 38 | sub = SettingHelper.proxy_cover_sub; 39 | key = SettingHelper.proxy_cover_key; 40 | setData(false, false); 41 | 42 | setOnClickListener(view -> { 43 | ScriptHelper.initScript(context, true); 44 | if (SettingHelper.getInstance().getSetting(SettingHelper.proxy_master_key) 45 | && !SettingHelper.getInstance().getSetting(SettingHelper.proxy_server_key)) { 46 | Tools.showToastOnLooper(context, "操作成功,脚本即将重新启动"); 47 | } else { 48 | Tools.showToastOnLooper(context, "操作成功"); 49 | } 50 | ScriptHelper.startScript(); 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyFlacView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/09/09
14 |  *     desc   : 无损开关
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class ProxyFlacView extends BaseDialogItem { 20 | public ProxyFlacView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public ProxyFlacView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public ProxyFlacView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.proxy_flac_title; 36 | sub = SettingHelper.proxy_flac_sub; 37 | key = SettingHelper.proxy_flac_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyGrayView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/09/13
14 |  *     desc   : 不变灰
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class ProxyGrayView extends BaseDialogItem { 20 | public ProxyGrayView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public ProxyGrayView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public ProxyGrayView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.proxy_gray_title; 36 | sub = SettingHelper.proxy_gray_sub; 37 | key = SettingHelper.proxy_gray_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyHttpView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.TextWatcher; 6 | import android.text.method.DigitsKeyListener; 7 | import android.util.AttributeSet; 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 10 | 11 | /** 12 | *
13 |  *     author : Luoxingran
14 |  *     e-mail : szb5845201314@gmail.com
15 |  *     time   : 2021/12/14
16 |  *     desc   : http代理模式
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class ProxyHttpView extends BaseDialogInputItem { 22 | public ProxyHttpView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public ProxyHttpView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public ProxyHttpView(Context context) { 31 | super(context); 32 | } 33 | 34 | @Override 35 | public void init(Context context, AttributeSet attrs) { 36 | super.init(context, attrs); 37 | title = SettingHelper.http_proxy_title; 38 | editView.setKeyListener(DigitsKeyListener.getInstance("0123456789.qwertyuiopasdfghjklzxcvbnm")); 39 | setData(SettingHelper.getInstance().getHttpProxy() + "", SettingHelper.http_proxy_default); 40 | 41 | defaultView.setOnClickListener(view -> { 42 | editView.setText(SettingHelper.http_proxy_default); 43 | editView.setSelection(editView.getText().length()); 44 | }); 45 | 46 | editView.addTextChangedListener(new TextWatcher() { 47 | @Override 48 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 49 | 50 | } 51 | 52 | @Override 53 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 54 | 55 | } 56 | 57 | @Override 58 | public void afterTextChanged(Editable editable) { 59 | SettingHelper.getInstance().setHttpProxy(editView.getText().toString()); 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyMasterView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.ScriptHelper; 7 | import com.raincat.dolby_beta.helper.SettingHelper; 8 | import com.raincat.dolby_beta.view.BaseDialogItem; 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/09/09
15 |  *     desc   : 代理总开关
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class ProxyMasterView extends BaseDialogItem { 21 | public ProxyMasterView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public ProxyMasterView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public ProxyMasterView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = SettingHelper.proxy_master_title; 37 | key = SettingHelper.proxy_master_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | ScriptHelper.initScript(context, false); 43 | ScriptHelper.startScript(); 44 | sendBroadcast(SettingHelper.refresh_setting); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyOriginalView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.TextWatcher; 6 | import android.text.method.DigitsKeyListener; 7 | import android.util.AttributeSet; 8 | 9 | import com.raincat.dolby_beta.helper.SettingHelper; 10 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 11 | 12 | /** 13 | *
14 |  *     author : RainCat
15 |  *     e-mail : nining377@gmail.com
16 |  *     time   : 2021/09/10
17 |  *     desc   : 音源切换
18 |  *     version: 1.0
19 |  * 
20 | */ 21 | 22 | public class ProxyOriginalView extends BaseDialogInputItem { 23 | public ProxyOriginalView(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | public ProxyOriginalView(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | public ProxyOriginalView(Context context) { 32 | super(context); 33 | } 34 | 35 | @Override 36 | public void init(Context context, AttributeSet attrs) { 37 | super.init(context, attrs); 38 | title = SettingHelper.proxy_original_title; 39 | editView.setKeyListener(DigitsKeyListener.getInstance("qwertyuiopasdfghjklzxcvbnm ")); 40 | setData(SettingHelper.getInstance().getProxyOriginal() + "", SettingHelper.proxy_original_default); 41 | 42 | defaultView.setOnClickListener(view -> { 43 | editView.setText(SettingHelper.proxy_original_default); 44 | editView.setSelection(editView.getText().length()); 45 | }); 46 | 47 | editView.addTextChangedListener(new TextWatcher() { 48 | @Override 49 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 50 | 51 | } 52 | 53 | @Override 54 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 55 | 56 | } 57 | 58 | @Override 59 | public void afterTextChanged(Editable editable) { 60 | SettingHelper.getInstance().setProxyOriginal(editView.getText().toString()); 61 | } 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyPortView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.InputFilter; 6 | import android.text.TextWatcher; 7 | import android.text.method.DigitsKeyListener; 8 | import android.util.AttributeSet; 9 | 10 | import com.raincat.dolby_beta.helper.SettingHelper; 11 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2021/09/09
18 |  *     desc   : 代理端口
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | 23 | public class ProxyPortView extends BaseDialogInputItem { 24 | public ProxyPortView(Context context, AttributeSet attrs, int defStyle) { 25 | super(context, attrs, defStyle); 26 | } 27 | 28 | public ProxyPortView(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | } 31 | 32 | public ProxyPortView(Context context) { 33 | super(context); 34 | } 35 | 36 | @Override 37 | public void init(Context context, AttributeSet attrs) { 38 | super.init(context, attrs); 39 | title = SettingHelper.proxy_port_title; 40 | editView.setKeyListener(DigitsKeyListener.getInstance("0123456789")); 41 | editView.setFilters(new InputFilter[]{new InputFilter.LengthFilter(5)}); 42 | setData(SettingHelper.getInstance().getProxyPort() + "", SettingHelper.proxy_port_default + ""); 43 | 44 | defaultView.setOnClickListener(view -> { 45 | editView.setText(SettingHelper.proxy_port_default + ""); 46 | editView.setSelection(editView.getText().length()); 47 | }); 48 | 49 | editView.addTextChangedListener(new TextWatcher() { 50 | @Override 51 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 52 | 53 | } 54 | 55 | @Override 56 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 57 | 58 | } 59 | 60 | @Override 61 | public void afterTextChanged(Editable editable) { 62 | SettingHelper.getInstance().setProxyPort(editView.getText().toString()); 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyPriorityView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/12
14 |  *     desc   : 音质优先
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class ProxyPriorityView extends BaseDialogItem { 20 | public ProxyPriorityView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public ProxyPriorityView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public ProxyPriorityView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.proxy_priority_title; 36 | sub = SettingHelper.proxy_priority_sub; 37 | key = SettingHelper.proxy_priority_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyServerView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import com.raincat.dolby_beta.helper.SettingHelper; 6 | import com.raincat.dolby_beta.view.BaseDialogItem; 7 | 8 | /** 9 | *
10 |  *     author : RainCat
11 |  *     e-mail : nining377@gmail.com
12 |  *     time   : 2021/12/07
13 |  *     desc   : 服务器代理模式
14 |  *     version: 1.0
15 |  * 
16 | */ 17 | 18 | public class ProxyServerView extends BaseDialogItem { 19 | public ProxyServerView(Context context, AttributeSet attrs, int defStyle) { 20 | super(context, attrs, defStyle); 21 | } 22 | 23 | public ProxyServerView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | public ProxyServerView(Context context) { 28 | super(context); 29 | } 30 | 31 | @Override 32 | public void init(Context context, AttributeSet attrs) { 33 | super.init(context, attrs); 34 | title = SettingHelper.proxy_server_title; 35 | sub = SettingHelper.proxy_server_sub; 36 | key = SettingHelper.proxy_server_key; 37 | setData(true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/proxy/ProxyTitleView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.proxy; 2 | 3 | import android.content.Context; 4 | import android.text.TextPaint; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | import com.raincat.dolby_beta.view.BaseDialogItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/09/10
16 |  *     desc   : 代理标题
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class ProxyTitleView extends BaseDialogItem { 22 | public ProxyTitleView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public ProxyTitleView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public ProxyTitleView(Context context) { 31 | super(context); 32 | } 33 | 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 37 | TextPaint paint = titleView.getPaint(); 38 | paint.setFakeBoldText(true); 39 | 40 | title = SettingHelper.proxy_title; 41 | setData(false, false); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/AboutView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.util.AttributeSet; 7 | 8 | import com.raincat.dolby_beta.view.BaseDialogItem; 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/11/02
15 |  *     desc   : 关于
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class AboutView extends BaseDialogItem { 21 | public AboutView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public AboutView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public AboutView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = "关于"; 37 | setData(false, false); 38 | 39 | setOnClickListener(view -> { 40 | Uri uri = Uri.parse("https://github.com/nining377/dolby_beta"); 41 | Intent intent = new Intent(Intent.ACTION_VIEW, uri); 42 | context.startActivity(intent); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/BeautyView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | import com.raincat.dolby_beta.view.BaseDialogTextItem; 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/10/21
15 |  *     desc   : 美化
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class BeautyView extends BaseDialogItem { 21 | public BeautyView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public BeautyView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public BeautyView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = SettingHelper.beauty_title; 37 | key = SettingHelper.beauty_key; 38 | setData(false, false); 39 | 40 | setOnClickListener(view -> { 41 | sendBroadcast(SettingHelper.beauty_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/BlackView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/04/13
14 |  *     desc   : 黑胶支持
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class BlackView extends BaseDialogItem { 20 | public BlackView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public BlackView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public BlackView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.black_title; 36 | sub = SettingHelper.black_sub; 37 | key = SettingHelper.black_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/DexView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/04/13
14 |  *     desc   : Dex缓存
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class DexView extends BaseDialogItem { 20 | public DexView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public DexView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public DexView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.dex_title; 36 | sub = SettingHelper.dex_sub; 37 | key = SettingHelper.dex_key; 38 | setData( true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/FixCommentView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/11/30
14 |  *     desc   : 评论区加载失败
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class FixCommentView extends BaseDialogItem { 20 | public FixCommentView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public FixCommentView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public FixCommentView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.fix_comment_title; 36 | sub = SettingHelper.fix_comment_sub; 37 | key = SettingHelper.fix_comment_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/ListenView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import com.raincat.dolby_beta.helper.SettingHelper; 6 | import com.raincat.dolby_beta.view.BaseDialogItem; 7 | 8 | 9 | 10 | public class ListenView extends BaseDialogItem { 11 | public ListenView(Context context, AttributeSet attrs, int defStyle) { 12 | super(context, attrs, defStyle); 13 | } 14 | 15 | public ListenView(Context context, AttributeSet attrs) { 16 | super(context, attrs); 17 | } 18 | 19 | public ListenView(Context context) { 20 | super(context); 21 | } 22 | 23 | @Override 24 | public void init(Context context, AttributeSet attrs) { 25 | super.init(context, attrs); 26 | title = SettingHelper.listen_title; 27 | sub = SettingHelper.listen_sub; 28 | key = SettingHelper.listen_key; 29 | setData(true, SettingHelper.getInstance().getSetting(key)); 30 | 31 | setOnClickListener(view -> { 32 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 33 | sendBroadcast(SettingHelper.refresh_setting); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/MasterView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.utils.Tools; 8 | import com.raincat.dolby_beta.view.BaseDialogItem; 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/04/13
15 |  *     desc   : 总开关
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class MasterView extends BaseDialogItem { 21 | public MasterView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public MasterView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public MasterView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = SettingHelper.master_title; 37 | key = SettingHelper.master_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | Tools.showToastOnLooper(context,"打开/关闭此设置需重启网易云"); 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/ProxyView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/04/13
14 |  *     desc   : 音源代理
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class ProxyView extends BaseDialogItem { 20 | public ProxyView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public ProxyView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public ProxyView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.proxy_title; 36 | key = SettingHelper.proxy_key; 37 | setData(false, false); 38 | 39 | setOnClickListener(view -> { 40 | sendBroadcast(SettingHelper.proxy_setting); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/SignSongDailyView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/09/13
14 |  *     desc   : 歌曲每日打卡
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class SignSongDailyView extends BaseDialogItem { 20 | public SignSongDailyView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public SignSongDailyView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public SignSongDailyView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.sign_song_title; 36 | sub = SettingHelper.sign_song_sub; 37 | key = SettingHelper.sign_song_key; 38 | setData( true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/SignSongSelfView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.helper.SignSongHelper; 8 | import com.raincat.dolby_beta.view.BaseDialogItem; 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/09/17
15 |  *     desc   : 自助打卡
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class SignSongSelfView extends BaseDialogItem { 21 | public SignSongSelfView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public SignSongSelfView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public SignSongSelfView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = SettingHelper.sign_self_title; 37 | setData(false, false); 38 | 39 | setOnClickListener(view -> { 40 | SignSongHelper.showSelfSignDialog(context); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/SignView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/04/13
14 |  *     desc   : 签到
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class SignView extends BaseDialogItem { 20 | public SignView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public SignView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public SignView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.sign_title; 36 | key = SettingHelper.sign_key; 37 | setData( true, SettingHelper.getInstance().getSetting(key)); 38 | 39 | setOnClickListener(view -> { 40 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 41 | sendBroadcast(SettingHelper.refresh_setting); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/TitleView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.text.TextPaint; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | 8 | import com.raincat.dolby_beta.BuildConfig; 9 | import com.raincat.dolby_beta.view.BaseDialogItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/04/13
16 |  *     desc   : 标题
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class TitleView extends BaseDialogItem { 22 | public TitleView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public TitleView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public TitleView(Context context) { 31 | super(context); 32 | } 33 | 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 37 | TextPaint paint = titleView.getPaint(); 38 | paint.setFakeBoldText(true); 39 | 40 | title = "杜比大喇叭β v" + BuildConfig.VERSION_NAME; 41 | sub = "本模块仅供学习交流,严禁用于商业用途,请于24小时内删除。\n" + 42 | "注意:模块工作原理为音源替换而非破解,所以单曲付费与无版权歌曲有几率匹配错误,真心支持歌手请付费。"; 43 | setData(false, false); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/UpdateView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | 10 | /** 11 | *
12 |  *     author : RainCat
13 |  *     e-mail : nining377@gmail.com
14 |  *     time   : 2021/04/13
15 |  *     desc   : 去升级
16 |  *     version: 1.0
17 |  * 
18 | */ 19 | 20 | public class UpdateView extends BaseDialogItem { 21 | public UpdateView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | public UpdateView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public UpdateView(Context context) { 30 | super(context); 31 | } 32 | 33 | @Override 34 | public void init(Context context, AttributeSet attrs) { 35 | super.init(context, attrs); 36 | title = SettingHelper.update_title; 37 | key = SettingHelper.update_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/setting/WarnView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.setting; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.raincat.dolby_beta.helper.SettingHelper; 7 | import com.raincat.dolby_beta.view.BaseDialogItem; 8 | 9 | /** 10 | *
11 |  *     author : RainCat
12 |  *     e-mail : nining377@gmail.com
13 |  *     time   : 2021/10/26
14 |  *     desc   : 通知栏警告
15 |  *     version: 1.0
16 |  * 
17 | */ 18 | 19 | public class WarnView extends BaseDialogItem { 20 | public WarnView(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public WarnView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public WarnView(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public void init(Context context, AttributeSet attrs) { 34 | super.init(context, attrs); 35 | title = SettingHelper.warn_title; 36 | sub = SettingHelper.warn_sub; 37 | key = SettingHelper.warn_key; 38 | setData(true, SettingHelper.getInstance().getSetting(key)); 39 | 40 | setOnClickListener(view -> { 41 | SettingHelper.getInstance().setSetting(key, !checkBox.isChecked()); 42 | sendBroadcast(SettingHelper.refresh_setting); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/sign/SignCountView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.sign; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.InputFilter; 6 | import android.text.TextWatcher; 7 | import android.text.method.DigitsKeyListener; 8 | import android.util.AttributeSet; 9 | 10 | import com.raincat.dolby_beta.helper.SettingHelper; 11 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2021/09/17
18 |  *     desc   : 打卡数量
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | 23 | public class SignCountView extends BaseDialogInputItem { 24 | public SignCountView(Context context, AttributeSet attrs, int defStyle) { 25 | super(context, attrs, defStyle); 26 | } 27 | 28 | public SignCountView(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | } 31 | 32 | public SignCountView(Context context) { 33 | super(context); 34 | } 35 | 36 | @Override 37 | public void init(Context context, AttributeSet attrs) { 38 | super.init(context, attrs); 39 | title = SettingHelper.sign_count_title; 40 | editView.setKeyListener(DigitsKeyListener.getInstance("0123456789")); 41 | editView.setFilters(new InputFilter[]{new InputFilter.LengthFilter(5)}); 42 | setData(SettingHelper.getInstance().getSignCount() + "", SettingHelper.sign_count_default + ""); 43 | 44 | defaultView.setOnClickListener(view -> { 45 | editView.setText(SettingHelper.sign_count_default + ""); 46 | editView.setSelection(editView.getText().length()); 47 | }); 48 | 49 | editView.addTextChangedListener(new TextWatcher() { 50 | @Override 51 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 52 | 53 | } 54 | 55 | @Override 56 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 57 | 58 | } 59 | 60 | @Override 61 | public void afterTextChanged(Editable editable) { 62 | SettingHelper.getInstance().setSignCount(editView.getText().toString()); 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/sign/SignIdView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.sign; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.TextWatcher; 6 | import android.util.AttributeSet; 7 | 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/09/17
16 |  *     desc   : 歌曲列表id
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class SignIdView extends BaseDialogInputItem { 22 | public SignIdView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public SignIdView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public SignIdView(Context context) { 31 | super(context); 32 | } 33 | 34 | @Override 35 | public void init(Context context, AttributeSet attrs) { 36 | super.init(context, attrs); 37 | title = SettingHelper.sign_id_title; 38 | setData(SettingHelper.getInstance().getSignId(), ""); 39 | 40 | defaultView.setText("清空"); 41 | defaultView.setOnClickListener(view -> { 42 | editView.setText(""); 43 | }); 44 | 45 | editView.addTextChangedListener(new TextWatcher() { 46 | @Override 47 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 48 | 49 | } 50 | 51 | @Override 52 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 53 | 54 | } 55 | 56 | @Override 57 | public void afterTextChanged(Editable editable) { 58 | SettingHelper.getInstance().setSignId(editView.getText().toString()); 59 | } 60 | }); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/sign/SignStartView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.sign; 2 | 3 | import android.content.Context; 4 | import android.text.Editable; 5 | import android.text.InputFilter; 6 | import android.text.TextWatcher; 7 | import android.text.method.DigitsKeyListener; 8 | import android.util.AttributeSet; 9 | 10 | import com.raincat.dolby_beta.helper.SettingHelper; 11 | import com.raincat.dolby_beta.view.BaseDialogInputItem; 12 | 13 | /** 14 | *
15 |  *     author : RainCat
16 |  *     e-mail : nining377@gmail.com
17 |  *     time   : 2021/09/17
18 |  *     desc   : 打卡开始
19 |  *     version: 1.0
20 |  * 
21 | */ 22 | 23 | public class SignStartView extends BaseDialogInputItem { 24 | public SignStartView(Context context, AttributeSet attrs, int defStyle) { 25 | super(context, attrs, defStyle); 26 | } 27 | 28 | public SignStartView(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | } 31 | 32 | public SignStartView(Context context) { 33 | super(context); 34 | } 35 | 36 | @Override 37 | public void init(Context context, AttributeSet attrs) { 38 | super.init(context, attrs); 39 | title = SettingHelper.sign_start_title; 40 | editView.setKeyListener(DigitsKeyListener.getInstance("0123456789")); 41 | editView.setFilters(new InputFilter[]{new InputFilter.LengthFilter(5)}); 42 | setData(SettingHelper.getInstance().getSignStart() + "", SettingHelper.sign_start_default + ""); 43 | 44 | defaultView.setOnClickListener(view -> { 45 | editView.setText(SettingHelper.sign_start_default + ""); 46 | editView.setSelection(editView.getText().length()); 47 | }); 48 | 49 | editView.addTextChangedListener(new TextWatcher() { 50 | @Override 51 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 52 | 53 | } 54 | 55 | @Override 56 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 57 | 58 | } 59 | 60 | @Override 61 | public void afterTextChanged(Editable editable) { 62 | SettingHelper.getInstance().setSignStart(editView.getText().toString()); 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/raincat/dolby_beta/view/sign/SignTitleView.java: -------------------------------------------------------------------------------- 1 | package com.raincat.dolby_beta.view.sign; 2 | 3 | import android.content.Context; 4 | import android.text.TextPaint; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | 8 | import com.raincat.dolby_beta.helper.SettingHelper; 9 | import com.raincat.dolby_beta.view.BaseDialogItem; 10 | 11 | /** 12 | *
13 |  *     author : RainCat
14 |  *     e-mail : nining377@gmail.com
15 |  *     time   : 2021/09/15
16 |  *     desc   : 每日歌曲打卡
17 |  *     version: 1.0
18 |  * 
19 | */ 20 | 21 | public class SignTitleView extends BaseDialogItem { 22 | public SignTitleView(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | 26 | public SignTitleView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public SignTitleView(Context context) { 31 | super(context); 32 | } 33 | 34 | public void setTitle(String title) { 35 | titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 36 | TextPaint paint = titleView.getPaint(); 37 | paint.setFakeBoldText(true); 38 | 39 | this.title = title; 40 | setData(false, false); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libnode.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/src/main/jniLibs/arm64-v8a/libnode.so -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 杜比大喇叭β 3 | 4 | 模块无界面,设置已内嵌到“网易云音乐->设置”中 5 | 6 | 7 | com.netease.cloudmusic 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter/" } 4 | mavenCentral() 5 | jcenter() 6 | google() 7 | } 8 | dependencies { 9 | classpath "com.android.tools.build:gradle:4.0.2" 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter/" } 16 | mavenCentral() 17 | jcenter() 18 | google() 19 | flatDir { 20 | dirs 'libs' 21 | } 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 25 10:56:22 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.2-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /hotxposed/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /hotxposed/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion '29.0.3' 6 | defaultConfig { 7 | minSdkVersion 14 8 | targetSdkVersion 29 9 | } 10 | 11 | buildTypes { 12 | release { 13 | minifyEnabled false 14 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 15 | } 16 | } 17 | 18 | lintOptions { 19 | abortOnError false 20 | } 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(dir: 'libs', include: ['*.jar']) 25 | compileOnly 'de.robv.android.xposed:api:82' 26 | implementation 'androidx.appcompat:appcompat:1.2.0' 27 | } 28 | -------------------------------------------------------------------------------- /hotxposed/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /hotxposed/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /hotxposed/src/main/java/net/androidwing/hotxposed/HotXposed.java: -------------------------------------------------------------------------------- 1 | package net.androidwing.hotxposed; 2 | 3 | import android.content.Context; 4 | import android.content.pm.ApplicationInfo; 5 | import android.content.pm.PackageManager; 6 | import android.util.Log; 7 | 8 | import java.io.File; 9 | import java.lang.reflect.Method; 10 | 11 | import dalvik.system.PathClassLoader; 12 | import de.robv.android.xposed.XC_MethodHook; 13 | import de.robv.android.xposed.XposedHelpers; 14 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 15 | 16 | /** 17 | * Created on 2018/3/30. 18 | */ 19 | public class HotXposed { 20 | public static void hook(Class clazz, XC_LoadPackage.LoadPackageParam lpparam) 21 | throws Exception { 22 | String packageName = clazz.getName().replace("." + clazz.getSimpleName(), ""); 23 | File apkFile = getApkFile(packageName, lpparam); 24 | 25 | if (!apkFile.exists()) { 26 | Log.e("error", "apk file not found"); 27 | return; 28 | } 29 | 30 | filterNotify(lpparam); 31 | 32 | PathClassLoader classLoader = new PathClassLoader(apkFile.getAbsolutePath(), lpparam.getClass().getClassLoader()); 33 | Class cls = classLoader.loadClass(clazz.getName()); 34 | if (cls != null) { 35 | Method method = cls.getDeclaredMethod("dispatch", XC_LoadPackage.LoadPackageParam.class); 36 | method.setAccessible(true); 37 | method.invoke(cls.newInstance(), lpparam); 38 | } 39 | } 40 | 41 | private static void filterNotify(XC_LoadPackage.LoadPackageParam lpparam) 42 | throws ClassNotFoundException { 43 | if ("de.robv.android.xposed.installer".equals(lpparam.packageName)) { 44 | XposedHelpers.findAndHookMethod(lpparam.classLoader.loadClass("de.robv.android.xposed.installer.util.NotificationUtil"), 45 | "showModulesUpdatedNotification", new XC_MethodHook() { 46 | @Override 47 | protected void beforeHookedMethod(MethodHookParam param) { 48 | param.setResult(new Object()); 49 | } 50 | 51 | @Override 52 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 53 | super.afterHookedMethod(param); 54 | } 55 | }); 56 | } 57 | } 58 | 59 | private static File getApkFile(String packageName, XC_LoadPackage.LoadPackageParam lpparam) throws PackageManager.NameNotFoundException { 60 | Context systemContext = (Context) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", lpparam.classLoader), "currentActivityThread"), "getSystemContext"); 61 | ApplicationInfo applicationInfo = systemContext.getPackageManager().getApplicationInfo(packageName, 0); 62 | return new File(applicationInfo.sourceDir); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /hotxposed/src/main/java/net/androidwing/hotxposed/IHookerDispatcher.java: -------------------------------------------------------------------------------- 1 | package net.androidwing.hotxposed; 2 | 3 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 4 | 5 | /** 6 | * Created on 2018/3/30. 7 | */ 8 | public interface IHookerDispatcher { 9 | void dispatch(XC_LoadPackage.LoadPackageParam loadPackageParam); 10 | } 11 | -------------------------------------------------------------------------------- /hotxposed/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HotXposed 3 | 4 | -------------------------------------------------------------------------------- /image/img_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nining377/dolby_beta/258ab9b95671ecfb13a03636842890d9ca36fe75/image/img_01.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='dolby_beta' 2 | include ':app', ':hotxposed' 3 | --------------------------------------------------------------------------------