安卓tv打包

This commit is contained in:
mtvpls
2026-06-01 09:52:29 +08:00
parent a682998930
commit 9d3f458291
13 changed files with 486 additions and 0 deletions
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.software.leanback"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<application
android:allowBackup="false"
android:banner="@drawable/logo"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@drawable/logo"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:exported="true"
android:resizeableActivity="false"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,200 @@
package com.moontvplus.tv;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
public class MainActivity extends Activity {
private FrameLayout root;
private WebView webView;
private View customView;
private WebChromeClient.CustomViewCallback customViewCallback;
@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
);
root = new FrameLayout(this);
setContentView(root);
setupWebView();
webView.loadUrl(buildTvUrl(BuildConfig.BASE_URL));
}
@SuppressLint("SetJavaScriptEnabled")
private void setupWebView() {
webView = new WebView(this);
webView.setFocusable(true);
webView.setFocusableInTouchMode(true);
webView.requestFocus();
root.addView(webView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
settings.setMediaPlaybackRequiresUserGesture(false);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setAllowFileAccess(false);
settings.setAllowContentAccess(true);
settings.setSupportZoom(false);
settings.setBuiltInZoomControls(false);
settings.setDisplayZoomControls(false);
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");
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@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();
}
});
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (customView != null) {
callback.onCustomViewHidden();
return;
}
customView = view;
customViewCallback = callback;
webView.setVisibility(View.GONE);
root.addView(customView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
}
@Override
public void onHideCustomView() {
hideCustomView();
}
});
}
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";
}
private void hideCustomView() {
if (customView == null) {
return;
}
root.removeView(customView);
customView = null;
webView.setVisibility(View.VISIBLE);
if (customViewCallback != null) {
customViewCallback.onCustomViewHidden();
customViewCallback = null;
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_UP) {
webView.reload();
return true;
}
return super.dispatchKeyEvent(event);
}
@Override
public void onBackPressed() {
if (customView != null) {
hideCustomView();
return;
}
if (webView != null && webView.canGoBack()) {
webView.goBack();
return;
}
super.onBackPressed();
}
@Override
protected void onResume() {
super.onResume();
if (webView != null) {
webView.onResume();
}
}
@Override
protected void onPause() {
if (webView != null) {
webView.onPause();
}
super.onPause();
}
@Override
protected void onDestroy() {
if (webView != null) {
root.removeView(webView);
webView.destroy();
webView = null;
}
super.onDestroy();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

@@ -0,0 +1,3 @@
<resources>
<color name="black">#000000</color>
</resources>
@@ -0,0 +1,9 @@
<resources>
<style name="AppTheme" parent="android:style/Theme.Material.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@color/black</item>
<item name="android:fontFamily">sans</item>
</style>
</resources>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>