From 1b379bf3d408d8eb8e0237f59a67fd2f78d84496 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Sun, 30 Aug 2026 01:29:15 +0530 Subject: [PATCH] feat(pwa): add Android TV native app project for OPD Queue TV display --- android_opd_queue_tv/app/build.gradle | 35 +++++ .../app/src/main/AndroidManifest.xml | 47 +++++++ .../com/eatria/hms/opdqueue/MainActivity.java | 120 ++++++++++++++++++ .../app/src/main/res/layout/activity_main.xml | 19 +++ .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 8 ++ android_opd_queue_tv/build.gradle | 20 +++ android_opd_queue_tv/gradle.properties | 3 + android_opd_queue_tv/settings.gradle | 17 +++ 9 files changed, 272 insertions(+) create mode 100644 android_opd_queue_tv/app/build.gradle create mode 100644 android_opd_queue_tv/app/src/main/AndroidManifest.xml create mode 100644 android_opd_queue_tv/app/src/main/java/com/eatria/hms/opdqueue/MainActivity.java create mode 100644 android_opd_queue_tv/app/src/main/res/layout/activity_main.xml create mode 100644 android_opd_queue_tv/app/src/main/res/values/strings.xml create mode 100644 android_opd_queue_tv/app/src/main/res/values/styles.xml create mode 100644 android_opd_queue_tv/build.gradle create mode 100644 android_opd_queue_tv/gradle.properties create mode 100644 android_opd_queue_tv/settings.gradle 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'