├── .github
└── workflows
│ ├── APK-J-Jar.yml
│ ├── APK-J.yml
│ ├── APK-T-Jar.yml
│ └── APK-T.yml
├── DIY
├── J
│ ├── ApiConfig.java
│ ├── App.java
│ ├── DetailActivity.java
│ ├── HomeActivity.java
│ ├── LivePlayActivity.java
│ ├── VodController.java
│ ├── activity_home.xml
│ ├── activity_live_play.xml
│ ├── fragment_user.xml
│ └── player_vod_control_view.xml
├── T
│ ├── ApiConfig.java
│ ├── App.java
│ ├── BaseActivity.java
│ ├── HomeActivity.java
│ ├── HomeIconDialog.java
│ ├── LivePlayActivity.java
│ ├── SearchActivity.java
│ ├── UserFragment.java
│ ├── VodController.java
│ ├── activity_home.xml
│ └── fragment_user.xml
├── TVBoxOSC.jks
├── app_bg.png
├── app_bg_black.png
├── app_icon.png
└── bg.jpg
├── LICENSE
├── README.md
├── diy-J-Jar.sh
├── diy-J.sh
├── diy-T-Jar.sh
└── diy-T.sh
/.github/workflows/APK-J-Jar.yml:
--------------------------------------------------------------------------------
1 | name: APK-J-Jar Build
2 |
3 | on:
4 | # push:
5 | # branches:
6 | # - main
7 | # pull_request:
8 | workflow_dispatch:
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | fetch-depth: 0
17 | - name: Clone Project
18 | run: git clone -b main --depth=1 https://github.com/zhoujck/TVBoxOS
19 | - name: DIY
20 | run: |
21 | chmod +x diy-J-Jar.sh
22 | bash ${{ github.workspace }}/diy-J-Jar.sh
23 | - name: Build With Gradle
24 | run: |
25 | num=$(find ${{ github.workspace }} -name gradlew | awk -F"/" '{print NF-1}')
26 | DIR=$(find ${{ github.workspace }} -name gradlew | cut -d \/ -f$num)
27 | cd $DIR
28 | chmod +x gradlew
29 | ./gradlew assemblerelease --build-cache --parallel --daemon --warning-mode all
30 | - name: Prepare App
31 | run: |
32 | mkdir -p ${{ github.workspace }}/apk/
33 | for file in `find ~ -name "*.apk" -print`; do
34 | mv "$file" ${{ github.workspace }}/apk/
35 | done
36 | - name: Upload App To Artifact
37 | uses: actions/upload-artifact@v3
38 | with:
39 | name: 糖果
40 | path: ${{ github.workspace }}/apk/*
41 |
--------------------------------------------------------------------------------
/.github/workflows/APK-J.yml:
--------------------------------------------------------------------------------
1 | name: APK-J Build
2 |
3 | on:
4 | # push:
5 | # branches:
6 | # - main
7 | # pull_request:
8 | workflow_dispatch:
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | fetch-depth: 0
17 | - name: Clone Project
18 | run: git clone -b main --depth=1 https://github.com/zhoujck/TVBoxOS
19 | - name: DIY
20 | run: |
21 | chmod +x diy-J.sh
22 | bash ${{ github.workspace }}/diy-J.sh
23 | - name: Build With Gradle
24 | run: |
25 | num=$(find ${{ github.workspace }} -name gradlew | awk -F"/" '{print NF-1}')
26 | DIR=$(find ${{ github.workspace }} -name gradlew | cut -d \/ -f$num)
27 | cd $DIR
28 | chmod +x gradlew
29 | ./gradlew assemblerelease --build-cache --parallel --daemon --warning-mode all
30 | - name: Prepare App
31 | run: |
32 | mkdir -p ${{ github.workspace }}/apk/
33 | for file in `find ~ -name "*.apk" -print`; do
34 | mv "$file" ${{ github.workspace }}/apk/
35 | done
36 | - name: Upload App To Artifact
37 | uses: actions/upload-artifact@v3
38 | with:
39 | name: 糖果
40 | path: ${{ github.workspace }}/apk/*
41 |
--------------------------------------------------------------------------------
/.github/workflows/APK-T-Jar.yml:
--------------------------------------------------------------------------------
1 |
2 | name: APK-T-Jar Build
3 |
4 | on:
5 | # push:
6 | # branches:
7 | # - main
8 | # pull_request:
9 | workflow_dispatch:
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v3
17 | with:
18 | fetch-depth: 0
19 | - name: set up JDK 17
20 | uses: actions/setup-java@v2
21 | with:
22 | java-version: '17'
23 | distribution: 'adopt'
24 | # - uses: actions/checkout@v3
25 | # with:
26 | # fetch-depth: 0
27 | - name: Clone Project
28 | run: git clone -b main --depth=1 https://github.com/takagen99/Box
29 | - name: DIY
30 | run: |
31 | chmod +x diy-T-Jar.sh
32 | bash ${{ github.workspace }}/diy-T-Jar.sh
33 | - name: Build With Gradle
34 | run: |
35 | num=$(find ${{ github.workspace }} -name gradlew | awk -F"/" '{print NF-1}')
36 | DIR=$(find ${{ github.workspace }} -name gradlew | cut -d \/ -f$num)
37 | cd $DIR
38 | chmod +x gradlew
39 | ./gradlew assemblerelease --build-cache --parallel --daemon --warning-mode all
40 |
41 | - name: Prepare App
42 | run: |
43 | mkdir -p ${{ github.workspace }}/apk/
44 | for file in `find ~ -name "*.apk" -print`; do
45 | mv "$file" ${{ github.workspace }}/apk/
46 | done
47 | - name: Upload App To Artifact
48 | uses: actions/upload-artifact@v3
49 | with:
50 | name: 糖果
51 | path: ${{ github.workspace }}/apk/*
52 |
--------------------------------------------------------------------------------
/.github/workflows/APK-T.yml:
--------------------------------------------------------------------------------
1 | name: APK-T Build
2 |
3 | on:
4 | # push:
5 | # branches:
6 | # - main
7 | # pull_request:
8 | workflow_dispatch:
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | fetch-depth: 0
17 | - name: Clone Project
18 | run: git clone -b main --depth=1 https://github.com/zhoujck/takagen99.git
19 | - name: DIY
20 | run: |
21 | chmod +x diy-T.sh
22 | bash ${{ github.workspace }}/diy-T.sh
23 | - name: Build With Gradle
24 | run: |
25 | num=$(find ${{ github.workspace }} -name gradlew | awk -F"/" '{print NF-1}')
26 | DIR=$(find ${{ github.workspace }} -name gradlew | cut -d \/ -f$num)
27 | cd $DIR
28 | chmod +x gradlew
29 | ./gradlew assemblerelease --build-cache --parallel --daemon --warning-mode all
30 | - name: Prepare App
31 | run: |
32 | mkdir -p ${{ github.workspace }}/apk/
33 | for file in `find ~ -name "*.apk" -print`; do
34 | mv "$file" ${{ github.workspace }}/apk/
35 | done
36 | - name: Upload App To Artifact
37 | uses: actions/upload-artifact@v3
38 | with:
39 | name: 糖果tv
40 | path: ${{ github.workspace }}/apk/*
41 |
--------------------------------------------------------------------------------
/DIY/J/App.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.base;
2 |
3 | import android.app.Activity;
4 | import androidx.multidex.MultiDexApplication;
5 |
6 | import com.github.tvbox.osc.bean.VodInfo;
7 | import com.github.tvbox.osc.callback.EmptyCallback;
8 | import com.github.tvbox.osc.callback.LoadingCallback;
9 | import com.github.tvbox.osc.data.AppDataManager;
10 | import com.github.tvbox.osc.server.ControlManager;
11 | import com.github.tvbox.osc.util.AppManager;
12 | import com.github.tvbox.osc.util.EpgUtil;
13 | import com.github.tvbox.osc.util.FileUtils;
14 | import com.github.tvbox.osc.util.HawkConfig;
15 | import com.github.tvbox.osc.util.OkGoHelper;
16 | import com.github.tvbox.osc.util.PlayerHelper;
17 | import com.github.tvbox.osc.util.js.JSEngine;
18 | import com.kingja.loadsir.core.LoadSir;
19 | import com.orhanobut.hawk.Hawk;
20 |
21 | import me.jessyan.autosize.AutoSizeConfig;
22 | import me.jessyan.autosize.unit.Subunits;
23 |
24 | /**
25 | * @author pj567
26 | * @date :2020/12/17
27 | * @description:
28 | */
29 | public class App extends MultiDexApplication {
30 | private static App instance;
31 |
32 | @Override
33 | public void onCreate() {
34 | super.onCreate();
35 | instance = this;
36 | initParams();
37 | // OKGo
38 | OkGoHelper.init(); //台标获取
39 | EpgUtil.init();
40 | // 初始化Web服务器
41 | ControlManager.init(this);
42 | //初始化数据库
43 | AppDataManager.init();
44 | LoadSir.beginBuilder()
45 | .addCallback(new EmptyCallback())
46 | .addCallback(new LoadingCallback())
47 | .commit();
48 | AutoSizeConfig.getInstance().setCustomFragment(true).getUnitsManager()
49 | .setSupportDP(false)
50 | .setSupportSP(false)
51 | .setSupportSubunits(Subunits.MM);
52 | PlayerHelper.init();
53 | JSEngine.getInstance().create();
54 | FileUtils.cleanPlayerCache();
55 | }
56 |
57 | private void initParams() {
58 | // Hawk
59 | Hawk.init(this).build();
60 | Hawk.put(HawkConfig.DEBUG_OPEN, false);
61 | putDefault(HawkConfig.HOME_REC, 0); // Home Rec 0=豆瓣, 1=站点推荐, 2=历史
62 | putDefault(HawkConfig.HOME_REC_STYLE, true); // 首页多行 是 or 否
63 | putDefault(HawkConfig.FAST_SEARCH_MODE, false); // 聚合模式 打开 or 关闭
64 | putDefault(HawkConfig.PLAY_TYPE, 1); // Player 0=系统, 1=IJK, 2=Exo
65 | putDefault(HawkConfig.IJK_CODEC, "硬解码");// IJK Render 软解码, 硬解码
66 | putDefault(HawkConfig.DOH_URL, 2); // DNS 0=关闭 1=腾讯 2=阿里 3=360
67 | putDefault(HawkConfig.SEARCH_VIEW, 1); // 搜索展示 Text or Picture
68 | putDefault(HawkConfig.IJK_CACHE_PLAY, true); // IJK缓存 打开 or 关闭
69 | putDefault(HawkConfig.HISTORY_NUM, 0); // 0=30 1=50 2=70
70 | }
71 |
72 | public static App getInstance() {
73 | return instance;
74 | }
75 |
76 | @Override
77 | public void onTerminate() {
78 | super.onTerminate();
79 | JSEngine.getInstance().destroy();
80 | }
81 |
82 |
83 | private VodInfo vodInfo;
84 | public void setVodInfo(VodInfo vodinfo){
85 | this.vodInfo = vodinfo;
86 | }
87 | public VodInfo getVodInfo(){
88 | return this.vodInfo;
89 | }
90 |
91 | public Activity getCurrentActivity() {
92 | return AppManager.getInstance().currentActivity();
93 | }
94 | private void putDefault(String key, Object value) {
95 | if (!Hawk.contains(key)) {
96 | Hawk.put(key, value);
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/DIY/J/activity_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
21 |
22 |
34 |
35 |
48 |
49 |
60 |
61 |
62 |
73 |
74 |
83 |
84 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/DIY/J/activity_live_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
26 |
34 |
40 |
41 |
42 |
43 |
44 |
57 |
62 |
63 |
71 |
88 |
89 |
96 |
97 |
98 |
99 |
100 |
109 |
110 |
118 |
119 |
124 |
125 |
134 |
135 |
136 |
137 |
138 |
148 |
149 |
162 |
163 |
172 |
173 |
186 |
187 |
188 |
193 |
194 |
204 |
205 |
210 |
211 |
219 |
220 |
233 |
234 |
244 |
245 |
258 |
259 |
266 |
267 |
280 |
291 |
292 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
320 |
321 |
333 |
334 |
339 |
340 |
352 |
353 |
354 |
369 |
370 |
383 |
384 |
397 |
398 |
399 |
400 |
407 |
414 |
415 |
425 |
448 |
458 |
463 |
464 |
476 |
483 |
484 |
485 |
508 |
509 |
510 |
522 |
533 |
534 |
553 |
561 |
572 |
583 |
584 |
603 |
604 |
616 |
617 |
629 |
630 |
631 |
632 |
639 |
640 |
641 |
648 |
649 |
650 |
656 |
657 |
658 |
669 |
678 |
679 |
699 |
700 |
724 |
725 |
726 |
727 |
728 |
729 |
740 |
749 |
757 |
758 |
774 |
775 |
791 |
792 |
793 |
794 |
795 |
--------------------------------------------------------------------------------
/DIY/J/fragment_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
22 |
23 |
38 |
39 |
40 |
46 |
47 |
59 |
60 |
61 |
62 |
77 |
78 |
79 |
85 |
86 |
98 |
99 |
100 |
101 |
116 |
117 |
118 |
124 |
125 |
137 |
138 |
139 |
140 |
141 |
157 |
158 |
159 |
165 |
166 |
178 |
179 |
180 |
181 |
196 |
197 |
198 |
204 |
205 |
217 |
218 |
219 |
220 |
221 |
236 |
237 |
238 |
244 |
245 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
282 |
283 |
300 |
301 |
302 |
303 |
--------------------------------------------------------------------------------
/DIY/J/player_vod_control_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
21 |
22 |
35 |
36 |
48 |
49 |
50 |
51 |
63 |
64 |
77 |
78 |
92 |
93 |
94 |
106 |
107 |
108 |
109 |
123 |
124 |
138 |
139 |
144 |
157 |
171 |
172 |
185 |
186 |
199 |
200 |
214 |
215 |
228 |
229 |
242 |
243 |
256 |
257 |
270 |
271 |
284 |
285 |
286 |
287 |
300 |
301 |
313 |
314 |
327 |
328 |
341 |
342 |
343 |
355 |
356 |
369 |
370 |
383 |
384 |
396 |
397 |
398 |
399 |
407 |
408 |
418 |
419 |
428 |
429 |
430 |
431 |
436 |
437 |
446 |
447 |
465 |
466 |
475 |
476 |
477 |
478 |
479 |
480 |
487 |
488 |
496 |
497 |
509 |
510 |
511 |
520 |
521 |
528 |
529 |
541 |
542 |
543 |
544 |
545 |
560 |
561 |
573 |
574 |
581 |
582 |
593 |
594 |
595 |
596 |
605 |
606 |
618 |
619 |
620 |
--------------------------------------------------------------------------------
/DIY/T/App.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.base;
2 |
3 | import androidx.multidex.MultiDexApplication;
4 |
5 | import com.github.tvbox.osc.callback.EmptyCallback;
6 | import com.github.tvbox.osc.callback.LoadingCallback;
7 | import com.github.tvbox.osc.data.AppDataManager;
8 | import com.github.tvbox.osc.server.ControlManager;
9 | import com.github.tvbox.osc.util.EpgUtil;
10 | import com.github.tvbox.osc.util.FileUtils;
11 | import com.github.tvbox.osc.util.HawkConfig;
12 | import com.github.tvbox.osc.util.LocaleHelper;
13 | import com.github.tvbox.osc.util.OkGoHelper;
14 | import com.github.tvbox.osc.util.PlayerHelper;
15 | import com.github.tvbox.osc.util.js.JSEngine;
16 | import com.kingja.loadsir.core.LoadSir;
17 | import com.orhanobut.hawk.Hawk;
18 |
19 | import java.io.File;
20 |
21 | import me.jessyan.autosize.AutoSizeConfig;
22 | import me.jessyan.autosize.unit.Subunits;
23 |
24 | /**
25 | * @author pj567
26 | * @date :2020/12/17
27 | * @description:
28 | */
29 | public class App extends MultiDexApplication {
30 | private static App instance;
31 |
32 | @Override
33 | public void onCreate() {
34 | super.onCreate();
35 | instance = this;
36 | initParams();
37 | // takagen99 : Initialize Locale
38 | initLocale();
39 | // OKGo
40 | OkGoHelper.init();
41 | // Get EPG Info
42 | EpgUtil.init();
43 | // 初始化Web服务器
44 | ControlManager.init(this);
45 | //初始化数据库
46 | AppDataManager.init();
47 | LoadSir.beginBuilder()
48 | .addCallback(new EmptyCallback())
49 | .addCallback(new LoadingCallback())
50 | .commit();
51 | AutoSizeConfig.getInstance().setCustomFragment(true).getUnitsManager()
52 | .setSupportDP(false)
53 | .setSupportSP(false)
54 | .setSupportSubunits(Subunits.MM);
55 | PlayerHelper.init();
56 |
57 | // Delete Cache
58 | File dir = getCacheDir();
59 | FileUtils.recursiveDelete(dir);
60 | dir = getExternalCacheDir();
61 | FileUtils.recursiveDelete(dir);
62 |
63 | // Add JS support
64 | JSEngine.getInstance().create();
65 | }
66 |
67 | private void initParams() {
68 | // Hawk
69 | Hawk.init(this).build();
70 | Hawk.put(HawkConfig.DEBUG_OPEN, false);
71 |
72 | putDefault(HawkConfig.HOME_REC, 0); // Home Rec 0=豆瓣, 1=推荐, 2=历史
73 | putDefault(HawkConfig.PLAY_TYPE, 1); // Player 0=系统, 1=IJK, 2=Exo
74 | putDefault(HawkConfig.IJK_CODEC, "硬解码");// IJK Render 软解码, 硬解码
75 | putDefault(HawkConfig.HOME_SEARCH_POSITION, false);// 上方/下方
76 | putDefault(HawkConfig.HOME_MENU_POSITION, false);// 上方/下方
77 | putDefault(HawkConfig.HOME_SHOW_SOURCE, true);// 开启/关闭
78 | putDefault(HawkConfig.HOME_REC_STYLE, true);// 开启/关闭
79 | putDefault(HawkConfig.HOME_NUM, 0); // 0=30 1=50 2=70
80 |
81 |
82 | }
83 |
84 | private void initLocale() {
85 | if (Hawk.get(HawkConfig.HOME_LOCALE, 0) == 0) {
86 | LocaleHelper.setLocale(App.this, "zh");
87 | } else {
88 | LocaleHelper.setLocale(App.this, "");
89 | }
90 | }
91 |
92 | public static App getInstance() {
93 | return instance;
94 | }
95 |
96 | private void putDefault(String key, Object value) {
97 | if (!Hawk.contains(key)) {
98 | Hawk.put(key, value);
99 | }
100 | }
101 |
102 | @Override
103 | public void onTerminate() {
104 | super.onTerminate();
105 | JSEngine.getInstance().destroy();
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/DIY/T/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.base;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.res.AssetManager;
6 | import android.content.res.Resources;
7 | import android.content.res.TypedArray;
8 | import android.graphics.BitmapFactory;
9 | import android.graphics.drawable.BitmapDrawable;
10 | import android.os.Build;
11 | import android.os.Bundle;
12 | import android.os.Looper;
13 | import android.util.DisplayMetrics;
14 | import android.view.View;
15 | import android.view.WindowManager;
16 |
17 | import androidx.annotation.Nullable;
18 | import androidx.appcompat.app.AppCompatActivity;
19 | import androidx.core.content.PermissionChecker;
20 |
21 | import com.github.tvbox.osc.R;
22 | import com.github.tvbox.osc.callback.EmptyCallback;
23 | import com.github.tvbox.osc.callback.LoadingCallback;
24 | import com.github.tvbox.osc.util.AppManager;
25 | import com.github.tvbox.osc.util.HawkConfig;
26 | import com.github.tvbox.osc.util.LocaleHelper;
27 | import com.kingja.loadsir.callback.Callback;
28 | import com.kingja.loadsir.core.LoadService;
29 | import com.kingja.loadsir.core.LoadSir;
30 | import com.orhanobut.hawk.Hawk;
31 |
32 | import java.io.BufferedReader;
33 | import java.io.File;
34 | import java.io.IOException;
35 | import java.io.InputStreamReader;
36 |
37 | import me.jessyan.autosize.AutoSizeCompat;
38 | import me.jessyan.autosize.internal.CustomAdapt;
39 | import xyz.doikki.videoplayer.util.CutoutUtil;
40 |
41 | /**
42 | * @author pj567
43 | * @date :2020/12/17
44 | * @description:
45 | */
46 | public abstract class BaseActivity extends AppCompatActivity implements CustomAdapt {
47 | protected Context mContext;
48 | private LoadService mLoadService;
49 |
50 | private static float screenRatio = -100.0f;
51 |
52 | // takagen99 : Fix for Locale change not persist on higher Android version
53 | @Override
54 | protected void attachBaseContext(Context base) {
55 | if (Hawk.get(HawkConfig.HOME_LOCALE, 0) == 0) {
56 | super.attachBaseContext(LocaleHelper.onAttach(base, "zh"));
57 | } else {
58 | super.attachBaseContext(LocaleHelper.onAttach(base, ""));
59 | }
60 | }
61 |
62 | @Override
63 | protected void onCreate(@Nullable Bundle savedInstanceState) {
64 | try {
65 | if (screenRatio < 0) {
66 | DisplayMetrics dm = new DisplayMetrics();
67 | getWindowManager().getDefaultDisplay().getMetrics(dm);
68 | int screenWidth = dm.widthPixels;
69 | int screenHeight = dm.heightPixels;
70 | screenRatio = (float) Math.max(screenWidth, screenHeight) / (float) Math.min(screenWidth, screenHeight);
71 | }
72 | } catch (Throwable th) {
73 | th.printStackTrace();
74 | }
75 |
76 | // takagen99 : Set Theme Color
77 | if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 0) {
78 | setTheme(R.style.NetfxTheme);
79 | } else if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 1) {
80 | setTheme(R.style.DoraeTheme);
81 | } else if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 2) {
82 | setTheme(R.style.PepsiTheme);
83 | } else if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 3) {
84 | setTheme(R.style.NarutoTheme);
85 | } else if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 4) {
86 | setTheme(R.style.MinionTheme);
87 | } else if (Hawk.get(HawkConfig.THEME_SELECT, 0) == 5) {
88 | setTheme(R.style.YagamiTheme);
89 | } else {
90 | setTheme(R.style.SakuraTheme);
91 | }
92 |
93 | super.onCreate(savedInstanceState);
94 | setContentView(getLayoutResID());
95 | mContext = this;
96 | CutoutUtil.adaptCutoutAboveAndroidP(mContext, true);//设置刘海
97 | AppManager.getInstance().addActivity(this);
98 | init();
99 | setScreenOn();
100 | }
101 |
102 | @Override
103 | protected void onResume() {
104 | super.onResume();
105 | hideSystemUI(true);
106 | changeWallpaper(false);
107 | }
108 |
109 | // takagen99 : Check for Gesture or 3-Buttons NavBar
110 | // 0 : 3-Button NavBar
111 | // 1 : 2-Button NavBar (Android P)
112 | // 2 : Gesture full screen
113 | public static int isEdgeToEdgeEnabled(Context context) {
114 | Resources resources = context.getResources();
115 | int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
116 | if (resourceId > 0) {
117 | return resources.getInteger(resourceId);
118 | }
119 | return 0;
120 | }
121 |
122 | public void hideSysBar() {
123 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
124 | int uiOptions = getWindow().getDecorView().getSystemUiVisibility();
125 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
126 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
127 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
128 | uiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
129 | uiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
130 | uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
131 | getWindow().getDecorView().setSystemUiVisibility(uiOptions);
132 | }
133 | }
134 |
135 | public void vidHideSysBar() {
136 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
137 | int uiOptions = getWindow().getDecorView().getSystemUiVisibility();
138 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
139 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
140 | uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
141 | uiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
142 | uiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
143 | uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
144 | getWindow().getDecorView().setSystemUiVisibility(uiOptions);
145 | }
146 | }
147 |
148 | public void hideSystemUI(boolean shownavbar) {
149 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
150 | int uiVisibility = getWindow().getDecorView().getSystemUiVisibility();
151 | uiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
152 | uiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
153 | uiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
154 | uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE;
155 | uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
156 | if (!shownavbar) {
157 | uiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
158 | uiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
159 | }
160 | getWindow().getDecorView().setSystemUiVisibility(uiVisibility);
161 | // set content behind navigation bar
162 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
163 | }
164 | }
165 |
166 | public void showSystemUI() {
167 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
168 | int uiVisibility = getWindow().getDecorView().getSystemUiVisibility();
169 | uiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
170 | uiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
171 | uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE;
172 | uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
173 | uiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
174 | uiVisibility &= ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
175 | getWindow().getDecorView().setSystemUiVisibility(uiVisibility);
176 | }
177 | }
178 |
179 | @Override
180 | public Resources getResources() {
181 | if (Looper.myLooper() == Looper.getMainLooper()) {
182 | AutoSizeCompat.autoConvertDensityOfCustomAdapt(super.getResources(), this);
183 | }
184 | return super.getResources();
185 | }
186 |
187 | public boolean hasPermission(String permission) {
188 | boolean has = true;
189 | try {
190 | has = PermissionChecker.checkSelfPermission(this, permission) == PermissionChecker.PERMISSION_GRANTED;
191 | } catch (Exception e) {
192 | e.printStackTrace();
193 | }
194 | return has;
195 | }
196 |
197 | protected abstract int getLayoutResID();
198 |
199 | protected abstract void init();
200 |
201 | protected void setLoadSir(View view) {
202 | if (mLoadService == null) {
203 | mLoadService = LoadSir.getDefault().register(view, new Callback.OnReloadListener() {
204 | @Override
205 | public void onReload(View v) {
206 | }
207 | });
208 | }
209 | }
210 |
211 | protected void showLoading() {
212 | if (mLoadService != null) {
213 | mLoadService.showCallback(LoadingCallback.class);
214 | }
215 | }
216 |
217 | protected void showEmpty() {
218 | if (null != mLoadService) {
219 | mLoadService.showCallback(EmptyCallback.class);
220 | }
221 | }
222 |
223 | protected void showSuccess() {
224 | if (null != mLoadService) {
225 | mLoadService.showSuccess();
226 | }
227 | }
228 |
229 | @Override
230 | protected void onDestroy() {
231 | super.onDestroy();
232 | AppManager.getInstance().finishActivity(this);
233 | }
234 |
235 | public void jumpActivity(Class extends BaseActivity> clazz) {
236 | Intent intent = new Intent(mContext, clazz);
237 | startActivity(intent);
238 | }
239 |
240 | public void jumpActivity(Class extends BaseActivity> clazz, Bundle bundle) {
241 | Intent intent = new Intent(mContext, clazz);
242 | intent.putExtras(bundle);
243 | startActivity(intent);
244 | }
245 |
246 | protected String getAssetText(String fileName) {
247 | StringBuilder stringBuilder = new StringBuilder();
248 | try {
249 | AssetManager assets = getAssets();
250 | BufferedReader bf = new BufferedReader(new InputStreamReader(assets.open(fileName)));
251 | String line;
252 | while ((line = bf.readLine()) != null) {
253 | stringBuilder.append(line);
254 | }
255 | return stringBuilder.toString();
256 | } catch (IOException e) {
257 | e.printStackTrace();
258 | }
259 | return "";
260 | }
261 |
262 | @Override
263 | public float getSizeInDp() {
264 | return isBaseOnWidth() ? 1280 : 720;
265 | }
266 |
267 | @Override
268 | public boolean isBaseOnWidth() {
269 | return !(screenRatio >= 4.0f);
270 | }
271 |
272 | public boolean supportsPiPMode() {
273 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
274 | }
275 |
276 | public boolean supportsTouch() {
277 | return getPackageManager().hasSystemFeature("android.hardware.touchscreen");
278 | }
279 |
280 | public void setScreenBrightness(float amt) {
281 | WindowManager.LayoutParams lparams = getWindow().getAttributes();
282 | lparams.screenBrightness = amt;
283 | getWindow().setAttributes(lparams);
284 | }
285 |
286 | public void setScreenOn() {
287 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
288 | }
289 |
290 | public void setScreenOff() {
291 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
292 | }
293 |
294 | // takagen99: Added Theme Color
295 | public int getThemeColor() {
296 | TypedArray a = mContext.obtainStyledAttributes(R.styleable.themeColor);
297 | int themeColor = a.getColor(R.styleable.themeColor_color_theme, 0);
298 | return themeColor;
299 | }
300 |
301 | protected static BitmapDrawable globalWp = null;
302 |
303 | public void changeWallpaper(boolean force) {
304 | if (!force && globalWp != null) {
305 | getWindow().setBackgroundDrawable(globalWp);
306 | return;
307 | }
308 | try {
309 | File wp = new File(getFilesDir().getAbsolutePath() + "/wp");
310 | if (wp.exists()) {
311 | BitmapFactory.Options opts = new BitmapFactory.Options();
312 | opts.inJustDecodeBounds = true;
313 | BitmapFactory.decodeFile(wp.getAbsolutePath(), opts);
314 | // 从Options中获取图片的分辨率
315 | int imageHeight = opts.outHeight;
316 | int imageWidth = opts.outWidth;
317 | int picHeight = 720;
318 | int picWidth = 1080;
319 | int scaleX = imageWidth / picWidth;
320 | int scaleY = imageHeight / picHeight;
321 | int scale = Math.max(Math.max(scaleX, scaleY), 1);
322 | opts.inJustDecodeBounds = false;
323 | // 采样率
324 | opts.inSampleSize = scale;
325 | globalWp = new BitmapDrawable(BitmapFactory.decodeFile(wp.getAbsolutePath(), opts));
326 | } else {
327 | globalWp = null;
328 | }
329 | } catch (Throwable throwable) {
330 | throwable.printStackTrace();
331 | globalWp = null;
332 | }
333 | if (globalWp != null) {
334 | getWindow().setBackgroundDrawable(globalWp);
335 | } else {
336 | getWindow().setBackgroundDrawableResource(R.drawable.app_bg);
337 | }
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/DIY/T/HomeIconDialog.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.ui.dialog;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.TextView;
6 |
7 | import androidx.annotation.NonNull;
8 |
9 | import com.github.tvbox.osc.R;
10 | import com.github.tvbox.osc.util.FastClickCheckUtil;
11 | import com.github.tvbox.osc.util.HawkConfig;
12 | import com.orhanobut.hawk.Hawk;
13 |
14 | import org.jetbrains.annotations.NotNull;
15 |
16 | /**
17 | * 描述
18 | *
19 | * @author pj567
20 | * @since 2020/12/27
21 | */
22 | public class HomeIconDialog extends BaseDialog {
23 | private final TextView tvHomeSearch;
24 | private final TextView tvHomeMenu;
25 |
26 | public HomeIconDialog(@NonNull @NotNull Context context) {
27 | super(context);
28 | setContentView(R.layout.dialog_homeoption);
29 | setCanceledOnTouchOutside(true);
30 | tvHomeSearch = findViewById(R.id.tvHomeSearch);
31 | tvHomeSearch.setText(Hawk.get(HawkConfig.HOME_SEARCH_POSITION, true) ? "上方" : "下方");
32 | tvHomeMenu = findViewById(R.id.tvHomeMenu);
33 | tvHomeMenu.setText(Hawk.get(HawkConfig.HOME_MENU_POSITION, true) ? "上方" : "下方");
34 |
35 | findViewById(R.id.llSearch).setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | FastClickCheckUtil.check(v);
39 | Hawk.put(HawkConfig.HOME_SEARCH_POSITION, !Hawk.get(HawkConfig.HOME_SEARCH_POSITION, true));
40 | tvHomeSearch.setText(Hawk.get(HawkConfig.HOME_SEARCH_POSITION, false) ? "上方" : "下方");
41 | }
42 | });
43 | findViewById(R.id.llMenu).setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | FastClickCheckUtil.check(v);
47 | Hawk.put(HawkConfig.HOME_MENU_POSITION, !Hawk.get(HawkConfig.HOME_MENU_POSITION, true));
48 | tvHomeMenu.setText(Hawk.get(HawkConfig.HOME_MENU_POSITION, false) ? "上方" : "下方");
49 | }
50 | });
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/DIY/T/SearchActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.ui.activity;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.graphics.Rect;
7 | import android.os.Bundle;
8 | import android.text.TextUtils;
9 | import android.view.KeyEvent;
10 | import android.view.View;
11 | import android.view.inputmethod.InputMethodManager;
12 | import android.widget.EditText;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 | import android.widget.TextView;
16 | import android.widget.Toast;
17 |
18 | import androidx.lifecycle.ViewModelProvider;
19 |
20 | import com.chad.library.adapter.base.BaseQuickAdapter;
21 | import com.github.tvbox.osc.R;
22 | import com.github.tvbox.osc.api.ApiConfig;
23 | import com.github.tvbox.osc.base.BaseActivity;
24 | import com.github.tvbox.osc.bean.AbsXml;
25 | import com.github.tvbox.osc.bean.Movie;
26 | import com.github.tvbox.osc.bean.SourceBean;
27 | import com.github.tvbox.osc.event.RefreshEvent;
28 | import com.github.tvbox.osc.event.ServerEvent;
29 | import com.github.tvbox.osc.server.ControlManager;
30 | import com.github.tvbox.osc.ui.adapter.PinyinAdapter;
31 | import com.github.tvbox.osc.ui.adapter.SearchAdapter;
32 | import com.github.tvbox.osc.ui.dialog.RemoteDialog;
33 | import com.github.tvbox.osc.ui.dialog.SearchCheckboxDialog;
34 | import com.github.tvbox.osc.ui.tv.QRCodeGen;
35 | import com.github.tvbox.osc.ui.tv.widget.SearchKeyboard;
36 | import com.github.tvbox.osc.util.FastClickCheckUtil;
37 | import com.github.tvbox.osc.util.HawkConfig;
38 | import com.github.tvbox.osc.util.SearchHelper;
39 | import com.github.tvbox.osc.util.js.JSEngine;
40 | import com.github.tvbox.osc.viewmodel.SourceViewModel;
41 | import com.google.gson.JsonArray;
42 | import com.google.gson.JsonElement;
43 | import com.google.gson.JsonObject;
44 | import com.google.gson.JsonParser;
45 | import com.lzy.okgo.OkGo;
46 | import com.lzy.okgo.callback.AbsCallback;
47 | import com.lzy.okgo.model.Response;
48 | import com.orhanobut.hawk.Hawk;
49 | import com.owen.tvrecyclerview.widget.TvRecyclerView;
50 | import com.owen.tvrecyclerview.widget.V7GridLayoutManager;
51 | import com.owen.tvrecyclerview.widget.V7LinearLayoutManager;
52 |
53 | import org.greenrobot.eventbus.EventBus;
54 | import org.greenrobot.eventbus.Subscribe;
55 | import org.greenrobot.eventbus.ThreadMode;
56 |
57 | import java.util.ArrayList;
58 | import java.util.Arrays;
59 | import java.util.HashMap;
60 | import java.util.List;
61 | import java.util.concurrent.ExecutorService;
62 | import java.util.concurrent.Executors;
63 | import java.util.concurrent.atomic.AtomicInteger;
64 |
65 | /**
66 | * @author pj567
67 | * @date :2020/12/23
68 | * @description:
69 | */
70 | public class SearchActivity extends BaseActivity {
71 | private LinearLayout llLayout;
72 | private TvRecyclerView mGridView;
73 | private TvRecyclerView mGridViewWord;
74 | SourceViewModel sourceViewModel;
75 | private EditText etSearch;
76 | private TextView tvSearch;
77 | private TextView tvClear;
78 | private SearchKeyboard keyboard;
79 | private TextView tvAddress;
80 | private ImageView ivQRCode;
81 | private SearchAdapter searchAdapter;
82 | private PinyinAdapter wordAdapter;
83 | private String searchTitle = "";
84 | private ImageView tvSearchCheckbox;
85 | private static HashMap mCheckSources = null;
86 | private SearchCheckboxDialog mSearchCheckboxDialog = null;
87 |
88 | @Override
89 | protected int getLayoutResID() {
90 | return R.layout.activity_search;
91 | }
92 |
93 | @Override
94 | protected void init() {
95 | initView();
96 | initViewModel();
97 | initData();
98 | }
99 |
100 | private List pauseRunnable = null;
101 |
102 | @Override
103 | protected void onResume() {
104 | super.onResume();
105 | if (pauseRunnable != null && pauseRunnable.size() > 0) {
106 | searchExecutorService = Executors.newFixedThreadPool(5);
107 | allRunCount.set(pauseRunnable.size());
108 | for (Runnable runnable : pauseRunnable) {
109 | searchExecutorService.execute(runnable);
110 | }
111 | pauseRunnable.clear();
112 | pauseRunnable = null;
113 | }
114 | }
115 |
116 | private boolean isKeyboardHidden() {
117 | final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
118 | Rect r = new Rect();
119 | rootView.getWindowVisibleDisplayFrame(r);
120 | return rootView.getBottom() == r.bottom;
121 | }
122 |
123 | private void initView() {
124 | EventBus.getDefault().register(this);
125 | llLayout = findViewById(R.id.llLayout);
126 | etSearch = findViewById(R.id.etSearch);
127 | tvSearch = findViewById(R.id.tvSearch);
128 | tvSearchCheckbox = findViewById(R.id.tvSearchCheckbox);
129 | tvClear = findViewById(R.id.tvClear);
130 | tvAddress = findViewById(R.id.tvAddress);
131 | ivQRCode = findViewById(R.id.ivQRCode);
132 | mGridView = findViewById(R.id.mGridView);
133 | keyboard = findViewById(R.id.keyBoardRoot);
134 | mGridViewWord = findViewById(R.id.mGridViewWord);
135 | mGridViewWord.setHasFixedSize(true);
136 | mGridViewWord.setLayoutManager(new V7LinearLayoutManager(this.mContext, 1, false));
137 | wordAdapter = new PinyinAdapter();
138 | mGridViewWord.setAdapter(wordAdapter);
139 | // Allow Dpad Key switch to other focus
140 | etSearch.setOnKeyListener(new View.OnKeyListener() {
141 | @Override
142 | public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
143 | if (isKeyboardHidden()) {
144 | if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
145 | if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
146 | ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
147 | .showSoftInput(etSearch, 0);
148 | return false;
149 | }
150 | } else if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
151 | int len = etSearch.getText().length();
152 | if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
153 | // Avoid show ime keyboard bug
154 | return true;
155 | } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
156 | etSearch.focusSearch(View.FOCUS_DOWN).requestFocus();
157 | return true;
158 | } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && (len == 0 || etSearch.getSelectionStart() == len)) {
159 | etSearch.focusSearch(View.FOCUS_RIGHT).requestFocus();
160 | return true;
161 | }
162 | }
163 | }
164 | return false;
165 | }
166 | });
167 | wordAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
168 | @Override
169 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
170 | search(wordAdapter.getItem(position));
171 | }
172 | });
173 | mGridView.setHasFixedSize(true);
174 | // lite
175 | if (Hawk.get(HawkConfig.SEARCH_VIEW, 0) == 0)
176 | mGridView.setLayoutManager(new V7LinearLayoutManager(this.mContext, 1, false));
177 | // with preview
178 | else
179 | mGridView.setLayoutManager(new V7GridLayoutManager(this.mContext, 3));
180 | searchAdapter = new SearchAdapter();
181 | mGridView.setAdapter(searchAdapter);
182 | searchAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
183 | @Override
184 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
185 | FastClickCheckUtil.check(view);
186 | Movie.Video video = searchAdapter.getData().get(position);
187 | if (video != null) {
188 | try {
189 | if (searchExecutorService != null) {
190 | pauseRunnable = searchExecutorService.shutdownNow();
191 | searchExecutorService = null;
192 | JSEngine.getInstance().stopAll();
193 | }
194 | } catch (Throwable th) {
195 | th.printStackTrace();
196 | }
197 | Bundle bundle = new Bundle();
198 | bundle.putString("id", video.id);
199 | bundle.putString("sourceKey", video.sourceKey);
200 | jumpActivity(DetailActivity.class, bundle);
201 | }
202 | }
203 | });
204 | tvSearch.setOnClickListener(new View.OnClickListener() {
205 | @Override
206 | public void onClick(View v) {
207 | FastClickCheckUtil.check(v);
208 | String wd = etSearch.getText().toString().trim();
209 | if (!TextUtils.isEmpty(wd)) {
210 | search(wd);
211 | } else {
212 | Toast.makeText(mContext, getString(R.string.search_input), Toast.LENGTH_SHORT).show();
213 | }
214 | }
215 | });
216 | tvClear.setOnClickListener(new View.OnClickListener() {
217 | @Override
218 | public void onClick(View v) {
219 | FastClickCheckUtil.check(v);
220 | etSearch.setText("");
221 | }
222 | });
223 | keyboard.setOnSearchKeyListener(new SearchKeyboard.OnSearchKeyListener() {
224 | @Override
225 | public void onSearchKey(int pos, String key) {
226 | if (pos > 1) {
227 | String text = etSearch.getText().toString().trim();
228 | text += key;
229 | etSearch.setText(text);
230 | if (text.length() > 0) {
231 | loadRec(text);
232 | }
233 | } else if (pos == 1) {
234 | String text = etSearch.getText().toString().trim();
235 | if (text.length() > 0) {
236 | text = text.substring(0, text.length() - 1);
237 | etSearch.setText(text);
238 | }
239 | if (text.length() > 0) {
240 | loadRec(text);
241 | }
242 | } else if (pos == 0) {
243 | RemoteDialog remoteDialog = new RemoteDialog(mContext);
244 | remoteDialog.show();
245 | }
246 | }
247 | });
248 | tvSearchCheckbox.setOnClickListener(new View.OnClickListener() {
249 | @Override
250 | public void onClick(View view) {
251 | if (mSearchCheckboxDialog == null) {
252 | List allSourceBean = ApiConfig.get().getSourceBeanList();
253 | List searchAbleSource = new ArrayList<>();
254 | for (SourceBean sourceBean : allSourceBean) {
255 | if (sourceBean.isSearchable()) {
256 | searchAbleSource.add(sourceBean);
257 | }
258 | }
259 | mSearchCheckboxDialog = new SearchCheckboxDialog(SearchActivity.this, searchAbleSource, mCheckSources);
260 | }
261 | mSearchCheckboxDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
262 | @Override
263 | public void onDismiss(DialogInterface dialog) {
264 | dialog.dismiss();
265 | }
266 | });
267 | mSearchCheckboxDialog.show();
268 | }
269 | });
270 | setLoadSir(llLayout);
271 | }
272 |
273 | private void initViewModel() {
274 | sourceViewModel = new ViewModelProvider(this).get(SourceViewModel.class);
275 | }
276 |
277 | /**
278 | * 拼音联想
279 | */
280 | private void loadRec(String key) {
281 | // OkGo.get("https://s.video.qq.com/smartbox")
282 | // .params("plat", 2)
283 | // .params("ver", 0)
284 | // .params("num", 10)
285 | // .params("otype", "json")
286 | // .params("query", key)
287 | // .execute(new AbsCallback() {
288 | // @Override
289 | // public void onSuccess(Response response) {
290 | // try {
291 | // ArrayList hots = new ArrayList<>();
292 | // String result = response.body();
293 | // JsonObject json = JsonParser.parseString(result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1)).getAsJsonObject();
294 | // JsonArray itemList = json.get("item").getAsJsonArray();
295 | // for (JsonElement ele : itemList) {
296 | // JsonObject obj = (JsonObject) ele;
297 | // hots.add(obj.get("word").getAsString().trim());
298 | // }
299 | // wordAdapter.setNewData(hots);
300 | // } catch (Throwable th) {
301 | // th.printStackTrace();
302 | // }
303 | // }
304 |
305 | // @Override
306 | // public String convertResponse(okhttp3.Response response) throws Throwable {
307 | // return response.body().string();
308 | // }
309 | // });
310 | OkGo.get("https://suggest.video.iqiyi.com/")
311 | .params("if", "mobile")
312 | .params("key", key)
313 | .execute(new AbsCallback() {
314 | @Override
315 | public void onSuccess(Response response) {
316 | try {
317 | ArrayList hots = new ArrayList<>();
318 | String result = response.body();
319 | JsonObject json = JsonParser.parseString(result).getAsJsonObject();
320 | JsonArray itemList = json.get("data").getAsJsonArray();
321 | for (JsonElement ele : itemList) {
322 | JsonObject obj = (JsonObject) ele;
323 | hots.add(obj.get("name").getAsString().trim().replaceAll("<|>|《|》|-", ""));
324 | }
325 | wordAdapter.setNewData(hots);
326 | } catch (Throwable th) {
327 | th.printStackTrace();
328 | }
329 | }
330 |
331 | @Override
332 | public String convertResponse(okhttp3.Response response) throws Throwable {
333 | return response.body().string();
334 | }
335 | });
336 |
337 | }
338 |
339 | private void initData() {
340 | refreshQRCode();
341 | initCheckedSourcesForSearch();
342 | Intent intent = getIntent();
343 | if (intent != null && intent.hasExtra("title")) {
344 | String title = intent.getStringExtra("title");
345 | showLoading();
346 | search(title);
347 | }
348 | // 加载热词
349 | loadHotSearch();
350 | }
351 |
352 | //load hot search
353 | private void loadHotSearch() {
354 | OkGo.get("https://node.video.qq.com/x/api/hot_search")
355 | .params("channdlId", "0")
356 | .params("_", System.currentTimeMillis())
357 | .execute(new AbsCallback() {
358 | @Override
359 | public void onSuccess(Response response) {
360 | try {
361 | ArrayList hots = new ArrayList<>();
362 | JsonObject mapResult = JsonParser.parseString(response.body())
363 | .getAsJsonObject()
364 | .get("data").getAsJsonObject()
365 | .get("mapResult").getAsJsonObject();
366 | List groupIndex = Arrays.asList("0", "1", "2", "3", "5");
367 | for (String index : groupIndex) {
368 | JsonArray itemList = mapResult.get(index).getAsJsonObject()
369 | .get("listInfo").getAsJsonArray();
370 | for (JsonElement ele : itemList) {
371 | JsonObject obj = (JsonObject) ele;
372 | String hotKey = obj.get("title").getAsString().trim().replaceAll("<|>|《|》|-", "").split(" ")[0];
373 | if (!hots.contains(hotKey))
374 | hots.add(hotKey);
375 | }
376 | }
377 |
378 | wordAdapter.setNewData(hots);
379 | } catch (Throwable th) {
380 | th.printStackTrace();
381 | }
382 | }
383 |
384 | @Override
385 | public String convertResponse(okhttp3.Response response) throws Throwable {
386 | return response.body().string();
387 | }
388 | });
389 | }
390 |
391 | private void refreshQRCode() {
392 | String address = ControlManager.get().getAddress(false);
393 | tvAddress.setText(String.format("远程搜索使用手机/电脑扫描下面二维码或者直接浏览器访问地址\n%s", address));
394 | ivQRCode.setImageBitmap(QRCodeGen.generateBitmap(address, 300, 300));
395 | }
396 |
397 | @Subscribe(threadMode = ThreadMode.MAIN)
398 | public void server(ServerEvent event) {
399 | if (event.type == ServerEvent.SERVER_SEARCH) {
400 | String title = (String) event.obj;
401 | showLoading();
402 | search(title);
403 | }
404 | }
405 |
406 | @Subscribe(threadMode = ThreadMode.MAIN)
407 | public void refresh(RefreshEvent event) {
408 | if (event.type == RefreshEvent.TYPE_SEARCH_RESULT) {
409 | try {
410 | searchData(event.obj == null ? null : (AbsXml) event.obj);
411 | } catch (Exception e) {
412 | searchData(null);
413 | }
414 | }
415 | }
416 |
417 | private void initCheckedSourcesForSearch() {
418 | mCheckSources = SearchHelper.getSourcesForSearch();
419 | }
420 |
421 | public static void setCheckedSourcesForSearch(HashMap checkedSources) {
422 | mCheckSources = checkedSources;
423 | }
424 |
425 | private void search(String title) {
426 | cancel();
427 | showLoading();
428 | this.searchTitle = title;
429 | mGridView.setVisibility(View.INVISIBLE);
430 | searchAdapter.setNewData(new ArrayList<>());
431 | searchResult();
432 | }
433 |
434 | private ExecutorService searchExecutorService = null;
435 | private final AtomicInteger allRunCount = new AtomicInteger(0);
436 |
437 | private void searchResult() {
438 | try {
439 | if (searchExecutorService != null) {
440 | searchExecutorService.shutdownNow();
441 | searchExecutorService = null;
442 | JSEngine.getInstance().stopAll();
443 | }
444 | } catch (Throwable th) {
445 | th.printStackTrace();
446 | } finally {
447 | searchAdapter.setNewData(new ArrayList<>());
448 | allRunCount.set(0);
449 | }
450 | searchExecutorService = Executors.newFixedThreadPool(5);
451 | List searchRequestList = new ArrayList<>();
452 | searchRequestList.addAll(ApiConfig.get().getSourceBeanList());
453 | SourceBean home = ApiConfig.get().getHomeSourceBean();
454 | searchRequestList.remove(home);
455 | searchRequestList.add(0, home);
456 |
457 | ArrayList siteKey = new ArrayList<>();
458 | for (SourceBean bean : searchRequestList) {
459 | if (!bean.isSearchable()) {
460 | continue;
461 | }
462 | if (mCheckSources != null && !mCheckSources.containsKey(bean.getKey())) {
463 | continue;
464 | }
465 | siteKey.add(bean.getKey());
466 | allRunCount.incrementAndGet();
467 | }
468 | if (siteKey.size() <= 0) {
469 | Toast.makeText(mContext, getString(R.string.search_site), Toast.LENGTH_SHORT).show();
470 | showEmpty();
471 | return;
472 | }
473 | for (String key : siteKey) {
474 | searchExecutorService.execute(new Runnable() {
475 | @Override
476 | public void run() {
477 | sourceViewModel.getSearch(key, searchTitle);
478 | }
479 | });
480 | }
481 | }
482 |
483 | private boolean matchSearchResult(String name, String searchTitle) {
484 | if (TextUtils.isEmpty(name) || TextUtils.isEmpty(searchTitle)) return false;
485 | searchTitle = searchTitle.trim();
486 | String[] arr = searchTitle.split("\\s+");
487 | int matchNum = 0;
488 | for (String one : arr) {
489 | if (name.contains(one)) matchNum++;
490 | }
491 | return matchNum == arr.length;
492 | }
493 |
494 | private void searchData(AbsXml absXml) {
495 | if (absXml != null && absXml.movie != null && absXml.movie.videoList != null && absXml.movie.videoList.size() > 0) {
496 | List data = new ArrayList<>();
497 | for (Movie.Video video : absXml.movie.videoList) {
498 | data.add(video);
499 | }
500 | if (searchAdapter.getData().size() > 0) {
501 | searchAdapter.addData(data);
502 | } else {
503 | showSuccess();
504 | mGridView.setVisibility(View.VISIBLE);
505 | searchAdapter.setNewData(data);
506 | }
507 | }
508 |
509 | int count = allRunCount.decrementAndGet();
510 | if (count <= 0) {
511 | if (searchAdapter.getData().size() <= 0) {
512 | showEmpty();
513 | }
514 | cancel();
515 | }
516 | }
517 |
518 | private void cancel() {
519 | OkGo.getInstance().cancelTag("search");
520 | }
521 |
522 | @Override
523 | protected void onDestroy() {
524 | super.onDestroy();
525 | cancel();
526 | try {
527 | if (searchExecutorService != null) {
528 | searchExecutorService.shutdownNow();
529 | searchExecutorService = null;
530 | JSEngine.getInstance().stopAll();
531 | }
532 | } catch (Throwable th) {
533 | th.printStackTrace();
534 | }
535 | EventBus.getDefault().unregister(this);
536 | }
537 | }
538 |
--------------------------------------------------------------------------------
/DIY/T/UserFragment.java:
--------------------------------------------------------------------------------
1 | package com.github.tvbox.osc.ui.fragment;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.view.animation.BounceInterpolator;
7 | import android.widget.LinearLayout;
8 | import android.widget.Toast;
9 |
10 | import com.chad.library.adapter.base.BaseQuickAdapter;
11 | import com.github.tvbox.osc.R;
12 | import com.github.tvbox.osc.api.ApiConfig;
13 | import com.github.tvbox.osc.base.BaseLazyFragment;
14 | import com.github.tvbox.osc.bean.Movie;
15 | import com.github.tvbox.osc.bean.VodInfo;
16 | import com.github.tvbox.osc.cache.RoomDataManger;
17 | import com.github.tvbox.osc.event.ServerEvent;
18 | import com.github.tvbox.osc.ui.activity.CollectActivity;
19 | import com.github.tvbox.osc.ui.activity.DetailActivity;
20 | import com.github.tvbox.osc.ui.activity.DriveActivity;
21 | import com.github.tvbox.osc.ui.activity.FastSearchActivity;
22 | import com.github.tvbox.osc.ui.activity.HistoryActivity;
23 | import com.github.tvbox.osc.ui.activity.LivePlayActivity;
24 | import com.github.tvbox.osc.ui.activity.PushActivity;
25 | import com.github.tvbox.osc.ui.activity.SearchActivity;
26 | import com.github.tvbox.osc.ui.activity.SettingActivity;
27 | import com.github.tvbox.osc.ui.adapter.HomeHotVodAdapter;
28 | import com.github.tvbox.osc.util.FastClickCheckUtil;
29 | import com.github.tvbox.osc.util.HawkConfig;
30 | import com.google.gson.Gson;
31 | import com.google.gson.JsonArray;
32 | import com.google.gson.JsonElement;
33 | import com.google.gson.JsonObject;
34 | import com.lzy.okgo.OkGo;
35 | import com.lzy.okgo.callback.AbsCallback;
36 | import com.lzy.okgo.model.Response;
37 | import com.orhanobut.hawk.Hawk;
38 | import com.owen.tvrecyclerview.widget.TvRecyclerView;
39 | import com.owen.tvrecyclerview.widget.V7GridLayoutManager;
40 |
41 | import org.greenrobot.eventbus.EventBus;
42 | import org.greenrobot.eventbus.Subscribe;
43 | import org.greenrobot.eventbus.ThreadMode;
44 |
45 | import java.util.ArrayList;
46 | import java.util.Calendar;
47 | import java.util.List;
48 |
49 | /**
50 | * @author pj567
51 | * @date :2021/3/9
52 | * @description:
53 | */
54 | public class UserFragment extends BaseLazyFragment implements View.OnClickListener {
55 | private LinearLayout tvDrive;
56 | private LinearLayout tvLive;
57 | private LinearLayout tvSearch;
58 | private LinearLayout tvSetting;
59 | private LinearLayout tvHistory;
60 | private LinearLayout tvCollect;
61 | private LinearLayout tvPush;
62 | public static HomeHotVodAdapter homeHotVodAdapter;
63 | private List homeSourceRec;
64 | public static TvRecyclerView tvHotListForGrid;
65 | public static TvRecyclerView tvHotListForLine;
66 |
67 | public static UserFragment newInstance() {
68 | return new UserFragment();
69 | }
70 |
71 | public static UserFragment newInstance(List recVod) {
72 | return new UserFragment().setArguments(recVod);
73 | }
74 |
75 | public UserFragment setArguments(List recVod) {
76 | this.homeSourceRec = recVod;
77 | return this;
78 | }
79 |
80 | @Override
81 | public void onFragmentResume() {
82 |
83 | // takagen99: Initialize Icon Placement
84 | if (!Hawk.get(HawkConfig.HOME_SEARCH_POSITION, true)) {
85 | tvSearch.setVisibility(View.VISIBLE);
86 | } else {
87 | tvSearch.setVisibility(View.GONE);
88 | }
89 | if (!Hawk.get(HawkConfig.HOME_MENU_POSITION, true)) {
90 | tvSetting.setVisibility(View.VISIBLE);
91 | } else {
92 | tvSetting.setVisibility(View.GONE);
93 | }
94 |
95 | super.onFragmentResume();
96 | if (Hawk.get(HawkConfig.HOME_REC, 0) == 2) {
97 | List allVodRecord = RoomDataManger.getAllVodRecord(20);
98 | List vodList = new ArrayList<>();
99 | for (VodInfo vodInfo : allVodRecord) {
100 | Movie.Video vod = new Movie.Video();
101 | vod.id = vodInfo.id;
102 | vod.sourceKey = vodInfo.sourceKey;
103 | vod.name = vodInfo.name;
104 | vod.pic = vodInfo.pic;
105 | if (vodInfo.playNote != null && !vodInfo.playNote.isEmpty())
106 | vod.note = "上次看到" + vodInfo.playNote;
107 | vodList.add(vod);
108 | }
109 | homeHotVodAdapter.setNewData(vodList);
110 | }
111 | }
112 |
113 | @Override
114 | protected int getLayoutResID() {
115 | return R.layout.fragment_user;
116 | }
117 |
118 | @Override
119 | protected void init() {
120 | EventBus.getDefault().register(this);
121 | tvDrive = findViewById(R.id.tvDrive);
122 | tvLive = findViewById(R.id.tvLive);
123 | tvSearch = findViewById(R.id.tvSearch);
124 | tvSetting = findViewById(R.id.tvSetting);
125 | tvCollect = findViewById(R.id.tvFavorite);
126 | tvHistory = findViewById(R.id.tvHistory);
127 | tvPush = findViewById(R.id.tvPush);
128 | tvDrive.setOnClickListener(this);
129 | tvLive.setOnClickListener(this);
130 | tvSearch.setOnClickListener(this);
131 | tvSetting.setOnClickListener(this);
132 | tvHistory.setOnClickListener(this);
133 | tvPush.setOnClickListener(this);
134 | tvCollect.setOnClickListener(this);
135 | tvDrive.setOnFocusChangeListener(focusChangeListener);
136 | tvLive.setOnFocusChangeListener(focusChangeListener);
137 | tvSearch.setOnFocusChangeListener(focusChangeListener);
138 | tvSetting.setOnFocusChangeListener(focusChangeListener);
139 | tvHistory.setOnFocusChangeListener(focusChangeListener);
140 | tvPush.setOnFocusChangeListener(focusChangeListener);
141 | tvCollect.setOnFocusChangeListener(focusChangeListener);
142 | tvHotListForLine = findViewById(R.id.tvHotListForLine);
143 | tvHotListForGrid = findViewById(R.id.tvHotListForGrid);
144 | tvHotListForGrid.setHasFixedSize(true);
145 | tvHotListForGrid.setLayoutManager(new V7GridLayoutManager(this.mContext, 5));
146 | homeHotVodAdapter = new HomeHotVodAdapter();
147 | homeHotVodAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
148 | @Override
149 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
150 | if (ApiConfig.get().getSourceBeanList().isEmpty())
151 | return;
152 | Movie.Video vod = ((Movie.Video) adapter.getItem(position));
153 |
154 | // takagen99: CHeck if in Delete Mode
155 | if ((vod.id != null && !vod.id.isEmpty()) && (Hawk.get(HawkConfig.HOME_REC, 0) == 2) && HawkConfig.hotVodDelete) {
156 | homeHotVodAdapter.remove(position);
157 | VodInfo vodInfo = RoomDataManger.getVodInfo(vod.sourceKey, vod.id);
158 | RoomDataManger.deleteVodRecord(vod.sourceKey, vodInfo);
159 | Toast.makeText(mContext, getString(R.string.hm_hist_del), Toast.LENGTH_SHORT).show();
160 | } else if (vod.id != null && !vod.id.isEmpty()) {
161 | Bundle bundle = new Bundle();
162 | bundle.putString("id", vod.id);
163 | bundle.putString("sourceKey", vod.sourceKey);
164 | if (vod.id.startsWith("msearch:")) {
165 | bundle.putString("title", vod.name);
166 | jumpActivity(FastSearchActivity.class, bundle);
167 | } else {
168 | jumpActivity(DetailActivity.class, bundle);
169 | }
170 | } else {
171 | Intent newIntent = new Intent(mContext, SearchActivity.class);
172 | newIntent.putExtra("title", vod.name);
173 | newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
174 | mActivity.startActivity(newIntent);
175 | }
176 | }
177 | });
178 | // takagen99 : Long press to trigger Delete Mode for VOD History on Home Page
179 | homeHotVodAdapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {
180 | @Override
181 | public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
182 | if (ApiConfig.get().getSourceBeanList().isEmpty())
183 | return false;
184 | Movie.Video vod = ((Movie.Video) adapter.getItem(position));
185 | // Additional Check if : Home Rec 0=豆瓣, 1=推荐, 2=历史
186 | if ((vod.id != null && !vod.id.isEmpty()) && (Hawk.get(HawkConfig.HOME_REC, 0) == 2)) {
187 | HawkConfig.hotVodDelete = !HawkConfig.hotVodDelete;
188 | homeHotVodAdapter.notifyDataSetChanged();
189 | } else {
190 | Intent newIntent = new Intent(mContext, FastSearchActivity.class);
191 | newIntent.putExtra("title", vod.name);
192 | newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
193 | mActivity.startActivity(newIntent);
194 | }
195 | return true;
196 | }
197 | });
198 | // Grid View
199 | tvHotListForGrid.setOnItemListener(new TvRecyclerView.OnItemListener() {
200 | @Override
201 | public void onItemPreSelected(TvRecyclerView parent, View itemView, int position) {
202 | itemView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
203 | }
204 |
205 | @Override
206 | public void onItemSelected(TvRecyclerView parent, View itemView, int position) {
207 | itemView.animate().scaleX(1.05f).scaleY(1.05f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
208 | }
209 |
210 | @Override
211 | public void onItemClick(TvRecyclerView parent, View itemView, int position) {
212 |
213 | }
214 | });
215 | tvHotListForGrid.setAdapter(homeHotVodAdapter);
216 | // Line View
217 | tvHotListForLine.setOnItemListener(new TvRecyclerView.OnItemListener() {
218 | @Override
219 | public void onItemPreSelected(TvRecyclerView parent, View itemView, int position) {
220 | itemView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
221 | }
222 |
223 | @Override
224 | public void onItemSelected(TvRecyclerView parent, View itemView, int position) {
225 | itemView.animate().scaleX(1.05f).scaleY(1.05f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
226 | }
227 |
228 | @Override
229 | public void onItemClick(TvRecyclerView parent, View itemView, int position) {
230 |
231 | }
232 | });
233 | tvHotListForLine.setAdapter(homeHotVodAdapter);
234 |
235 | initHomeHotVod(homeHotVodAdapter);
236 |
237 | // Swifly: Home Style
238 | if (Hawk.get(HawkConfig.HOME_REC_STYLE, false)) {
239 | tvHotListForGrid.setVisibility(View.VISIBLE);
240 | tvHotListForLine.setVisibility(View.GONE);
241 | } else {
242 | tvHotListForGrid.setVisibility(View.GONE);
243 | tvHotListForLine.setVisibility(View.VISIBLE);
244 | }
245 | }
246 |
247 | private void initHomeHotVod(HomeHotVodAdapter adapter) {
248 | if (Hawk.get(HawkConfig.HOME_REC, 0) == 1) {
249 | if (homeSourceRec != null) {
250 | adapter.setNewData(homeSourceRec);
251 | }
252 | return;
253 | } else if (Hawk.get(HawkConfig.HOME_REC, 0) == 2) {
254 | return;
255 | }
256 | try {
257 | Calendar cal = Calendar.getInstance();
258 | int year = cal.get(Calendar.YEAR);
259 | int month = cal.get(Calendar.MONTH) + 1;
260 | int day = cal.get(Calendar.DATE);
261 | String today = String.format("%d%d%d", year, month, day);
262 | String requestDay = Hawk.get("home_hot_day", "");
263 | if (requestDay.equals(today)) {
264 | String json = Hawk.get("home_hot", "");
265 | if (!json.isEmpty()) {
266 | adapter.setNewData(loadHots(json));
267 | return;
268 | }
269 | }
270 | OkGo.get("https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&playable=1&start=0&year_range=" + year + "," + year).execute(new AbsCallback() {
271 | @Override
272 | public void onSuccess(Response response) {
273 | String netJson = response.body();
274 | Hawk.put("home_hot_day", today);
275 | Hawk.put("home_hot", netJson);
276 | mActivity.runOnUiThread(new Runnable() {
277 | @Override
278 | public void run() {
279 | adapter.setNewData(loadHots(netJson));
280 | }
281 | });
282 | }
283 |
284 | @Override
285 | public String convertResponse(okhttp3.Response response) throws Throwable {
286 | return response.body().string();
287 | }
288 | });
289 | } catch (Throwable th) {
290 | th.printStackTrace();
291 | }
292 | }
293 |
294 | private ArrayList loadHots(String json) {
295 | ArrayList result = new ArrayList<>();
296 | try {
297 | JsonObject infoJson = new Gson().fromJson(json, JsonObject.class);
298 | JsonArray array = infoJson.getAsJsonArray("data");
299 | for (JsonElement ele : array) {
300 | JsonObject obj = (JsonObject) ele;
301 | Movie.Video vod = new Movie.Video();
302 | vod.name = obj.get("title").getAsString();
303 | vod.note = obj.get("rate").getAsString();
304 | vod.pic = obj.get("cover").getAsString();
305 | result.add(vod);
306 | }
307 | } catch (Throwable th) {
308 |
309 | }
310 | return result;
311 | }
312 |
313 | private final View.OnFocusChangeListener focusChangeListener = new View.OnFocusChangeListener() {
314 | @Override
315 | public void onFocusChange(View v, boolean hasFocus) {
316 | if (hasFocus)
317 | v.animate().scaleX(1.05f).scaleY(1.05f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
318 | else
319 | v.animate().scaleX(1.0f).scaleY(1.0f).setDuration(300).setInterpolator(new BounceInterpolator()).start();
320 | }
321 | };
322 |
323 | @Override
324 | public void onClick(View v) {
325 |
326 | // takagen99: Remove Delete Mode
327 | HawkConfig.hotVodDelete = false;
328 |
329 | FastClickCheckUtil.check(v);
330 | if (v.getId() == R.id.tvLive) {
331 | jumpActivity(LivePlayActivity.class);
332 | } else if (v.getId() == R.id.tvSearch) {
333 | jumpActivity(SearchActivity.class);
334 | } else if (v.getId() == R.id.tvSetting) {
335 | jumpActivity(SettingActivity.class);
336 | } else if (v.getId() == R.id.tvHistory) {
337 | jumpActivity(HistoryActivity.class);
338 | } else if (v.getId() == R.id.tvPush) {
339 | jumpActivity(PushActivity.class);
340 | } else if (v.getId() == R.id.tvFavorite) {
341 | jumpActivity(CollectActivity.class);
342 | } else if (v.getId() == R.id.tvDrive) {
343 | jumpActivity(DriveActivity.class);
344 | }
345 | }
346 |
347 | @Subscribe(threadMode = ThreadMode.MAIN)
348 | public void server(ServerEvent event) {
349 | if (event.type == ServerEvent.SERVER_CONNECTION) {
350 | }
351 | }
352 |
353 | @Override
354 | public void onDestroy() {
355 | super.onDestroy();
356 | EventBus.getDefault().unregister(this);
357 | }
358 | }
--------------------------------------------------------------------------------
/DIY/T/activity_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
21 |
22 |
31 |
32 |
49 |
50 |
63 |
64 |
79 |
80 |
94 |
95 |
109 |
110 |
124 |
125 |
140 |
141 |
156 |
157 |
158 |
159 |
170 |
171 |
180 |
181 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/DIY/T/fragment_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
19 |
20 |
21 |
30 |
31 |
43 |
44 |
51 |
52 |
65 |
66 |
67 |
68 |
79 |
80 |
87 |
88 |
101 |
102 |
103 |
104 |
115 |
116 |
123 |
124 |
137 |
138 |
139 |
140 |
151 |
152 |
159 |
160 |
173 |
174 |
175 |
176 |
187 |
188 |
195 |
196 |
209 |
210 |
211 |
212 |
223 |
224 |
231 |
232 |
245 |
246 |
247 |
248 |
259 |
260 |
267 |
268 |
281 |
282 |
283 |
284 |
285 |
286 |
304 |
305 |
321 |
322 |
323 |
324 |
--------------------------------------------------------------------------------
/DIY/TVBoxOSC.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoujck/DIY_TvBox/3720a887c9598f8e5bbf266a78c5693a9ca4feb9/DIY/TVBoxOSC.jks
--------------------------------------------------------------------------------
/DIY/app_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoujck/DIY_TvBox/3720a887c9598f8e5bbf266a78c5693a9ca4feb9/DIY/app_bg.png
--------------------------------------------------------------------------------
/DIY/app_bg_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoujck/DIY_TvBox/3720a887c9598f8e5bbf266a78c5693a9ca4feb9/DIY/app_bg_black.png
--------------------------------------------------------------------------------
/DIY/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoujck/DIY_TvBox/3720a887c9598f8e5bbf266a78c5693a9ca4feb9/DIY/app_icon.png
--------------------------------------------------------------------------------
/DIY/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoujck/DIY_TvBox/3720a887c9598f8e5bbf266a78c5693a9ca4feb9/DIY/bg.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TVBoxDIY
2 | Fork:https://github.com/CatVodTVOfficial/TVBoxOSC.git
3 |
4 | 源码:https://github.com/lm317379829/TVBoxOSC.git
5 |
6 | # 说明
7 | APK-J Build为本地爬虫-俊版,APK-T Build为本地爬虫taka版
8 | diy-J.sh、diy-T.sh分别为俊版、taka版自定义脚本,可自行修改apk名、背景、图标以及其他源码内容。
9 |
10 |
11 |
--------------------------------------------------------------------------------
/diy-J-Jar.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #获取目录
4 | CURRENT_DIR=$(cd $(dirname $0); pwd)
5 | num=$(find $CURRENT_DIR -name gradlew | awk -F"/" '{print NF-1}')
6 | DIR=$(find $CURRENT_DIR -name gradlew | cut -d \/ -f$num)
7 | cd $CURRENT_DIR/$DIR
8 |
9 | #签名
10 | signingConfigs='ICAgIHNpZ25pbmdDb25maWdzIHtcCiAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICBteUNvbmZpZyB7XAogICAgICAgICAgICAgICAgc3RvcmVGaWxlIGZpbGUoUkVMRUFTRV9TVE9SRV9GSUxFKVwKICAgICAgICAgICAgICAgIHN0b3JlUGFzc3dvcmQgUkVMRUFTRV9TVE9SRV9QQVNTV09SRFwKICAgICAgICAgICAgICAgIGtleUFsaWFzIFJFTEVBU0VfS0VZX0FMSUFTXAogICAgICAgICAgICAgICAga2V5UGFzc3dvcmQgUkVMRUFTRV9LRVlfUEFTU1dPUkRcCiAgICAgICAgICAgICAgICB2MVNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICB2MlNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICBlbmFibGVWM1NpZ25pbmcgPSB0cnVlXAogICAgICAgICAgICAgICAgZW5hYmxlVjRTaWduaW5nID0gdHJ1ZVwKICAgICAgICAgICAgfVwKICAgICAgICB9XAogICAgfVwKXA=='
11 | signingConfig='ICAgICAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICAgICAgc2lnbmluZ0NvbmZpZyBzaWduaW5nQ29uZmlncy5teUNvbmZpZ1wKICAgICAgICAgICAgfVwK'
12 | signingConfigs="$(echo "$signingConfigs" |base64 -d )"
13 | signingConfig="$(echo "$signingConfig" |base64 -d )"
14 | sed -i -e "/defaultConfig {/i\\$signingConfigs " -e "/debug {/a\\$signingConfig " -e "/release {/a\\$signingConfig " $CURRENT_DIR/$DIR/app/build.gradle
15 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/app/TVBoxOSC.jks
16 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/TVBoxOSC.jks
17 | echo "" >>$CURRENT_DIR/$DIR/gradle.properties
18 | echo "RELEASE_STORE_FILE=./TVBoxOSC.jks" >>$CURRENT_DIR/$DIR/gradle.properties
19 | echo "RELEASE_KEY_ALIAS=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
20 | echo "RELEASE_STORE_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
21 | echo "RELEASE_KEY_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
22 |
23 |
24 | # 名称修改
25 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values/strings.xml
26 |
27 | # 图标修改
28 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_banner.png
29 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-hdpi/app_icon.png
30 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xhdpi/app_icon.png
31 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xxhdpi/app_icon.png
32 | mv $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xxxhdpi/app_icon.png
33 |
34 | # 主页UI微调
35 | #cp $CURRENT_DIR/DIY/J/fragment_user.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/fragment_user.xml
36 |
37 | #主页增加每日一言1.0
38 | #cp $CURRENT_DIR/DIY/J/ApiConfig.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
39 | #cp $CURRENT_DIR/DIY/J/activity_home.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_home.xml
40 | #cp $CURRENT_DIR/DIY/J/HomeActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
41 |
42 | # 背景修改
43 | cp $CURRENT_DIR/DIY/app_bg_black.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_bg.png
44 |
45 | # 默认设置修改
46 | #cp $CURRENT_DIR/DIY/J/App.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
47 |
48 | # 内置接口
49 | sed -i 's#API_URL, ""#API_URL, "https://agit.ai/zhoujck/config/raw/branch/master/box"#g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
50 |
51 | #自定义epg
52 | #cp $CURRENT_DIR/DIY/epg_data.json $CURRENT_DIR/$DIR/app/src/main/assets/epg_data.json
53 |
54 | #播放界面修改 1.底部控件重排 2.直播增加分辨率显示
55 | #cp $CURRENT_DIR/DIY/J/activity_live_play.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_live_play.xml
56 | #cp $CURRENT_DIR/DIY/J/player_vod_control_view.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/player_vod_control_view.xml
57 | #cp $CURRENT_DIR/DIY/J/VodController.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
58 | #cp $CURRENT_DIR/DIY/J/LivePlayActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java
59 |
60 | #换源
61 | #cp $CURRENT_DIR/DIY/J/DetailActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/DetailActivity.java
62 |
63 | #修改播放器进度条消失时间
64 | #sed -i 's/10000/6000/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
65 |
66 | #主界面首页文字修改
67 | #sed -i 's/color_BBFFFFFF/color_FFFFFF/g' $CURRENT_DIR/$DIR/app/src/main/res/layout/item_home_sort.xml
68 | #sed -i 's/color_BBFFFFFF/color_FFFFFF/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
69 |
70 | #进度条颜色
71 | #sed -i 's/color_353744/color_1890FF/g' $CURRENT_DIR/$DIR/app/src/main/res/drawable/shape_player_control_vod_seek.xml
72 |
73 | #共存
74 | #sed -i 's/com.github.tvbox.osc/com.tvbox.q/g' $CURRENT_DIR/$DIR/app/build.gradle
75 |
76 | #FongMi的jar支持
77 | #echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
78 | #echo "-keep class com.google.gson.**{*;}" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
79 |
80 |
81 | echo 'DIY end'
82 |
--------------------------------------------------------------------------------
/diy-J.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #获取目录
4 | CURRENT_DIR=$(cd $(dirname $0); pwd)
5 | num=$(find $CURRENT_DIR -name gradlew | awk -F"/" '{print NF-1}')
6 | DIR=$(find $CURRENT_DIR -name gradlew | cut -d \/ -f$num)
7 | cd $CURRENT_DIR/$DIR
8 |
9 | #签名
10 | signingConfigs='ICAgIHNpZ25pbmdDb25maWdzIHtcCiAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICBteUNvbmZpZyB7XAogICAgICAgICAgICAgICAgc3RvcmVGaWxlIGZpbGUoUkVMRUFTRV9TVE9SRV9GSUxFKVwKICAgICAgICAgICAgICAgIHN0b3JlUGFzc3dvcmQgUkVMRUFTRV9TVE9SRV9QQVNTV09SRFwKICAgICAgICAgICAgICAgIGtleUFsaWFzIFJFTEVBU0VfS0VZX0FMSUFTXAogICAgICAgICAgICAgICAga2V5UGFzc3dvcmQgUkVMRUFTRV9LRVlfUEFTU1dPUkRcCiAgICAgICAgICAgICAgICB2MVNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICB2MlNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICBlbmFibGVWM1NpZ25pbmcgPSB0cnVlXAogICAgICAgICAgICAgICAgZW5hYmxlVjRTaWduaW5nID0gdHJ1ZVwKICAgICAgICAgICAgfVwKICAgICAgICB9XAogICAgfVwKXA=='
11 | signingConfig='ICAgICAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICAgICAgc2lnbmluZ0NvbmZpZyBzaWduaW5nQ29uZmlncy5teUNvbmZpZ1wKICAgICAgICAgICAgfVwK'
12 | signingConfigs="$(echo "$signingConfigs" |base64 -d )"
13 | signingConfig="$(echo "$signingConfig" |base64 -d )"
14 | sed -i -e "/defaultConfig {/i\\$signingConfigs " -e "/debug {/a\\$signingConfig " -e "/release {/a\\$signingConfig " $CURRENT_DIR/$DIR/app/build.gradle
15 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/app/TVBoxOSC.jks
16 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/TVBoxOSC.jks
17 | echo "" >>$CURRENT_DIR/$DIR/gradle.properties
18 | echo "RELEASE_STORE_FILE=./TVBoxOSC.jks" >>$CURRENT_DIR/$DIR/gradle.properties
19 | echo "RELEASE_KEY_ALIAS=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
20 | echo "RELEASE_STORE_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
21 | echo "RELEASE_KEY_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
22 |
23 |
24 | # 名称修改
25 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values/strings.xml
26 |
27 | # 图标修改
28 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_banner.png
29 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-hdpi/app_icon.png
30 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xhdpi/app_icon.png
31 | cp $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xxhdpi/app_icon.png
32 | mv $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable-xxxhdpi/app_icon.png
33 |
34 | # 主页UI微调
35 | cp $CURRENT_DIR/DIY/J/fragment_user.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/fragment_user.xml
36 |
37 | #主页增加每日一言1.0
38 | cp $CURRENT_DIR/DIY/J/ApiConfig.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
39 | cp $CURRENT_DIR/DIY/J/activity_home.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_home.xml
40 | cp $CURRENT_DIR/DIY/J/HomeActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
41 |
42 | # 背景修改
43 | cp $CURRENT_DIR/DIY/app_bg_black.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_bg.png
44 |
45 | # 默认设置修改
46 | cp $CURRENT_DIR/DIY/J/App.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
47 |
48 | # 内置接口
49 | sed -i 's#API_URL, ""#API_URL, "https://agit.ai/zhoujck/config/raw/branch/master/box"#g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
50 |
51 | #自定义epg
52 | #cp $CURRENT_DIR/DIY/epg_data.json $CURRENT_DIR/$DIR/app/src/main/assets/epg_data.json
53 |
54 | #播放界面修改 1.底部控件重排 2.直播增加分辨率显示
55 | cp $CURRENT_DIR/DIY/J/activity_live_play.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_live_play.xml
56 | cp $CURRENT_DIR/DIY/J/player_vod_control_view.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/player_vod_control_view.xml
57 | cp $CURRENT_DIR/DIY/J/VodController.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
58 | cp $CURRENT_DIR/DIY/J/LivePlayActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java
59 |
60 | #换源
61 | #cp $CURRENT_DIR/DIY/J/DetailActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/DetailActivity.java
62 |
63 | #修改播放器进度条消失时间
64 | sed -i 's/10000/6000/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
65 |
66 | #主界面首页文字修改
67 | sed -i 's/color_BBFFFFFF/color_FFFFFF/g' $CURRENT_DIR/$DIR/app/src/main/res/layout/item_home_sort.xml
68 | sed -i 's/color_BBFFFFFF/color_FFFFFF/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
69 |
70 | #进度条颜色
71 | sed -i 's/color_353744/color_1890FF/g' $CURRENT_DIR/$DIR/app/src/main/res/drawable/shape_player_control_vod_seek.xml
72 |
73 | #共存
74 | sed -i 's/com.github.tvbox.osc/com.tvbox.q/g' $CURRENT_DIR/$DIR/app/build.gradle
75 |
76 | #添加PY支持
77 | wget --no-check-certificate -qO- "https://raw.githubusercontent.com/UndCover/PyramidStore/main/aar/pyramid-1011.aar" -O $CURRENT_DIR/$DIR/app/libs/pyramid.aar
78 | sed -i "/thunder.jar/a\ implementation files('libs@pyramid.aar')" $CURRENT_DIR/$DIR/app/build.gradle
79 | sed -i 's#@#\\#g' $CURRENT_DIR/$DIR/app/build.gradle
80 | sed -i 's#pyramid#\\pyramid#g' $CURRENT_DIR/$DIR/app/build.gradle
81 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
82 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
83 | echo "#添加PY支持" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
84 | echo "-keep public class com.undcover.freedom.pyramid.** { *; }" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
85 | echo "-dontwarn com.undcover.freedom.pyramid.**" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
86 | echo "-keep public class com.chaquo.python.** { *; }" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
87 | echo "-dontwarn com.chaquo.python.**" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
88 | sed -i '/import com.orhanobut.hawk.Hawk;/a\import com.undcover.freedom.pyramid.PythonLoader;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
89 | sed -i '/import com.orhanobut.hawk.Hawk;/a\import com.github.catvod.crawler.SpiderNull;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
90 | sed -i '/PlayerHelper.init/a\ PythonLoader.getInstance().setApplication(this);' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
91 | sed -i '/import android.util.Base64;/a\import com.github.catvod.crawler.SpiderNull;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
92 | sed -i '/import android.util.Base64;/a\import com.undcover.freedom.pyramid.PythonLoader;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
93 | sed -i '/private void parseJson(String apiUrl, String jsonStr)/a\ PythonLoader.getInstance().setConfig(jsonStr);' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
94 | sed -i '/public Spider getCSP(SourceBean sourceBean)/a\ if (sourceBean.getApi().startsWith(\"py_\")) {\n try {\n return PythonLoader.getInstance().getSpider(sourceBean.getKey(), sourceBean.getExt());\n } catch (Exception e) {\n e.printStackTrace();\n return new SpiderNull();\n }\n }' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
95 | sed -i '/public Object\[\] proxyLoca/a\ try {\n if(param.containsKey(\"api\")){\n String doStr = param.get(\"do\").toString();\n if(doStr.equals(\"ck\"))\n return PythonLoader.getInstance().proxyLocal(\"\",\"\",param);\n SourceBean sourceBean = ApiConfig.get().getSource(doStr);\n return PythonLoader.getInstance().proxyLocal(sourceBean.getKey(),sourceBean.getExt(),param);\n }else{\n String doStr = param.get(\"do\").toString();\n if(doStr.equals(\"live\")) return PythonLoader.getInstance().proxyLocal(\"\",\"\",param);\n }\n } catch (Exception e) {\n e.printStackTrace();\n }\n' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
96 | #FongMi的jar支持
97 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
98 | echo "-keep class com.google.gson.**{*;}" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
99 |
100 |
101 | echo 'DIY end'
102 |
--------------------------------------------------------------------------------
/diy-T-Jar.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #获取目录
4 | CURRENT_DIR=$(cd $(dirname $0); pwd)
5 | num=$(find $CURRENT_DIR -name gradlew | awk -F"/" '{print NF-1}'| head -1)
6 | DIR=$(find $CURRENT_DIR -name gradlew | cut -d \/ -f$num | head -1)
7 | cd $DIR
8 |
9 | # 签名
10 | signingConfigs='ICAgIHNpZ25pbmdDb25maWdzIHtcCiAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICBteUNvbmZpZyB7XAogICAgICAgICAgICAgICAgc3RvcmVGaWxlIGZpbGUoUkVMRUFTRV9TVE9SRV9GSUxFKVwKICAgICAgICAgICAgICAgIHN0b3JlUGFzc3dvcmQgUkVMRUFTRV9TVE9SRV9QQVNTV09SRFwKICAgICAgICAgICAgICAgIGtleUFsaWFzIFJFTEVBU0VfS0VZX0FMSUFTXAogICAgICAgICAgICAgICAga2V5UGFzc3dvcmQgUkVMRUFTRV9LRVlfUEFTU1dPUkRcCiAgICAgICAgICAgICAgICB2MVNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICB2MlNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICBlbmFibGVWM1NpZ25pbmcgPSB0cnVlXAogICAgICAgICAgICAgICAgZW5hYmxlVjRTaWduaW5nID0gdHJ1ZVwKICAgICAgICAgICAgfVwKICAgICAgICB9XAogICAgfVwKXA=='
11 | signingConfig='ICAgICAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICAgICAgc2lnbmluZ0NvbmZpZyBzaWduaW5nQ29uZmlncy5teUNvbmZpZ1wKICAgICAgICAgICAgfVwK'
12 | signingConfigs="$(echo "$signingConfigs" |base64 -d )"
13 | signingConfig="$(echo "$signingConfig" |base64 -d )"
14 | sed -i -e "/defaultConfig {/i\\$signingConfigs " -e "/debug {/a\\$signingConfig " -e "/release {/a\\$signingConfig " $CURRENT_DIR/$DIR/app/build.gradle
15 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/app/TVBoxOSC.jks
16 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/TVBoxOSC.jks
17 | echo "" >>$CURRENT_DIR/$DIR/gradle.properties
18 | echo "RELEASE_STORE_FILE=./TVBoxOSC.jks" >>$CURRENT_DIR/$DIR/gradle.properties
19 | echo "RELEASE_KEY_ALIAS=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
20 | echo "RELEASE_STORE_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
21 | echo "RELEASE_KEY_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
22 |
23 | #名称修改
24 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values-zh/strings.xml
25 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values/strings.xml
26 | sed -i 's#"app_source"><#"app_source">https://framagit.org/zhoujck/config/-/raw/master/box<#g' $CURRENT_DIR/$DIR/app/src/main/res/values-zh/strings.xml
27 |
28 | #包名修改为西瓜视频
29 | sed -i 's/com.github.tvbox.osc.tk/com.ss.android.article.video/g' $CURRENT_DIR/$DIR/app/build.gradle
30 |
31 |
32 | #图标修改
33 | mv $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_icon.png
34 | sed -i 's/app_banner/app_icon/g' $CURRENT_DIR/$DIR/app/src/main/AndroidManifest.xml
35 |
36 | #背景修改
37 | #mv $CURRENT_DIR/DIY/app_bg_black.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_bg.png
38 |
39 | # 主页UI调整 恢复老版;默认多行显示
40 | #cp $CURRENT_DIR/DIY/T/fragment_user.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/fragment_user.xml
41 |
42 | # 主页增加每日一言/去除部分图标
43 | #cp $CURRENT_DIR/DIY/T/ApiConfig.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
44 | #cp $CURRENT_DIR/DIY/T/activity_home.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_home.xml
45 | #cp $CURRENT_DIR/DIY/T/HomeActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
46 |
47 | # 默认设置修改
48 | #cp $CURRENT_DIR/DIY/T/App.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
49 |
50 | # 取消首页从通知栏位置布置
51 | #cp $CURRENT_DIR/DIY/T/BaseActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/BaseActivity.java
52 |
53 | # 直播添加epg112114支持
54 | #cp $CURRENT_DIR/DIY/T/LivePlayActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java
55 |
56 | # 搜索改为爱奇艺热词,支持首字母联想
57 | #cp $CURRENT_DIR/DIY/T/SearchActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java
58 |
59 | #长按倍速修改为2
60 | #sed -i 's/3.0/2.0/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
61 |
62 | #FongMi的jar支持
63 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
64 | echo "-keep class com.google.gson.**{*;}" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
65 |
66 | echo 'DIY end'
67 |
--------------------------------------------------------------------------------
/diy-T.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #获取目录
4 | CURRENT_DIR=$(cd $(dirname $0); pwd)
5 | num=$(find $CURRENT_DIR -name gradlew | awk -F"/" '{print NF-1}'| head -1)
6 | DIR=$(find $CURRENT_DIR -name gradlew | cut -d \/ -f$num | head -1)
7 | cd $DIR
8 | #签名
9 | signingConfigs='ICAgIHNpZ25pbmdDb25maWdzIHtcCiAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICBteUNvbmZpZyB7XAogICAgICAgICAgICAgICAgc3RvcmVGaWxlIGZpbGUoUkVMRUFTRV9TVE9SRV9GSUxFKVwKICAgICAgICAgICAgICAgIHN0b3JlUGFzc3dvcmQgUkVMRUFTRV9TVE9SRV9QQVNTV09SRFwKICAgICAgICAgICAgICAgIGtleUFsaWFzIFJFTEVBU0VfS0VZX0FMSUFTXAogICAgICAgICAgICAgICAga2V5UGFzc3dvcmQgUkVMRUFTRV9LRVlfUEFTU1dPUkRcCiAgICAgICAgICAgICAgICB2MVNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICB2MlNpZ25pbmdFbmFibGVkIHRydWVcCiAgICAgICAgICAgICAgICBlbmFibGVWM1NpZ25pbmcgPSB0cnVlXAogICAgICAgICAgICAgICAgZW5hYmxlVjRTaWduaW5nID0gdHJ1ZVwKICAgICAgICAgICAgfVwKICAgICAgICB9XAogICAgfVwKXA=='
10 | signingConfig='ICAgICAgICAgICAgaWYgKHByb2plY3QuaGFzUHJvcGVydHkoIlJFTEVBU0VfU1RPUkVfRklMRSIpKSB7XAogICAgICAgICAgICAgICAgc2lnbmluZ0NvbmZpZyBzaWduaW5nQ29uZmlncy5teUNvbmZpZ1wKICAgICAgICAgICAgfVwK'
11 | signingConfigs="$(echo "$signingConfigs" |base64 -d )"
12 | signingConfig="$(echo "$signingConfig" |base64 -d )"
13 | sed -i -e "/defaultConfig {/i\\$signingConfigs " -e "/debug {/a\\$signingConfig " -e "/release {/a\\$signingConfig " $CURRENT_DIR/$DIR/app/build.gradle
14 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/app/TVBoxOSC.jks
15 | cp -f $CURRENT_DIR/DIY/TVBoxOSC.jks $CURRENT_DIR/$DIR/TVBoxOSC.jks
16 | echo "" >>$CURRENT_DIR/$DIR/gradle.properties
17 | echo "RELEASE_STORE_FILE=./TVBoxOSC.jks" >>$CURRENT_DIR/$DIR/gradle.properties
18 | echo "RELEASE_KEY_ALIAS=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
19 | echo "RELEASE_STORE_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
20 | echo "RELEASE_KEY_PASSWORD=TVBoxOSC" >>$CURRENT_DIR/$DIR/gradle.properties
21 |
22 | #名称修改
23 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values-zh/strings.xml
24 | sed -i 's/TVBox/糖果影视/g' $CURRENT_DIR/$DIR/app/src/main/res/values/strings.xml
25 | sed -i 's#"app_source"><#"app_source">https://gitee.com/zhoujck/tv/raw/master/box<#g' $CURRENT_DIR/$DIR/app/src/main/res/values-zh/strings.xml
26 |
27 | #图标修改
28 | mv $CURRENT_DIR/DIY/app_icon.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_icon.png
29 | sed -i 's/app_banner/app_icon/g' $CURRENT_DIR/$DIR/app/src/main/AndroidManifest.xml
30 |
31 |
32 | #背景修改
33 | mv $CURRENT_DIR/DIY/app_bg_black.png $CURRENT_DIR/$DIR/app/src/main/res/drawable/app_bg.png
34 |
35 | # 主页UI调整 恢复老版;默认多行显示
36 | cp $CURRENT_DIR/DIY/T/fragment_user.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/fragment_user.xml
37 |
38 | # 主页增加每日一言/去除部分图标
39 | cp $CURRENT_DIR/DIY/T/ApiConfig.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
40 | cp $CURRENT_DIR/DIY/T/activity_home.xml $CURRENT_DIR/$DIR/app/src/main/res/layout/activity_home.xml
41 | cp $CURRENT_DIR/DIY/T/HomeActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
42 |
43 | # 默认设置修改
44 | cp $CURRENT_DIR/DIY/T/App.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
45 |
46 | # 整体布局修改
47 | cp $CURRENT_DIR/DIY/T/BaseActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/BaseActivity.java
48 |
49 | # 直播添加epg112114支持
50 | cp $CURRENT_DIR/DIY/T/LivePlayActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java
51 |
52 | # 搜索改为爱奇艺热词,支持首字母联想
53 | #cp $CURRENT_DIR/DIY/T/SearchActivity.java $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java
54 |
55 | #长按倍速修改为2
56 | sed -i 's/3.0/2.0/g' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
57 |
58 | #版本号修改
59 | sed -i 's/versionName "1.0."/versionName "1."/g' $CURRENT_DIR/$DIR/app/build.gradle
60 |
61 | #FongMi的jar支持
62 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
63 | echo "-keep class com.google.gson.**{*;}" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
64 |
65 | #添加PY支持
66 | wget --no-check-certificate -qO- "https://raw.githubusercontent.com/UndCover/PyramidStore/main/aar/pyramid-1011.aar" -O $CURRENT_DIR/$DIR/app/libs/pyramid.aar
67 | sed -i "/thunder.jar/a\ implementation files('libs@pyramid.aar')" $CURRENT_DIR/$DIR/app/build.gradle
68 | sed -i 's#@#\\#g' $CURRENT_DIR/$DIR/app/build.gradle
69 | sed -i 's#pyramid#\\pyramid#g' $CURRENT_DIR/$DIR/app/build.gradle
70 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
71 | echo "" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
72 | echo "#添加PY支持" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
73 | echo "-keep public class com.undcover.freedom.pyramid.** { *; }" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
74 | echo "-dontwarn com.undcover.freedom.pyramid.**" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
75 | echo "-keep public class com.chaquo.python.** { *; }" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
76 | echo "-dontwarn com.chaquo.python.**" >>$CURRENT_DIR/$DIR/app/proguard-rules.pro
77 | sed -i '/import com.orhanobut.hawk.Hawk;/a\import com.undcover.freedom.pyramid.PythonLoader;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
78 | sed -i '/import com.orhanobut.hawk.Hawk;/a\import com.github.catvod.crawler.SpiderNull;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
79 | sed -i '/PlayerHelper.init/a\ PythonLoader.getInstance().setApplication(this);' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/base/App.java
80 | sed -i '/import android.util.Base64;/a\import com.github.catvod.crawler.SpiderNull;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
81 | sed -i '/import android.util.Base64;/a\import com.undcover.freedom.pyramid.PythonLoader;' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
82 | sed -i '/private void parseJson(String apiUrl, String jsonStr)/a\ PythonLoader.getInstance().setConfig(jsonStr);' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
83 | sed -i '/public Spider getCSP(SourceBean sourceBean)/a\ if (sourceBean.getApi().startsWith(\"py_\")) {\n try {\n return PythonLoader.getInstance().getSpider(sourceBean.getKey(), sourceBean.getExt());\n } catch (Exception e) {\n e.printStackTrace();\n return new SpiderNull();\n }\n }' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
84 | sed -i '/public Object\[\] proxyLoca/a\ try {\n if(param.containsKey(\"api\")){\n String doStr = param.get(\"do\").toString();\n if(doStr.equals(\"ck\"))\n return PythonLoader.getInstance().proxyLocal(\"\",\"\",param);\n SourceBean sourceBean = ApiConfig.get().getSource(doStr);\n return PythonLoader.getInstance().proxyLocal(sourceBean.getKey(),sourceBean.getExt(),param);\n }else{\n String doStr = param.get(\"do\").toString();\n if(doStr.equals(\"live\")) return PythonLoader.getInstance().proxyLocal(\"\",\"\",param);\n }\n } catch (Exception e) {\n e.printStackTrace();\n }\n' $CURRENT_DIR/$DIR/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
85 |
86 |
87 | echo 'DIY end'
88 |
--------------------------------------------------------------------------------