web tv增加局域网遥控

This commit is contained in:
mtvpls
2026-06-19 15:26:18 +08:00
parent acb5850260
commit 9881ad3238
7 changed files with 696 additions and 5 deletions
@@ -2,22 +2,32 @@ package com.moontvplus.tv;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoView;
public class MainActivity extends Activity {
import java.net.URLEncoder;
public class MainActivity extends Activity implements RemoteCommandHandler {
private static GeckoRuntime runtime;
private GeckoSession session;
private GeckoView geckoView;
private boolean canGoBack = false;
private LocalRemoteServer localRemoteServer;
private TextView remoteHintView;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,7 +65,112 @@ public class MainActivity extends Activity {
});
session.open(runtime);
geckoView.setSession(session);
session.loadUri(buildTvUrl(BuildConfig.BASE_URL));
setupLocalRemoteServer();
session.loadUri(withLocalRemoteHash(buildTvUrl(BuildConfig.BASE_URL)));
}
private void setupLocalRemoteServer() {
localRemoteServer = new LocalRemoteServer(this);
localRemoteServer.start();
String url = localRemoteServer.getRemoteUrl();
if (url == null) return;
remoteHintView = new TextView(this);
remoteHintView.setText("局域网遥控:手机浏览器打开\n" + url);
remoteHintView.setTextColor(0xFFE0E7FF);
remoteHintView.setTextSize(13);
remoteHintView.setPadding(18, 12, 18, 12);
remoteHintView.setBackgroundColor(0xAA111827);
addContentView(remoteHintView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
));
mainHandler.postDelayed(() -> {
if (remoteHintView != null) remoteHintView.setVisibility(View.GONE);
}, 15000);
}
private int keyCodeForRemoteKey(String key, String digit) {
if ("up".equals(key)) return KeyEvent.KEYCODE_DPAD_UP;
if ("down".equals(key)) return KeyEvent.KEYCODE_DPAD_DOWN;
if ("left".equals(key)) return KeyEvent.KEYCODE_DPAD_LEFT;
if ("right".equals(key)) return KeyEvent.KEYCODE_DPAD_RIGHT;
if ("ok".equals(key)) return KeyEvent.KEYCODE_DPAD_CENTER;
if ("back".equals(key)) return KeyEvent.KEYCODE_BACK;
if ("menu".equals(key)) return KeyEvent.KEYCODE_MENU;
if ("home".equals(key)) return KeyEvent.KEYCODE_HOME;
if ("playPause".equals(key)) return KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
if ("pageUp".equals(key)) return KeyEvent.KEYCODE_PAGE_UP;
if ("pageDown".equals(key)) return KeyEvent.KEYCODE_PAGE_DOWN;
if ("digit".equals(key) && digit != null && digit.length() == 1 && digit.charAt(0) >= '0' && digit.charAt(0) <= '9') {
return KeyEvent.KEYCODE_0 + (digit.charAt(0) - '0');
}
return KeyEvent.KEYCODE_UNKNOWN;
}
@Override
public void onRemoteKey(String key, boolean repeat, String digit) {
int keyCode = keyCodeForRemoteKey(key, digit);
if (keyCode == KeyEvent.KEYCODE_UNKNOWN) return;
mainHandler.post(() -> {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return;
}
dispatchKeyCode(keyCode, repeat);
});
}
@Override
public void onRemoteText(String mode, String text) {
mainHandler.post(() -> {
String safeMode = mode == null ? "replace" : mode;
if ("clear".equals(safeMode) || "replace".equals(safeMode)) {
dispatchCtrlA();
dispatchKeyCode(KeyEvent.KEYCODE_DEL, false);
} else if ("backspace".equals(safeMode)) {
dispatchKeyCode(KeyEvent.KEYCODE_DEL, false);
return;
}
if (!"clear".equals(safeMode) && text != null && !text.isEmpty()) {
dispatchText(text);
}
});
}
private void dispatchKeyCode(int keyCode, boolean repeat) {
long now = System.currentTimeMillis();
geckoView.dispatchKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, repeat ? 1 : 0));
geckoView.dispatchKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
}
private void dispatchCtrlA() {
long now = System.currentTimeMillis();
geckoView.dispatchKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, KeyEvent.META_CTRL_ON));
geckoView.dispatchKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, KeyEvent.META_CTRL_ON));
}
private void dispatchText(String text) {
KeyEvent[] events = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD).getEvents(text.toCharArray());
if (events != null) {
for (KeyEvent event : events) {
geckoView.dispatchKeyEvent(event);
}
return;
}
geckoView.dispatchKeyEvent(new KeyEvent(System.currentTimeMillis(), text, KeyCharacterMap.VIRTUAL_KEYBOARD, 0));
}
private String withLocalRemoteHash(String url) {
String remoteUrl = localRemoteServer == null ? null : localRemoteServer.getRemoteUrl();
if (remoteUrl == null || remoteUrl.isEmpty()) return url;
try {
return url + "#localRemoteUrl=" + URLEncoder.encode(remoteUrl, "UTF-8");
} catch (Exception ignored) {
return url;
}
}
private static String buildTvUrl(String baseUrl) {
@@ -86,6 +201,10 @@ public class MainActivity extends Activity {
@Override
protected void onDestroy() {
if (localRemoteServer != null) {
localRemoteServer.stop();
localRemoteServer = null;
}
if (session != null) {
session.close();
session = null;