diff --git a/app/build.gradle b/app/build.gradle
index c87efb219..602ca12cf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
minSdk 21
targetSdk 28
versionCode 232
- versionName "2.3.2"
+ versionName "0404"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
@@ -127,6 +127,7 @@ dependencies {
implementation 'org.fourthline.cling:cling-core:2.1.1'
implementation 'org.fourthline.cling:cling-support:2.1.1'
implementation 'org.greenrobot:eventbus:3.3.1'
+ implementation 'com.tencent.tbs:tbssdk:44286'
implementation('org.simpleframework:simple-xml:2.7.1') { exclude group: 'stax', module: 'stax-api' exclude group: 'xpp3', module: 'xpp3' }
implementation(ext: 'aar', name: 'dlna-core', group: 'fongmi', version: 'release')
leanbackImplementation(ext: 'aar', name: 'dlna-dmr', group: 'fongmi', version: 'release')
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index bd7856fb3..3e24858c6 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -79,4 +79,10 @@
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
-}
\ No newline at end of file
+}
+
+# x5
+-dontwarn dalvik.**
+-dontwarn com.tencent.smtt.**
+-keep class com.tencent.smtt.** { *; }
+-keep class com.tencent.tbs.** { *; }
\ No newline at end of file
diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java
index 1bad08d74..82e6c33df 100644
--- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java
+++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java
@@ -58,6 +58,7 @@ import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.KeyUtil;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.ResUtil;
+import com.fongmi.android.tv.utils.Tbs;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.utils.Prefers;
import com.github.catvod.utils.Trans;
@@ -111,6 +112,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
setHomeType();
setPager();
initConfig();
+ Tbs.init();
}
@Override
diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java
index 7f5a5bfe6..9c9cbc8a8 100644
--- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java
+++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java
@@ -6,6 +6,7 @@ import android.view.View;
import androidx.viewbinding.ViewBinding;
+import com.fongmi.android.tv.App;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.databinding.ActivitySettingCustomBinding;
@@ -14,8 +15,9 @@ import com.fongmi.android.tv.ui.base.BaseActivity;
import com.fongmi.android.tv.ui.dialog.ButtonsDialog;
import com.fongmi.android.tv.ui.dialog.DisplayDialog;
import com.fongmi.android.tv.ui.dialog.MenuKeyDialog;
+import com.fongmi.android.tv.ui.dialog.X5WebViewDialog;
import com.fongmi.android.tv.utils.ResUtil;
-
+import com.tencent.smtt.sdk.QbSdk;
import java.util.Locale;
public class SettingCustomActivity extends BaseActivity {
@@ -27,6 +29,7 @@ public class SettingCustomActivity extends BaseActivity {
private String[] fullscreenMenuKey;
private String[] smallWindowBackKey;
private String[] homeUI;
+ private String[] parseWebview;
@Override
protected ViewBinding getBinding() {
@@ -56,6 +59,7 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.aggregatedSearchText.setText(getSwitch(Setting.isAggregatedSearch()));
mBinding.homeUIText.setText((homeUI = ResUtil.getStringArray(R.array.select_home_ui))[Setting.getHomeUI()]);
mBinding.homeHistoryText.setText(getSwitch(Setting.isHomeHistory()));
+ mBinding.parseWebviewText.setText((parseWebview = ResUtil.getStringArray(R.array.select_parse_webview))[Setting.getParseWebView()]);
}
@Override
@@ -75,6 +79,7 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.homeUI.setOnClickListener(this::setHomeUI);
mBinding.homeButtons.setOnClickListener(this::onHomeButtons);
mBinding.homeHistory.setOnClickListener(this::setHomeHistory);
+ mBinding.parseWebview.setOnClickListener(this::setParseWebview);
}
private void setQuality(View view) {
@@ -169,4 +174,11 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.homeHistoryText.setText(getSwitch(Setting.isHomeHistory()));
}
+ private void setParseWebview(View view) {
+ int index = Setting.getParseWebView();
+ Setting.putParseWebView(index = index == parseWebview.length - 1 ? 0 : ++index);
+ mBinding.parseWebviewText.setText(parseWebview[index]);
+ if (index == 1 && QbSdk.getTbsVersion(App.get()) <= 0) X5WebViewDialog.create(this).show();
+ }
+
}
diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/X5WebViewDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/X5WebViewDialog.java
new file mode 100644
index 000000000..be92e798e
--- /dev/null
+++ b/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/X5WebViewDialog.java
@@ -0,0 +1,84 @@
+package com.fongmi.android.tv.ui.dialog;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.fongmi.android.tv.Setting;
+import com.fongmi.android.tv.databinding.DialogX5webviewBinding;
+import com.fongmi.android.tv.utils.Download;
+import com.fongmi.android.tv.utils.Notify;
+import com.fongmi.android.tv.utils.Tbs;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import java.io.File;
+import java.util.Locale;
+
+public class X5WebViewDialog implements Download.Callback {
+
+ private DialogX5webviewBinding binding;
+ private AlertDialog dialog;
+ private Activity activity;
+
+ public X5WebViewDialog(Activity activity) {
+ this.activity = activity;
+ }
+
+ public void show() {
+ binding = DialogX5webviewBinding.inflate(LayoutInflater.from(activity));
+ binding.confirm.setOnClickListener(this::confirm);
+ binding.cancel.setOnClickListener(this::cancel);
+ dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).setCancelable(false).create();
+ dialog.show();
+ }
+
+ public static X5WebViewDialog create(Activity activity) {
+ return new X5WebViewDialog(activity);
+ }
+
+ private String getTbs() {
+ return Tbs.url();
+ }
+
+ private File getFile() {
+ return Tbs.file();
+ }
+
+ private void cancel(View view) {
+ dismiss();
+ }
+
+ private void confirm(View view) {
+ binding.confirm.setEnabled(false);
+ Download.create(getTbs(), getFile(), this).start();
+ }
+
+ private void dismiss() {
+ try {
+ if (dialog != null) dialog.dismiss();
+ } catch (Exception ignored) {
+ }
+ }
+
+ @Override
+ public void progress(int progress) {
+ binding.confirm.setText(String.format(Locale.getDefault(), "%1$d%%", progress));
+ }
+
+ @Override
+ public void error(String msg) {
+ Notify.show(msg);
+ Setting.putParseWebView(0);
+ dismiss();
+ }
+
+ @Override
+ public void success(File file) {
+ dismiss();
+ Tbs.download();
+ Setting.putParseWebView(1);
+ }
+
+
+}
diff --git a/app/src/leanback/res/layout/activity_setting_custom.xml b/app/src/leanback/res/layout/activity_setting_custom.xml
index a3864f9ff..842689396 100644
--- a/app/src/leanback/res/layout/activity_setting_custom.xml
+++ b/app/src/leanback/res/layout/activity_setting_custom.xml
@@ -463,5 +463,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/leanback/res/layout/dialog_x5webview.xml b/app/src/leanback/res/layout/dialog_x5webview.xml
new file mode 100644
index 000000000..1d74982ab
--- /dev/null
+++ b/app/src/leanback/res/layout/dialog_x5webview.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/fongmi/android/tv/Setting.java b/app/src/main/java/com/fongmi/android/tv/Setting.java
index 21bfdf7ea..463ac256a 100644
--- a/app/src/main/java/com/fongmi/android/tv/Setting.java
+++ b/app/src/main/java/com/fongmi/android/tv/Setting.java
@@ -477,4 +477,11 @@ public class Setting {
return Math.min(Prefers.getInt("config_cache", 0), 8);
}
+ public static void putParseWebView(int key) {
+ Prefers.put("parse_webview", key);
+ }
+
+ public static int getParseWebView() {
+ return Prefers.getInt("parse_webview", 0);
+ }
}
diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java
index 99b939a9b..0df2947c8 100644
--- a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java
+++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java
@@ -4,22 +4,27 @@ import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.net.Uri;
-import android.net.http.SslError;
import android.text.TextUtils;
import android.view.ViewGroup;
-import android.webkit.CookieManager;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
+import com.fongmi.android.tv.utils.Notify;
+import com.tencent.smtt.export.external.interfaces.SslError;
+import com.tencent.smtt.export.external.interfaces.SslErrorHandler;
+import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
+import com.tencent.smtt.export.external.interfaces.WebResourceResponse;
+import com.tencent.smtt.sdk.CookieManager;
+import com.tencent.smtt.sdk.QbSdk;
+import com.tencent.smtt.sdk.WebChromeClient;
+import com.tencent.smtt.sdk.WebView;
+import com.tencent.smtt.sdk.WebViewClient;
import androidx.annotation.NonNull;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
+import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.api.config.VodConfig;
import com.fongmi.android.tv.bean.Site;
@@ -49,12 +54,23 @@ public class CustomWebView extends WebView {
private String key;
public static CustomWebView create(@NonNull Context context) {
+ initTbs();
return new CustomWebView(context);
}
public CustomWebView(@NonNull Context context) {
super(context);
initSettings();
+ showTbs();
+ }
+
+ private static void initTbs() {
+ if (Setting.getParseWebView() == 0) QbSdk.forceSysWebView();
+ else QbSdk.unForceSysWebView();
+ }
+
+ private void showTbs() {
+ if (this.getIsX5Core()) Notify.show(R.string.x5webview_parsing);
}
@SuppressLint("SetJavaScriptEnabled")
@@ -75,11 +91,7 @@ public class CustomWebView extends WebView {
getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true);
setWebViewClient(webViewClient());
- }
-
- private void addView() {
- ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(1, 1);
- if (App.activity() != null) App.activity().addContentView(this, params);
+ setWebChromeClient(webChromeClient());
}
public CustomWebView start(String key, String from, Map headers, String url, String click, ParseCallback callback, boolean detect) {
@@ -89,7 +101,6 @@ public class CustomWebView extends WebView {
this.click = click;
this.from = from;
this.key = key;
- addView();
start(url, headers);
return this;
}
@@ -146,9 +157,22 @@ public class CustomWebView extends WebView {
};
}
+ private WebChromeClient webChromeClient() {
+ return new WebChromeClient() {
+ @Override
+ public Bitmap getDefaultVideoPoster() {
+ try {
+ return BitmapFactory.decodeResource(App.get().getResources(), R.drawable.ic_logo);
+ } catch (Throwable e) {
+ return super.getDefaultVideoPoster();
+ }
+ }
+ };
+ }
+
private void showDialog() {
if (dialog != null || App.activity() == null) return;
- removeView();
+ if (getParent() != null) ((ViewGroup) getParent()).removeView(this);
dialog = new AlertDialog.Builder(App.activity()).setView(this).show();
}
@@ -206,13 +230,8 @@ public class CustomWebView extends WebView {
callback = null;
}
- private void removeView() {
- if (getParent() != null) ((ViewGroup) getParent()).removeView(this);
- }
-
public void stop(boolean error) {
hideDialog();
- removeView();
stopLoading();
loadUrl(BLANK);
App.removeCallbacks(timer);
diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Tbs.java b/app/src/main/java/com/fongmi/android/tv/utils/Tbs.java
new file mode 100644
index 000000000..c4ce7f73c
--- /dev/null
+++ b/app/src/main/java/com/fongmi/android/tv/utils/Tbs.java
@@ -0,0 +1,106 @@
+package com.fongmi.android.tv.utils;
+
+import android.os.Build;
+
+import com.fongmi.android.tv.App;
+import com.fongmi.android.tv.R;
+import com.fongmi.android.tv.Setting;
+import com.github.catvod.utils.Path;
+import com.orhanobut.logger.Logger;
+import com.tencent.smtt.sdk.QbSdk;
+import com.tencent.smtt.sdk.TbsListener;
+import com.tencent.smtt.export.external.TbsCoreSettings;
+
+import java.io.File;
+import java.util.HashMap;
+
+public class Tbs {
+ private static final String TAG = Tbs.class.getSimpleName();
+
+ public static final String URL64 = "https://tmf-pkg-1314481471.cos.ap-shanghai.myqcloud.com/x5/64/46471/tbs_core_046471_20230809100104_nolog_fs_obfs_arm64-v8a_release.tbs";
+ public static final String URL32 = "https://tmf-pkg-1314481471.cos.ap-shanghai.myqcloud.com/x5/32/46471/tbs_core_046471_20230809095840_nolog_fs_obfs_armeabi_release.tbs";
+
+ private static boolean isCpu64Bit() {
+ for (String abi : Build.SUPPORTED_ABIS) {
+ if (abi.contains("64")) return true;
+ }
+ return false;
+ }
+
+ public static String getUrl() {
+ return isCpu64Bit() ? URL64 : URL32;
+ }
+
+ private static void tbsInit() {
+ HashMap map = new HashMap();
+ map.put(TbsCoreSettings.TBS_SETTINGS_USE_PRIVATE_CLASSLOADER, true);
+ QbSdk.initTbsSettings(map);
+ QbSdk.setDownloadWithoutWifi(false);
+ QbSdk.setCoreMinVersion(QbSdk.CORE_VER_ENABLE_202207);
+ TbsListener tbsListener = new TbsListener() {
+
+ /**
+ * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
+ */
+ @Override
+ public void onDownloadFinish(int stateCode) {
+ Logger.t(TAG).d("onDownloadFinish:" + stateCode);
+ }
+
+ /**
+ * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
+ */
+ @Override
+ public void onInstallFinish(int stateCode) {
+ Logger.t(TAG).d("onInstallFinish:" + stateCode);
+ }
+
+ /**
+ * 首次安装应用,会触发内核下载,此时会有内核下载的进度回调。
+ * @param progress 0 - 100
+ */
+ @Override
+ public void onDownloadProgress(int progress) {
+ Logger.t(TAG).d("onDownloadProgress:" + progress);
+ }
+ };
+ QbSdk.PreInitCallback callback = new QbSdk.PreInitCallback() {
+ @Override
+ public void onViewInitFinished(boolean finished) {
+ if (finished) Notify.show(R.string.x5webview_enabled);
+ }
+
+ @Override
+ public void onCoreInitFinished() {
+ }
+ };
+ QbSdk.setTbsListener(tbsListener);
+ QbSdk.initX5Environment(App.get(), callback);
+ }
+
+ public static void init() {
+ if (Setting.getParseWebView() == 0) return;
+ App.post(() -> tbsInit());
+ }
+
+ public static String url() {
+ return getUrl();
+ }
+
+ private static File tbs() {
+ File tbsDir = Path.files("tbs");
+ return tbsDir;
+ }
+
+ public static File file() {
+ File tbsDir = tbs();
+ if (!tbsDir.exists()) tbsDir.mkdirs();
+ File x5 = new File(tbsDir, "x5.apk");
+ return x5;
+ }
+
+ public static void download() {
+ QbSdk.installLocalQbApk(App.get(), "46471", file().getAbsolutePath(), null);
+ }
+
+}
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 0fd8a086c..9eb9c485e 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -80,6 +80,7 @@
图片品质
图片尺寸
聚合搜索
+ 嗅探内核
全屏菜单键
首页菜单键
首页源锁定
@@ -155,6 +156,12 @@
正在检测更新…
更新
+
+ X5 WebView
+ 下载X5 WebView并启用?
+ X5 WebView已启用
+ X5 WebView嗅探中
+
发生意外错误\n抱歉给您带来不便
重新启动
@@ -252,6 +259,11 @@
- 设置页面
+
+ - 系统
+ - X5 WebView
+
+
- 播放历史
- 站点推荐
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index b780e91cd..cc8674d0c 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -80,6 +80,7 @@
圖片品質
圖片尺寸
聚合搜索
+ 嗅探內核
全屏選單鍵
首頁選單鍵
首頁源鎖定
@@ -155,6 +156,12 @@
正在檢查更新…
更新
+
+ X5 WebView
+ 下载X5 WebView並啟用?
+ X5 WebView已啟用
+ X5 WebView嗅探中
+
發生意外錯誤\n抱歉給您帶來不便
重新啟動
@@ -252,6 +259,11 @@
- 设置頁面
+
+ - 系統
+ - X5 WebView
+
+
- 播放歷史
- 站點推薦
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ab9fafbd4..0cc251499 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -80,6 +80,7 @@
Image quality
Image size
Aggregated search
+ Parse webview
Fullscreen menu key
Home menu key
Home site lock
@@ -155,6 +156,12 @@
Checking for updates…
Update
+
+ X5 WebView
+ Download X5 WebView and Enable?
+ X5 WebView Enabled
+ X5 WebView Parsing
+
An unexpected error occurred.\nSorry for the inconvenience.
Restart app
@@ -252,6 +259,11 @@
- Setting page
+
+ - System
+ - X5 WebView
+
+
- Back
- Focus move