From 50bf533a012e84d8fbc51979d21694ad2cb751aa Mon Sep 17 00:00:00 2001 From: Norman Breau Date: Mon, 21 Oct 2024 20:55:11 -0300 Subject: [PATCH] Rewrite to use fragments for better view control --- android/build.gradle.kts | 4 +- android/fuse/build.gradle.kts | 1 + .../java/com/breautek/fuse/FuseActivity.java | 306 +++++++++--------- .../java/com/breautek/fuse/FuseContext.java | 119 +++---- .../java/com/breautek/fuse/FuseFragment.java | 189 +++++++++++ .../com/breautek/fuse/FuseScreenUtils.java | 7 +- .../src/main/res/layout/fragment_fuse.xml | 17 + android/fuse/src/main/res/values/strings.xml | 2 + test-app/android/build.gradle.kts | 1 + test-app/android/src/main/AndroidManifest.xml | 4 +- .../breautek/fuse/testapp/MainActivity.java | 17 +- .../src/main/res/layout/activity_main.xml | 7 + .../android/src/main/res/values/themes.xml | 5 + 13 files changed, 432 insertions(+), 247 deletions(-) create mode 100644 android/fuse/src/main/java/com/breautek/fuse/FuseFragment.java create mode 100644 android/fuse/src/main/res/layout/fragment_fuse.xml diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 22fbbdc..8f804cd 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -17,8 +17,8 @@ limitations under the License. // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.7.0" apply false - id("com.android.library") version "8.7.0" apply false + id("com.android.application") version "8.7.1" apply false + id("com.android.library") version "8.7.1" apply false } tasks.wrapper { diff --git a/android/fuse/build.gradle.kts b/android/fuse/build.gradle.kts index 06e7f65..84ae637 100644 --- a/android/fuse/build.gradle.kts +++ b/android/fuse/build.gradle.kts @@ -121,6 +121,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.7.0") implementation("com.google.android.material:material:1.12.0") implementation("androidx.webkit:webkit:1.12.1") + implementation("androidx.fragment:fragment:1.8.4") implementation("org.bouncycastle:bcprov-jdk18on:1.77") implementation("org.bouncycastle:bcpkix-jdk18on:1.77") diff --git a/android/fuse/src/main/java/com/breautek/fuse/FuseActivity.java b/android/fuse/src/main/java/com/breautek/fuse/FuseActivity.java index 0ac647b..f3d8b98 100644 --- a/android/fuse/src/main/java/com/breautek/fuse/FuseActivity.java +++ b/android/fuse/src/main/java/com/breautek/fuse/FuseActivity.java @@ -1,153 +1,153 @@ - -/* -Copyright 2023 Breautek - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package com.breautek.fuse; - -import android.os.Bundle; - -import androidx.annotation.ContentView; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import android.content.Intent; -import android.view.View; -import androidx.core.view.WindowCompat; -import androidx.core.view.WindowInsetsControllerCompat; - -import android.view.Window; - -import com.breautek.fuse.plugins.IFusePluginRegistrar; - -/** - * Convenience class that can be extended which provides - * a FuseContext with all the glue bits already done. - * - * If fine control is required, it is possible to create the FuseContext - * itself, you'll need to pass through the following lifecycle methods: - * - onCreate(Bundle) - * - onStart - * - onResume - * - onPause - * - onSaveInstanceState(Bundle) - * - onLowMemory - * - onRequestPermissionsResult - * - onStop - * - onDestroy - */ -public class FuseActivity extends AppCompatActivity { - - private FuseContext $fuseContext; - - public FuseActivity() { - super(); - $init(); - } - - @ContentView - public FuseActivity(@LayoutRes int contentLayoutId) { - super(contentLayoutId); - $init(); - } - - private void $init() { - $fuseContext = new FuseContext(this, this::_onContextReady); - $fuseContext.$pluginMapLock.writeLock().lock(); - _registerFusePlugins(plugin -> $fuseContext.$registerPlugin(plugin)); - $fuseContext.$pluginMapLock.writeLock().unlock(); - } - - protected void _onContextReady() {} - - /** - * Can be overwritten by subclasses to register plugins - * - * @param registrar - */ - protected void _registerFusePlugins(IFusePluginRegistrar registrar) {} - - public FuseContext getFuseContext() { - return $fuseContext; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Window window = getWindow(); - WindowCompat.setDecorFitsSystemWindows(window, false); - $fuseContext.onCreate(savedInstanceState); - View contentView = $fuseContext.getLayout(); - setContentView(contentView); - - WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(window, contentView); - controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_DEFAULT); - } - - @Override - protected void onStart() { - super.onStart(); - $fuseContext.onStart(); - } - - @Override - protected void onStop() { - super.onStop(); - $fuseContext.onStop(); - } - - @Override - public void onLowMemory() { - super.onLowMemory(); - $fuseContext.onLowMemory(); - } - - @Override - protected void onPause() { - super.onPause(); - $fuseContext.onPause(); - } - - @Override - protected void onResume() { - super.onResume(); - $fuseContext.onResume(); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - $fuseContext.onSaveInstanceState(outState); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - $fuseContext.onRequestPermissionResult(requestCode, permissions, grantResults); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - $fuseContext.onActivityResult(requestCode, resultCode, data); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - $fuseContext.onDestroy(); - } -} +// +///* +//Copyright 2023 Breautek +// +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +//*/ +// +//package com.breautek.fuse; +// +//import android.os.Bundle; +// +//import androidx.annotation.ContentView; +//import androidx.annotation.LayoutRes; +//import androidx.annotation.NonNull; +//import androidx.appcompat.app.AppCompatActivity; +//import android.content.Intent; +//import android.view.View; +//import androidx.core.view.WindowCompat; +//import androidx.core.view.WindowInsetsControllerCompat; +// +//import android.view.Window; +// +//import com.breautek.fuse.plugins.IFusePluginRegistrar; +// +///** +// * Convenience class that can be extended which provides +// * a FuseContext with all the glue bits already done. +// * +// * If fine control is required, it is possible to create the FuseContext +// * itself, you'll need to pass through the following lifecycle methods: +// * - onCreate(Bundle) +// * - onStart +// * - onResume +// * - onPause +// * - onSaveInstanceState(Bundle) +// * - onLowMemory +// * - onRequestPermissionsResult +// * - onStop +// * - onDestroy +// */ +//public class FuseActivity extends AppCompatActivity { +// +// private FuseContext $fuseContext; +// +// public FuseActivity() { +// super(); +// $init(); +// } +// +// @ContentView +// public FuseActivity(@LayoutRes int contentLayoutId) { +// super(contentLayoutId); +// $init(); +// } +// +// private void $init() { +// $fuseContext = new FuseContext(this, this::_onContextReady); +// $fuseContext.$pluginMapLock.writeLock().lock(); +// _registerFusePlugins(plugin -> $fuseContext.$registerPlugin(plugin)); +// $fuseContext.$pluginMapLock.writeLock().unlock(); +// } +// +// protected void _onContextReady() {} +// +// /** +// * Can be overwritten by subclasses to register plugins +// * +// * @param registrar +// */ +// protected void _registerFusePlugins(IFusePluginRegistrar registrar) {} +// +// public FuseContext getFuseContext() { +// return $fuseContext; +// } +// +// @Override +// protected void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// +// Window window = getWindow(); +// WindowCompat.setDecorFitsSystemWindows(window, false); +// $fuseContext.onCreate(savedInstanceState); +// View contentView = $fuseContext.getLayout(); +// setContentView(contentView); +// +// WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(window, contentView); +// controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_DEFAULT); +// } +// +// @Override +// protected void onStart() { +// super.onStart(); +// $fuseContext.onStart(); +// } +// +// @Override +// protected void onStop() { +// super.onStop(); +// $fuseContext.onStop(); +// } +// +// @Override +// public void onLowMemory() { +// super.onLowMemory(); +// $fuseContext.onLowMemory(); +// } +// +// @Override +// protected void onPause() { +// super.onPause(); +// $fuseContext.onPause(); +// } +// +// @Override +// protected void onResume() { +// super.onResume(); +// $fuseContext.onResume(); +// } +// +// @Override +// protected void onSaveInstanceState(@NonNull Bundle outState) { +// super.onSaveInstanceState(outState); +// $fuseContext.onSaveInstanceState(outState); +// } +// +// @Override +// public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { +// super.onRequestPermissionsResult(requestCode, permissions, grantResults); +// $fuseContext.onRequestPermissionResult(requestCode, permissions, grantResults); +// } +// +// @Override +// protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// super.onActivityResult(requestCode, resultCode, data); +// $fuseContext.onActivityResult(requestCode, resultCode, data); +// } +// +// @Override +// protected void onDestroy() { +// super.onDestroy(); +// $fuseContext.onDestroy(); +// } +//} diff --git a/android/fuse/src/main/java/com/breautek/fuse/FuseContext.java b/android/fuse/src/main/java/com/breautek/fuse/FuseContext.java index 68687f8..bb0b80c 100644 --- a/android/fuse/src/main/java/com/breautek/fuse/FuseContext.java +++ b/android/fuse/src/main/java/com/breautek/fuse/FuseContext.java @@ -38,11 +38,8 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.FrameLayout; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; -import androidx.core.view.WindowInsetsCompat; +import androidx.fragment.app.FragmentActivity; import androidx.webkit.WebViewAssetLoader; import androidx.webkit.WebViewClientCompat; import java.io.IOException; @@ -70,11 +67,11 @@ public class FuseContext implements IProgressContextListener { private static final String TAG = "FuseContext"; - private final AppCompatActivity $context; + private final FragmentActivity $context; - private WebView $webview; +// private WebView $webview; private final IProgressContext $loadProgress; - private SplashLoaderView $splash; +// private SplashLoaderView $splash; /*package private*/ final ReadWriteLock $pluginMapLock; private final Map $pluginMap; @@ -93,12 +90,10 @@ public class FuseContext implements IProgressContextListener { private FuseAPIResponseFactory $responseFactory; private final FuseLogger $logger; - - private ViewGroup $container; - private final FuseScreenUtils $screenUtils; private final FuseRuntime $runtime; private final IReadyCallback $readyCallback; + private final FuseFragment $view; private static final String LOAD_CONTEXT_CORE = "FuseContext_core"; private static final String LOAD_CONTEXT_API_SERVER = "FuseContext_apiServer"; @@ -109,8 +104,9 @@ public static interface IReadyCallback { void onReady(); } - public FuseContext(AppCompatActivity context, IReadyCallback callback) { + public FuseContext(FuseFragment view, FragmentActivity context, IReadyCallback callback) { $context = context; + $view = view; $readyCallback = callback; $loadProgress = new ProgressContext(); @@ -142,6 +138,10 @@ public FuseContext(AppCompatActivity context, IReadyCallback callback) { $loadProgress.update(LOAD_CONTEXT_CORE_PLUGINS, 1); } + public FuseRuntime getRuntime() { + return $runtime; + } + public FuseScreenUtils getScreenUtils() { return $screenUtils; } @@ -150,7 +150,7 @@ public String getHost() { return HOST; } - protected ViewGroup _createLayout(AppCompatActivity context) { + protected ViewGroup _createLayout(Context context) { FrameLayout layout = new FrameLayout(context); layout.setLayoutParams( new FrameLayout.LayoutParams( @@ -161,10 +161,6 @@ protected ViewGroup _createLayout(AppCompatActivity context) { return layout; } - public ViewGroup getLayout() { - return $container; - } - public SSLContext getSSLContext() { return $apiServer.getSSLContext(); } @@ -201,6 +197,25 @@ public boolean isDebug() { } } + public IProgressContext getProgressContext() { + return $loadProgress; + } + + public void onReceivedSslError(WebView webview, SslErrorHandler handler, SslError error) { + if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) { + // Test the certificate for our own generated certificate and if so, let it pass, + if ($apiServer.verifyCertificate(error.getCertificate())) { + handler.proceed(); + } + else { + handler.cancel(); + } + } + else { + handler.cancel(); + } + } + @SuppressLint("SetJavaScriptEnabled") public void onCreate(Bundle bundle) { if (isDebug()) { @@ -211,51 +226,6 @@ public void onCreate(Bundle bundle) { $logger.info(TAG, "Fuse Version: " + BuildConfig.FUSE_VERSION); - $container = _createLayout($context); - $webview = new WebView($context); - - $splash = new SplashLoaderView($context); - $loadProgress.addListener($splash); - - $container.addView($webview); - $container.addView($splash); - - ViewCompat.setOnApplyWindowInsetsListener($container, (v, insets) -> { - $runtime.onInsetChange(insets); - return insets; - }); - - final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() - .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler($context)) - .setHttpAllowed(false) - .setDomain(getHost()) - .build(); - - $webview.setWebViewClient(new WebViewClientCompat() { - @Override - public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { - $logger.info(TAG, "DOM Request: " + request.getUrl()); - return assetLoader.shouldInterceptRequest(request.getUrl()); - } - - @SuppressLint("WebViewClientOnReceivedSslError") - @Override - public void onReceivedSslError(WebView webview, SslErrorHandler handler, SslError error) { - if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) { - // Test the certificate for our own generated certificate and if so, let it pass, - if ($apiServer.verifyCertificate(error.getCertificate())) { - handler.proceed(); - } - else { - handler.cancel(); - } - } - else { - handler.cancel(); - } - } - }); - final FuseContext self = this; new Thread(() -> { try { @@ -271,18 +241,7 @@ public void onReceivedSslError(WebView webview, SslErrorHandler handler, SslErro $loadProgress.update(LOAD_CONTEXT_API_SERVER, 1); Log.i(TAG, "API Server Port: " + $apiServer.getPort()); - $readyCallback.onReady(); - - self.runOnMainThread(() -> { - WebSettings settings = $webview.getSettings(); - settings.setAllowFileAccess(false); - settings.setAllowContentAccess(false); - settings.setJavaScriptEnabled(true); - settings.setDomStorageEnabled(true); - $webview.setWebChromeClient(new WebChromeClient()); - $webview.addJavascriptInterface(this, "BTFuseNative"); - $webview.loadUrl("https://localhost/assets/index.html"); - }); + self.runOnMainThread($readyCallback::onReady); }).start(); } @@ -355,10 +314,10 @@ public void onDestroy() { } public WebView getWebview() { - return $webview; + return $view.getWebview(); } - public AppCompatActivity getActivityContext() { + public FragmentActivity getActivityContext() { return $context; } @@ -368,7 +327,7 @@ public void registerPlugin(FusePlugin plugin) { $pluginMapLock.writeLock().unlock(); } - /*package private*/ void $registerPlugin(FusePlugin plugin) { + void $registerPlugin(FusePlugin plugin) { if ($pluginMap.containsKey(plugin.getID())) { $logger.warn(TAG, "Plugin \"" + plugin.getID() + "\" is already registered."); return; @@ -427,13 +386,13 @@ public void onWebviewReady() { public void execCallback(String callbackID, String payload) { $mainThread.post(() -> { - $webview.evaluateJavascript(String.format("window.__btfuse_doCallback(\"%s\",\"%s\");", callbackID, payload.replace("\"", "\\\"")), null); + $view.getWebview().evaluateJavascript(String.format("window.__btfuse_doCallback(\"%s\",\"%s\");", callbackID, payload.replace("\"", "\\\"")), null); }); } public void execCallback(String callbackID) { $mainThread.post(() -> { - $webview.evaluateJavascript(String.format("window.__btfuse_doCallback(\"%s\");", callbackID), null); + $view.getWebview().evaluateJavascript(String.format("window.__btfuse_doCallback(\"%s\");", callbackID), null); }); } @@ -444,9 +403,7 @@ public void runOnMainThread(Runnable runnable) { @Override public void onProgressUpdate(IProgressContext context) { if (context.isComplete()) { - $mainThread.postDelayed(() -> { - $splash.setVisibility(View.GONE); - }, 300); + $mainThread.postDelayed($view::onFuseLoad, 300); } } } diff --git a/android/fuse/src/main/java/com/breautek/fuse/FuseFragment.java b/android/fuse/src/main/java/com/breautek/fuse/FuseFragment.java new file mode 100644 index 0000000..1c97f82 --- /dev/null +++ b/android/fuse/src/main/java/com/breautek/fuse/FuseFragment.java @@ -0,0 +1,189 @@ +package com.breautek.fuse; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.net.http.SslError; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.view.ViewCompat; +import androidx.fragment.app.Fragment; +import androidx.webkit.WebViewAssetLoader; +import androidx.webkit.WebViewClientCompat; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.SslErrorHandler; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; + +import com.breautek.fuse.views.SplashLoaderView; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link FuseFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class FuseFragment extends Fragment { + public static final String LOG_TAG = "FuseFragment"; + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + private FuseContext $fuseContext; + private FuseContext.IReadyCallback $fuseCB; + + public FuseFragment() {} + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment FuseFragment. + */ + public static FuseFragment newInstance(FuseContext.IReadyCallback callback) { + FuseFragment fragment = new FuseFragment(); + fragment.$fuseCB = callback; + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + $fuseContext = new FuseContext(this, this.getActivity(), this::_onContextReady); + $fuseContext.onCreate(savedInstanceState); + } + + public FuseContext getFuseContext() { + return $fuseContext; + } + + @Nullable + public WebView getWebview() { + return getView().findViewById(R.id.webview); + } + + protected void _onContextReady() { + WebView webview = this.getView().findViewById(R.id.webview); + WebSettings settings = webview.getSettings(); + settings.setAllowFileAccess(false); + settings.setAllowContentAccess(false); + settings.setJavaScriptEnabled(true); + settings.setDomStorageEnabled(true); + webview.setWebChromeClient(new WebChromeClient()); + webview.addJavascriptInterface($fuseContext, "BTFuseNative"); + webview.loadUrl("https://localhost/assets/index.html"); + $fuseCB.onReady(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_fuse, container, false); + + ViewCompat.setOnApplyWindowInsetsListener(root, (v, insets) -> { + $fuseContext.getRuntime().onInsetChange(insets); + return insets; + }); + + SplashLoaderView loaderView = root.findViewById(R.id.splash_loader); + loaderView.setVisibility(View.VISIBLE); + + $fuseContext.getProgressContext().addListener(loaderView); + + WebView webview = root.findViewById(R.id.webview); + + final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() + .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler($fuseContext.getActivityContext())) + .setHttpAllowed(false) + .setDomain($fuseContext.getHost()) + .build(); + + webview.setWebViewClient(new WebViewClientCompat() { + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + $fuseContext.getLogger().info(LOG_TAG, "DOM Request: " + request.getUrl()); + return assetLoader.shouldInterceptRequest(request.getUrl()); + } + + @SuppressLint("WebViewClientOnReceivedSslError") + @Override + public void onReceivedSslError(WebView webview, SslErrorHandler handler, SslError error) { + $fuseContext.onReceivedSslError(webview, handler, error); + } + }); + + return root; + } + + @Override + public void onStart() { + super.onStart(); + $fuseContext.onStart(); + } + + @Override + public void onStop() { + super.onStop(); + $fuseContext.onStop(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + $fuseContext.onLowMemory(); + } + + @Override + public void onPause() { + super.onPause(); + $fuseContext.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + $fuseContext.onResume(); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + $fuseContext.onSaveInstanceState(outState); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + $fuseContext.onRequestPermissionResult(requestCode, permissions, grantResults); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + $fuseContext.onActivityResult(requestCode, resultCode, data); + } + + @Override + public void onDestroy() { + super.onDestroy(); + $fuseContext.onDestroy(); + } + + void onFuseLoad() { + SplashLoaderView loaderView = getView().findViewById(R.id.splash_loader); + WebView wb = getView().findViewById(R.id.webview); + + wb.setVisibility(View.VISIBLE); + loaderView.setVisibility(View.GONE); + } +} \ No newline at end of file diff --git a/android/fuse/src/main/java/com/breautek/fuse/FuseScreenUtils.java b/android/fuse/src/main/java/com/breautek/fuse/FuseScreenUtils.java index 0fc28cd..e4610d7 100644 --- a/android/fuse/src/main/java/com/breautek/fuse/FuseScreenUtils.java +++ b/android/fuse/src/main/java/com/breautek/fuse/FuseScreenUtils.java @@ -18,13 +18,12 @@ package com.breautek.fuse; import android.util.DisplayMetrics; - -import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.FragmentActivity; public class FuseScreenUtils { - private final AppCompatActivity $context; + private final FragmentActivity $context; - public FuseScreenUtils(AppCompatActivity context) { + public FuseScreenUtils(FragmentActivity context) { $context = context; } diff --git a/android/fuse/src/main/res/layout/fragment_fuse.xml b/android/fuse/src/main/res/layout/fragment_fuse.xml new file mode 100644 index 0000000..2f31731 --- /dev/null +++ b/android/fuse/src/main/res/layout/fragment_fuse.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/android/fuse/src/main/res/values/strings.xml b/android/fuse/src/main/res/values/strings.xml index 13f81f4..d22fb0f 100644 --- a/android/fuse/src/main/res/values/strings.xml +++ b/android/fuse/src/main/res/values/strings.xml @@ -2,4 +2,6 @@ Built with Fuse Application Icon + + Hello blank fragment \ No newline at end of file diff --git a/test-app/android/build.gradle.kts b/test-app/android/build.gradle.kts index 34eb354..e5e556d 100644 --- a/test-app/android/build.gradle.kts +++ b/test-app/android/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.7.0") implementation("com.google.android.material:material:1.12.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("androidx.core:core-splashscreen:1.0.1") implementation(project(":fuse")) implementation(project(":EchoPlugin")) } diff --git a/test-app/android/src/main/AndroidManifest.xml b/test-app/android/src/main/AndroidManifest.xml index a053be5..c841612 100644 --- a/test-app/android/src/main/AndroidManifest.xml +++ b/test-app/android/src/main/AndroidManifest.xml @@ -10,11 +10,11 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/Theme.Fuse" + android:theme="@style/Theme.Fuse.Loading" tools:targetApi="31" > + android:exported="true"> diff --git a/test-app/android/src/main/java/com/breautek/fuse/testapp/MainActivity.java b/test-app/android/src/main/java/com/breautek/fuse/testapp/MainActivity.java index 1a0dbbd..403e48e 100644 --- a/test-app/android/src/main/java/com/breautek/fuse/testapp/MainActivity.java +++ b/test-app/android/src/main/java/com/breautek/fuse/testapp/MainActivity.java @@ -18,18 +18,25 @@ package com.breautek.fuse.testapp; import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.splashscreen.SplashScreen; -import com.breautek.fuse.FuseActivity; import com.breautek.fuse.FuseContext; - +import com.breautek.fuse.FuseFragment; import com.breautek.fuse.plugins.echo.EchoPlugin; -public class MainActivity extends FuseActivity { +public class MainActivity extends AppCompatActivity { + private FuseFragment $fuse; @Override protected void onCreate(Bundle savedInstanceState) { + SplashScreen.installSplashScreen(this); super.onCreate(savedInstanceState); - FuseContext fuseContext = getFuseContext(); - fuseContext.registerPlugin(new EchoPlugin(fuseContext)); + setContentView(R.layout.activity_main); + $fuse = FuseFragment.newInstance(() -> { + FuseContext fuseContext = $fuse.getFuseContext(); + fuseContext.registerPlugin(new EchoPlugin(fuseContext)); + }); + getSupportFragmentManager().beginTransaction().add(R.id.fuse_fragment_container, $fuse).commit(); } } \ No newline at end of file diff --git a/test-app/android/src/main/res/layout/activity_main.xml b/test-app/android/src/main/res/layout/activity_main.xml index 0b15a20..c4a8c8e 100644 --- a/test-app/android/src/main/res/layout/activity_main.xml +++ b/test-app/android/src/main/res/layout/activity_main.xml @@ -6,4 +6,11 @@ android:layout_height="match_parent" tools:context=".MainActivity"> + + + + \ No newline at end of file diff --git a/test-app/android/src/main/res/values/themes.xml b/test-app/android/src/main/res/values/themes.xml index bd01fd7..1f016e6 100644 --- a/test-app/android/src/main/res/values/themes.xml +++ b/test-app/android/src/main/res/values/themes.xml @@ -19,6 +19,11 @@ true + +