├── .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 |
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 |
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
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
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
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
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
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
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
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
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
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
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
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
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
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 |