diff --git a/android_opd_queue_tv/app/build.gradle b/android_opd_queue_tv/app/build.gradle
new file mode 100644
index 0000000..34b69e6
--- /dev/null
+++ b/android_opd_queue_tv/app/build.gradle
@@ -0,0 +1,35 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ namespace 'com.eatria.hms.opdqueue'
+ compileSdk 34
+
+ defaultConfig {
+ applicationId "com.eatria.hms.opdqueue"
+ minSdk 21
+ targetSdk 34
+ versionCode 1
+ versionName "1.0.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.11.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+}
diff --git a/android_opd_queue_tv/app/src/main/AndroidManifest.xml b/android_opd_queue_tv/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..77cf57a
--- /dev/null
+++ b/android_opd_queue_tv/app/src/main/AndroidManifest.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android_opd_queue_tv/app/src/main/java/com/eatria/hms/opdqueue/MainActivity.java b/android_opd_queue_tv/app/src/main/java/com/eatria/hms/opdqueue/MainActivity.java
new file mode 100644
index 0000000..24b10c1
--- /dev/null
+++ b/android_opd_queue_tv/app/src/main/java/com/eatria/hms/opdqueue/MainActivity.java
@@ -0,0 +1,120 @@
+package com.eatria.hms.opdqueue;
+
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
+
+public class MainActivity extends AppCompatActivity {
+
+ private WebView webView;
+ private ProgressBar progressBar;
+ private static final String PREFS_NAME = "HMSQueuePrefs";
+ private static final String KEY_SERVER_URL = "server_url";
+ private static final String DEFAULT_URL = "http://192.168.1.100:8080/app/queue";
+
+ @Override
+ @SuppressLint("SetJavaScriptEnabled")
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Keep screen turned on continuous (TV Monitor Display)
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ // Hide Android status bar for immersive full TV screen
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+ setContentView(R.layout.activity_main);
+
+ webView = findViewById(R.id.webView);
+ progressBar = findViewById(R.id.progressBar);
+
+ // Configure High-Performance WebView Settings
+ WebSettings webSettings = webView.getSettings();
+ webSettings.setJavaScriptEnabled(true);
+ webSettings.setDomStorageEnabled(true);
+ webSettings.setDatabaseEnabled(true);
+ webSettings.setAllowFileAccess(true);
+ webSettings.setAllowContentAccess(true);
+ webSettings.setMediaPlaybackRequiresUserGesture(false); // Enable auto audio callouts on TV
+ webSettings.setUseWideViewPort(true);
+ webSettings.setLoadWithOverviewMode(true);
+ webSettings.setBuiltInZoomControls(false);
+ webSettings.setSupportZoom(false);
+
+ webView.setWebViewClient(new WebViewClient() {
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ if (progressBar != null) progressBar.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ if (progressBar != null) progressBar.setVisibility(View.GONE);
+ }
+ });
+
+ webView.setWebChromeClient(new WebChromeClient());
+
+ // Load configured URL
+ loadConfiguredUrl();
+ }
+
+ private void loadConfiguredUrl() {
+ SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
+ String url = prefs.getString(KEY_SERVER_URL, DEFAULT_URL);
+ webView.loadUrl(url);
+ }
+
+ private void showServerUrlDialog() {
+ SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
+ String currentUrl = prefs.getString(KEY_SERVER_URL, DEFAULT_URL);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Configure HMS Server URL");
+
+ final EditText input = new EditText(this);
+ input.setText(currentUrl);
+ builder.setView(input);
+
+ builder.setPositiveButton("Save & Reload", (dialog, which) -> {
+ String newUrl = input.getText().toString().trim();
+ if (!newUrl.isEmpty()) {
+ prefs.edit().putString(KEY_SERVER_URL, newUrl).apply();
+ webView.loadUrl(newUrl);
+ Toast.makeText(MainActivity.this, "URL Saved: " + newUrl, Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
+ builder.show();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ // TV Remote Long-Press Menu Button or Back Button to edit URL
+ if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SETTINGS) {
+ showServerUrlDialog();
+ return true;
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
+ webView.goBack();
+ return true;
+ }
+
+ return super.onKeyDown(keyCode, event);
+ }
+}
diff --git a/android_opd_queue_tv/app/src/main/res/layout/activity_main.xml b/android_opd_queue_tv/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..aa2d7e1
--- /dev/null
+++ b/android_opd_queue_tv/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
diff --git a/android_opd_queue_tv/app/src/main/res/values/strings.xml b/android_opd_queue_tv/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a87bd10
--- /dev/null
+++ b/android_opd_queue_tv/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ HMS OPD Queue TV
+
diff --git a/android_opd_queue_tv/app/src/main/res/values/styles.xml b/android_opd_queue_tv/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..303c3ce
--- /dev/null
+++ b/android_opd_queue_tv/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/android_opd_queue_tv/build.gradle b/android_opd_queue_tv/build.gradle
new file mode 100644
index 0000000..df4514e
--- /dev/null
+++ b/android_opd_queue_tv/build.gradle
@@ -0,0 +1,20 @@
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.2.2'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/android_opd_queue_tv/gradle.properties b/android_opd_queue_tv/gradle.properties
new file mode 100644
index 0000000..cc18a0c
--- /dev/null
+++ b/android_opd_queue_tv/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android_opd_queue_tv/settings.gradle b/android_opd_queue_tv/settings.gradle
new file mode 100644
index 0000000..e391733
--- /dev/null
+++ b/android_opd_queue_tv/settings.gradle
@@ -0,0 +1,17 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "HMS OPD Queue TV"
+include ':app'