tv增加geckoview内核
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
- `VERSION_NAME`: APK 版本名
|
||||
- `VERSION_CODE`: APK 版本号,整数
|
||||
- `MIN_SDK`: 最低 Android API,标准版为 `23`(Android 6+),兼容版为 `21`(Android 5+)
|
||||
- `GECKOVIEW_VERSION`: GeckoView 依赖版本,仅 GeckoView 版本使用,默认 `126.0.20240526221752`
|
||||
|
||||
App 启动时会自动打开:
|
||||
|
||||
@@ -18,10 +19,20 @@ BASE_URL 去掉末尾 / 后 + /tv
|
||||
|
||||
## 特性
|
||||
|
||||
- GitHub Actions 默认构建两个版本:`android6plus` 标准版和 `android5plus` 兼容版
|
||||
- GitHub Actions 默认构建四个版本:`webview-android6plus`、`webview-android5plus`、`geckoview-android6plus`、`geckoview-android5plus`
|
||||
- GitHub Actions 未配置签名 secrets 时只构建 debug APK;配置完整签名 secrets 后只构建 release APK
|
||||
- `webview` 版本使用系统 Android WebView,体积小但依赖设备内置 WebView 版本
|
||||
- `gecko` 版本自带 GeckoView 浏览器内核,用于旧系统 WebView 无法兼容 Next.js 页面时测试
|
||||
- 锁定横屏
|
||||
- 支持 Android TV Launcher
|
||||
- 允许 HTTP 明文访问
|
||||
- 允许 HTTPS 页面加载 HTTP 视频/图片等混合内容
|
||||
- 使用 `public/logo.png` 作为图标来源
|
||||
- User-Agent 追加 `MoonTVPlusAndroidTV`
|
||||
- `webview` 版本 User-Agent 追加 `MoonTVPlusAndroidTV WebView`
|
||||
|
||||
## 本地构建
|
||||
|
||||
```bash
|
||||
gradle assembleWebviewDebug -PBASE_URL="http://192.168.1.10:3000"
|
||||
gradle assembleGeckoDebug -PBASE_URL="http://192.168.1.10:3000"
|
||||
```
|
||||
|
||||
@@ -13,6 +13,7 @@ val appDisplayName = propOrEnv("APP_NAME", "APP_NAME", "MoonTVPlus TV")
|
||||
val versionNameValue = propOrEnv("VERSION_NAME", "VERSION_NAME", "1.0.0")
|
||||
val versionCodeValue = propOrEnv("VERSION_CODE", "VERSION_CODE", "1").toIntOrNull() ?: 1
|
||||
val minSdkValue = propOrEnv("MIN_SDK", "MIN_SDK", "23").toIntOrNull() ?: 23
|
||||
val geckoViewVersion = propOrEnv("GECKOVIEW_VERSION", "GECKOVIEW_VERSION", "126.0.20240526221752")
|
||||
|
||||
fun escapeJavaString(value: String): String = value
|
||||
.replace("\\", "\\\\")
|
||||
@@ -44,6 +45,27 @@ android {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
flavorDimensions += "engine"
|
||||
|
||||
productFlavors {
|
||||
create("webview") {
|
||||
dimension = "engine"
|
||||
buildConfigField("String", "ENGINE_NAME", "\"WebView\"")
|
||||
resValue("string", "engine_name", "WebView")
|
||||
}
|
||||
create("gecko") {
|
||||
dimension = "engine"
|
||||
applicationIdSuffix = ".gecko"
|
||||
buildConfigField("String", "ENGINE_NAME", "\"GeckoView\"")
|
||||
resValue("string", "engine_name", "GeckoView")
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
val storeFilePath = System.getenv("ANDROID_KEYSTORE_PATH")
|
||||
@@ -69,3 +91,7 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
add("geckoImplementation", "org.mozilla.geckoview:geckoview:$geckoViewVersion")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.moontvplus.tv;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
private static GeckoRuntime runtime;
|
||||
|
||||
private GeckoSession session;
|
||||
private GeckoView geckoView;
|
||||
private boolean canGoBack = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
);
|
||||
|
||||
geckoView = new GeckoView(this);
|
||||
geckoView.setFocusable(true);
|
||||
geckoView.setFocusableInTouchMode(true);
|
||||
geckoView.requestFocus();
|
||||
setContentView(geckoView, new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
));
|
||||
|
||||
if (runtime == null) {
|
||||
runtime = GeckoRuntime.create(this);
|
||||
}
|
||||
|
||||
session = new GeckoSession();
|
||||
session.setNavigationDelegate(new GeckoSession.NavigationDelegate() {
|
||||
@Override
|
||||
public void onCanGoBack(GeckoSession session, boolean canGoBackValue) {
|
||||
canGoBack = canGoBackValue;
|
||||
}
|
||||
});
|
||||
session.open(runtime);
|
||||
geckoView.setSession(session);
|
||||
session.loadUri(buildTvUrl(BuildConfig.BASE_URL));
|
||||
}
|
||||
|
||||
private static String buildTvUrl(String baseUrl) {
|
||||
String url = baseUrl == null ? "" : baseUrl.trim();
|
||||
if (url.isEmpty()) {
|
||||
url = "http://192.168.1.10:3000";
|
||||
}
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
while (url.endsWith("/")) {
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
if (url.endsWith("/tv")) {
|
||||
return url;
|
||||
}
|
||||
return url + "/tv";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (session != null && canGoBack) {
|
||||
session.goBack();
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
session = null;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -70,7 +70,7 @@ public class MainActivity extends Activity {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
||||
}
|
||||
settings.setUserAgentString(settings.getUserAgentString() + " MoonTVPlusAndroidTV");
|
||||
settings.setUserAgentString(settings.getUserAgentString() + " MoonTVPlusAndroidTV WebView");
|
||||
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
@@ -90,8 +90,6 @@ public class MainActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||
// Do not bypass TLS certificate errors. HTTP is allowed by network security config;
|
||||
// invalid HTTPS certificates should still be blocked for safety.
|
||||
handler.cancel();
|
||||
}
|
||||
});
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=false
|
||||
android.useAndroidX=true
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://maven.mozilla.org/maven2/")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user