From c7fd9770cde2b3646741c81aef1a62302e4e2d21 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Fri, 20 Dec 2024 09:06:59 +0700 Subject: [PATCH] first commit --- .gitignore | 15 + .idea/.gitignore | 3 + .idea/.name | 1 + .idea/compiler.xml | 6 + .idea/deploymentTargetSelector.xml | 10 + .idea/gradle.xml | 19 + .idea/migrations.xml | 10 + .idea/misc.xml | 10 + .idea/other.xml | 340 ++++++++++++++++++ app/.gitignore | 1 + app/build.gradle.kts | 47 +++ app/libs/IminLibs1.0.20.jar | Bin 0 -> 15424 bytes ...NeoStraElectronicSDK-3-v1.3_2302281129.jar | Bin 0 -> 9913 bytes app/proguard-rules.pro | 21 ++ .../ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 62 ++++ .../myapplication/DifferentDisplay.java | 65 ++++ .../example/myapplication/MainActivity.java | 116 ++++++ .../myapplication/MyWebChromeClient.java | 59 +++ .../myapplication/MyWebViewClient.java | 18 + .../example/myapplication/ScreenActivity.java | 123 +++++++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++ .../res/drawable/ic_launcher_foreground.xml | 30 ++ app/src/main/res/layout/activity_main.xml | 37 ++ app/src/main/res/layout/activity_screen.xml | 65 ++++ app/src/main/res/layout/display_layout.xml | 11 + app/src/main/res/menu/menu_main.xml | 10 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/navigation/nav_graph.xml | 28 ++ app/src/main/res/values-land/dimens.xml | 3 + app/src/main/res/values-night/themes.xml | 7 + app/src/main/res/values-v23/themes.xml | 9 + app/src/main/res/values-w1240dp/dimens.xml | 3 + app/src/main/res/values-w600dp/dimens.xml | 3 + app/src/main/res/values/colors.xml | 5 + app/src/main/res/values/dimens.xml | 3 + app/src/main/res/values/strings.xml | 46 +++ app/src/main/res/values/themes.xml | 9 + app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + .../myapplication/ExampleUnitTest.java | 17 + build.gradle.kts | 4 + gradle.properties | 21 ++ gradle/libs.versions.toml | 24 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 ++++++++++ gradlew.bat | 89 +++++ settings.gradle.kts | 23 ++ 60 files changed, 1804 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/deploymentTargetSelector.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/migrations.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/other.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle.kts create mode 100644 app/libs/IminLibs1.0.20.jar create mode 100644 app/libs/NeoStraElectronicSDK-3-v1.3_2302281129.jar create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/example/myapplication/DifferentDisplay.java create mode 100644 app/src/main/java/com/example/myapplication/MainActivity.java create mode 100644 app/src/main/java/com/example/myapplication/MyWebChromeClient.java create mode 100644 app/src/main/java/com/example/myapplication/MyWebViewClient.java create mode 100644 app/src/main/java/com/example/myapplication/ScreenActivity.java create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_screen.xml create mode 100644 app/src/main/res/layout/display_layout.xml create mode 100644 app/src/main/res/menu/menu_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/navigation/nav_graph.xml create mode 100644 app/src/main/res/values-land/dimens.xml create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values-v23/themes.xml create mode 100644 app/src/main/res/values-w1240dp/dimens.xml create mode 100644 app/src/main/res/values-w600dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/test/java/com/example/myapplication/ExampleUnitTest.java create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..b3405b3 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +My Application \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..0897082 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0ad17cb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..b45a6e0 --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,340 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..681e29f --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,47 @@ +plugins { + alias(libs.plugins.android.application) +} + +android { + namespace = "com.example.myapplication" + compileSdk = 34 + + defaultConfig { + applicationId = "com.example.myapplication" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + buildFeatures { + viewBinding = true + } +} + +dependencies { + + implementation(libs.appcompat) + implementation(libs.material) + implementation(libs.constraintlayout) + implementation(libs.navigation.fragment) + implementation(libs.navigation.ui) + testImplementation(libs.junit) + androidTestImplementation(libs.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/app/libs/IminLibs1.0.20.jar b/app/libs/IminLibs1.0.20.jar new file mode 100644 index 0000000000000000000000000000000000000000..04113ee027ce82e32b06cce9b1af9e736353957e GIT binary patch literal 15424 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 Dxfv`J literal 0 HcmV?d00001 diff --git a/app/libs/NeoStraElectronicSDK-3-v1.3_2302281129.jar b/app/libs/NeoStraElectronicSDK-3-v1.3_2302281129.jar new file mode 100644 index 0000000000000000000000000000000000000000..c177b7518853d99be6cbea0894571d5d0b42b5b9 GIT binary patch literal 9913 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 literal 0 HcmV?d00001 diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java new file mode 100644 index 0000000..982ba51 --- /dev/null +++ b/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.myapplication; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.myapplication", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..23d0d38 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/DifferentDisplay.java b/app/src/main/java/com/example/myapplication/DifferentDisplay.java new file mode 100644 index 0000000..abf4f50 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/DifferentDisplay.java @@ -0,0 +1,65 @@ +package com.example.myapplication; + +import android.annotation.SuppressLint; +import android.app.Presentation; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.view.Display; +import android.view.WindowManager; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.VideoView; + + +@SuppressLint("NewApi") +public class DifferentDisplay extends Presentation { + + private TextView text; + private ImageView image; + private VideoView video; + + public DifferentDisplay(Context outerContext, Display display) { + super(outerContext, display); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.display_layout); + //此功能作用于主屏Activity返回桌面后,副屏View仍然显示 + //This function is used to display the secondary + // screen View after the main screen activity returns to the desktop + if(Build.VERSION.SDK_INT >=32){ + + }else if (Build.VERSION.SDK_INT>=26){ + // 画中画等详细请查看android sdk For details such as picture in picture, please check the android sdk + getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); + }else { + // 8.0 以下的安卓版本要实现上述功能使用以下api Android versions below 8.0 use the following apis to achieve the above functions + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY); + } + + WebView myWebView = (WebView) findViewById(R.id.webview2); + + myWebView.setWebViewClient(new MyWebViewClient()); + myWebView.setWebChromeClient(new WebChromeClient()); + WebSettings webSettings = myWebView.getSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setLoadWithOverviewMode(true); + webSettings.setDomStorageEnabled(true); + webSettings.setUseWideViewPort(true); + webSettings.setDefaultTextEncodingName("utf-8"); + webSettings.setUserAgentString("Desktop"); + webSettings.setBuiltInZoomControls(true); + webSettings.setDisplayZoomControls(false); + webSettings.setSupportMultipleWindows(true); + webSettings.setJavaScriptCanOpenWindowsAutomatically(true); + myWebView.loadUrl("https://odoodev.mapan.co.id"); + } + + +} diff --git a/app/src/main/java/com/example/myapplication/MainActivity.java b/app/src/main/java/com/example/myapplication/MainActivity.java new file mode 100644 index 0000000..d3232e6 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/MainActivity.java @@ -0,0 +1,116 @@ +package com.example.myapplication; + +import android.annotation.SuppressLint; +import android.app.Presentation; +import android.content.Context; +import android.content.Intent; +import android.hardware.display.DisplayManager; +import android.media.MediaRouter; +import android.os.Bundle; + +import com.google.android.material.snackbar.Snackbar; + +import androidx.appcompat.app.AppCompatActivity; + +import android.util.Log; +import android.view.Display; +import android.view.View; + +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import com.example.myapplication.databinding.ActivityMainBinding; + +import android.view.Menu; +import android.view.MenuItem; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.widget.Toast; + +public class MainActivity extends AppCompatActivity { + + private AppBarConfiguration appBarConfiguration; + private ActivityMainBinding binding; + private Presentation presentation; + + @SuppressLint("SetJavaScriptEnabled") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + setSupportActionBar(binding.toolbar); + + WebView myWebView = (WebView) findViewById(R.id.webview); + + myWebView.setWebViewClient(new MyWebViewClient()); + myWebView.setWebChromeClient(new WebChromeClient()); + WebSettings webSettings = myWebView.getSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setLoadWithOverviewMode(true); + webSettings.setDomStorageEnabled(true); + webSettings.setUseWideViewPort(true); + webSettings.setDefaultTextEncodingName("utf-8"); + webSettings.setUserAgentString("Desktop"); + webSettings.setBuiltInZoomControls(true); + webSettings.setDisplayZoomControls(false); + webSettings.setSupportMultipleWindows(true); + webSettings.setJavaScriptCanOpenWindowsAutomatically(true); + myWebView.loadUrl("https://odoodev.mapan.co.id"); + + if (presentation != null) { + presentation.cancel(); + presentation = null; + return; + } + + binding.fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dualScreenFunction(view); + } + }); + } + + public void dualScreenFunction(View view){ + DisplayManager mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); + Display[] displays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + if (displays != null && getPresentationDisplays() != null) { + presentation = new DifferentDisplay(getApplicationContext(), getPresentationDisplays()); + presentation.show(); + } else { + Toast.makeText(view.getContext(), "no second screen", Toast.LENGTH_SHORT).show(); + } + } + + public Display getPresentationDisplays() { + DisplayManager mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); + Display[] displays = mDisplayManager.getDisplays(); + if (displays != null) { + for (int i = 0; i < displays.length; i++) { + //Log.e(TAG, "屏幕==>" + displays[i] + " Flag:==> " + displays[i].getFlags()); + if ((displays[i].getFlags() & Display.FLAG_SECURE) != 0 + && (displays[i].getFlags() & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0 + && (displays[i].getFlags() & Display.FLAG_PRESENTATION) != 0) { + //Log.e(TAG, "第一个真实存在的副屏屏幕==> " + displays[i]); + return displays[i]; + } + } + } + return null; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (presentation != null) { + presentation.cancel(); + presentation = null; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/MyWebChromeClient.java b/app/src/main/java/com/example/myapplication/MyWebChromeClient.java new file mode 100644 index 0000000..9a26690 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/MyWebChromeClient.java @@ -0,0 +1,59 @@ +package com.example.myapplication; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Message; +import android.webkit.JsResult; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +public class MyWebChromeClient extends WebChromeClient { + @Override + public boolean onCreateWindow(WebView view, boolean isDialog, + boolean isUserGesture, Message resultMsg) { + WebView newWebView = new WebView(view.getContext()); + newWebView.getSettings().setJavaScriptEnabled(true); + newWebView.getSettings().setSupportZoom(true); + newWebView.getSettings().setBuiltInZoomControls(true); + newWebView.getSettings().setPluginState(WebSettings.PluginState.ON); + newWebView.getSettings().setSupportMultipleWindows(true); + view.addView(newWebView); + WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + newWebView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + view.loadUrl(url); + return true; + } + }); + + return true; + } + + @Override + public boolean onJsAlert(WebView view, String url, String message, JsResult result) + { + final JsResult finalRes = result; + new AlertDialog.Builder(view.getContext()) + .setMessage(message) + .setPositiveButton(android.R.string.ok, + new AlertDialog.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) { + finalRes.confirm(); + } + }) + .setCancelable(false) + .create() + .show(); + return true; + } +} + diff --git a/app/src/main/java/com/example/myapplication/MyWebViewClient.java b/app/src/main/java/com/example/myapplication/MyWebViewClient.java new file mode 100644 index 0000000..5d1d116 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/MyWebViewClient.java @@ -0,0 +1,18 @@ +package com.example.myapplication; + +import static androidx.core.content.ContextCompat.startActivity; + +import android.content.Intent; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +public class MyWebViewClient extends WebViewClient { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + view.loadUrl(url); + return true; + } + + +} diff --git a/app/src/main/java/com/example/myapplication/ScreenActivity.java b/app/src/main/java/com/example/myapplication/ScreenActivity.java new file mode 100644 index 0000000..aa1a4b9 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/ScreenActivity.java @@ -0,0 +1,123 @@ +package com.example.myapplication; + +import android.app.Presentation; +import android.content.Context; +import android.content.Intent; +import android.hardware.display.DisplayManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.view.Display; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.MediaController; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.VideoView; +import androidx.appcompat.app.AppCompatActivity; + +/** + * @author :Chenjk + * @version 1.0 + * @createTime :2023/12/29 10:55 + **/ +public class ScreenActivity extends AppCompatActivity { + private static final String TAG = "display_demo"; + private Presentation presentation; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_screen); + Button showDisplay = findViewById(R.id.btn_open_display); + Button showText = findViewById(R.id.btn_show_text); + Button showPic = findViewById(R.id.btn_show_pic); + Button showVideo = findViewById(R.id.btn_show_video); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) { + if (!Settings.canDrawOverlays(this)) { + Toast.makeText(this, "请同意显示窗口权限", Toast.LENGTH_SHORT).show(); + startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)); + } + } + + showDisplay.setOnClickListener(v -> { + if (presentation != null) { + presentation.cancel(); + presentation = null; + return; + } +// showSecondByMediaRouter(MainActivity.this); + showSecondByDisplayManager(ScreenActivity.this); + + }); + } + + +// private void showSecondByMediaRouter(Context context){ +// MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); +// MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO); +// if (route != null) { +// Display presentationDisplay = route.getPresentationDisplay(); +// if (presentationDisplay != null) { +// presentation = new DifferentDisplay(context, presentationDisplay); +// presentation.show(); +// } +// } +// } + + private void showSecondByDisplayManager(Context context) { + DisplayManager mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); + Display[] displays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + if (displays != null && getPresentationDisplays() != null) { + presentation = new DifferentDisplay(getApplicationContext(), getPresentationDisplays()); + presentation.show(); + } else { + Toast.makeText(ScreenActivity.this, "no second screen", Toast.LENGTH_SHORT).show(); + } + /*副屏的Window*/ + + } + + public Display getPresentationDisplays() { + DisplayManager mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); + Display[] displays = mDisplayManager.getDisplays(); + if (displays != null) { + for (int i = 0; i < displays.length; i++) { + Log.e(TAG, "屏幕==>" + displays[i] + " Flag:==> " + displays[i].getFlags()); + if ((displays[i].getFlags() & Display.FLAG_SECURE) != 0 + && (displays[i].getFlags() & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0 + && (displays[i].getFlags() & Display.FLAG_PRESENTATION) != 0) { + Log.e(TAG, "第一个真实存在的副屏屏幕==> " + displays[i]); + return displays[i]; + } + } + } + + return null; + } + +// private void showSecondByActivity(Context context){ +// ActivityOptions options = ActivityOptions.makeBasic(); +// MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); +// MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO); +// if (route != null) { +// Display presentationDisplay = route.getPresentationDisplay(); +// options.setLaunchDisplayId(presentationDisplay.getDisplayId()); +// Intent intent = new Intent("android.intent.action.MUSIC_PLAYER"); +// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// startActivity(intent, options.toBundle()); +// } +// } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (presentation != null) { + presentation.cancel(); + presentation = null; + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..22a2e05 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_screen.xml b/app/src/main/res/layout/activity_screen.xml new file mode 100644 index 0000000..dbe7e40 --- /dev/null +++ b/app/src/main/res/layout/activity_screen.xml @@ -0,0 +1,65 @@ + + + +