diff --git a/basic/consumer-rules.pro b/basic/consumer-rules.pro index 0b4d9374..5e2aa2de 100644 --- a/basic/consumer-rules.pro +++ b/basic/consumer-rules.pro @@ -1,3 +1,8 @@ +# DrawableKt.installApi24InflateDelegates -keep class androidx.appcompat.widget.ResourceManagerInternal { *; } -keep class androidx.appcompat.widget.ResourceManagerInternal$InflateDelegate { *; } --keep class * extends androidx.appcompat.widget.ResourceManagerInternal$InflateDelegate { *; } \ No newline at end of file +-keep class * extends androidx.appcompat.widget.ResourceManagerInternal$InflateDelegate { *; } + +# EdgeToEdgeCompat +-keep class androidx.activity.EdgeToEdgeImpl { *; } +-keep class * extends androidx.activity.EdgeToEdgeImpl { *; } \ No newline at end of file diff --git a/basic/src/main/java/androidx/activity/EdgeToEdgeCompat.java b/basic/src/main/java/androidx/activity/EdgeToEdgeCompat.java new file mode 100644 index 00000000..6c30a23b --- /dev/null +++ b/basic/src/main/java/androidx/activity/EdgeToEdgeCompat.java @@ -0,0 +1,89 @@ +package androidx.activity; + +import android.app.Activity; +import android.graphics.Color; +import android.os.Build; +import android.util.Log; +import android.view.View; +import android.view.Window; + +import com.dede.basic.utils.DynamicObjectUtils; +import com.dede.basic.utils.dynamic.DynamicResult; + +import org.jetbrains.annotations.Nullable; + +/** + * EdgeToEdge compat + * + * @see EdgeToEdge + */ +public class EdgeToEdgeCompat { + + private static final String TAG = "EdgeToEdgeCompat"; + + @Nullable + private final static EdgeToEdgeImpl impl = createEdgeToEdgeImpl(); + + /** + * Create EdgeToEdge instance + * + * @return EdgeToEdgeImpl instance + * @see EdgeToEdge#enable(ComponentActivity) + */ + @Nullable + private static EdgeToEdgeImpl createEdgeToEdgeImpl() { + String className = "androidx.activity.EdgeToEdgeBase"; + final int[] apis = { + Build.VERSION_CODES.R, // 30 + Build.VERSION_CODES.Q, // 29 + Build.VERSION_CODES.P, // 28 + Build.VERSION_CODES.O, // 26 + Build.VERSION_CODES.M, // 23 + Build.VERSION_CODES.LOLLIPOP,// 21 + }; + for (int api : apis) { + if (Build.VERSION.SDK_INT >= api) { + className = "androidx.activity.EdgeToEdgeApi" + api; + break; + } + } + DynamicResult dynamicResult = DynamicObjectUtils.asDynamicObject(className) + .newInstance(new Class[0], new Object[0]); + EdgeToEdgeImpl impl = DynamicResult.getTypeValue(dynamicResult, EdgeToEdgeImpl.class); + Log.i(TAG, "EdgeToEdgeImpl: " + impl); + return impl; + } + + private static boolean getDetectDarkMode(SystemBarStyle systemBarStyle, View view) { + // internal val detectDarkMode: (Resources) -> Boolean + // androidx.activity library + // release build + return systemBarStyle.getDetectDarkMode$activity_release().invoke(view.getResources()); + } + + public static void enable(Activity activity, SystemBarStyle statusBarStyle, SystemBarStyle navigationBarStyle) { + if (activity instanceof ComponentActivity) { + EdgeToEdge.enable((ComponentActivity) activity, statusBarStyle, navigationBarStyle); + return; + } + + if (impl == null) { + Log.w(TAG, "enableEdgeToEdge, impl == null"); + return; + } + + Window window = activity.getWindow(); + View view = window.getDecorView(); + boolean statusBarIsDark = getDetectDarkMode(statusBarStyle, view); + boolean navigationBarIsDark = getDetectDarkMode(navigationBarStyle, view); + impl.setUp( + statusBarStyle, navigationBarStyle, window, view, statusBarIsDark, navigationBarIsDark + ); + impl.adjustLayoutInDisplayCutoutMode(window); + } + + public static void enable(Activity activity) { + enable(activity, SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT), + SystemBarStyle.auto(EdgeToEdge.getDefaultLightScrim(), EdgeToEdge.getDefaultDarkScrim())); + } +} diff --git a/basic/src/main/java/com/dede/basic/Utils.kt b/basic/src/main/java/com/dede/basic/Utils.kt index c58cc281..e2ca1efa 100644 --- a/basic/src/main/java/com/dede/basic/Utils.kt +++ b/basic/src/main/java/com/dede/basic/Utils.kt @@ -9,15 +9,8 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageInfo import android.content.pm.PackageManager.NameNotFoundException -import android.graphics.Color import android.os.Build import android.provider.Settings -import android.view.WindowManager -import androidx.activity.ComponentActivity -import androidx.activity.enableEdgeToEdge -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat object Utils { @@ -83,36 +76,4 @@ object Utils { val Activity.isPlatLogoActivity: Boolean get() = javaClass.simpleName == "PlatLogoActivity" - fun Activity.platLogoEdge2Edge() { - if (this is ComponentActivity) { - this.enableEdgeToEdge() - return - } - - @Suppress("DEPRECATION") - with(window) { - addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) - addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) - - navigationBarColor = Color.TRANSPARENT - statusBarColor = Color.TRANSPARENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - isNavigationBarContrastEnforced = false - isStatusBarContrastEnforced = false - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - attributes = attributes.apply { - layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - } - - WindowCompat.setDecorFitsSystemWindows(this, false) - val windowInsetsController = WindowCompat.getInsetsController(this, this.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) - windowInsetsController.systemBarsBehavior = - WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - } - } } diff --git a/basic/src/main/java/com/dede/basic/utils/DynamicObjectUtils.kt b/basic/src/main/java/com/dede/basic/utils/DynamicObjectUtils.kt index 614b7c22..763b97c4 100644 --- a/basic/src/main/java/com/dede/basic/utils/DynamicObjectUtils.kt +++ b/basic/src/main/java/com/dede/basic/utils/DynamicObjectUtils.kt @@ -13,6 +13,7 @@ import kotlin.reflect.KClass object DynamicObjectUtils { + @JvmStatic fun forName(className: String): Class? { return try { Class.forName(className) @@ -22,19 +23,23 @@ object DynamicObjectUtils { } } + @JvmStatic fun asDynamicObject(className: String): DynamicObject { val clazz = forName(className) ?: return ClassNotFoundDynamicObject.INSTANCE return asDynamicObject(clazz) } + @JvmStatic fun asDynamicObject(obj: Any): DynamicObject { return ReflectDynamicObject(obj, obj.javaClass) } + @JvmStatic fun asDynamicObject(clazz: Class): DynamicObject { return ReflectDynamicObject(null, clazz) } + @JvmStatic fun asDynamicObject(clazz: KClass): DynamicObject { return asDynamicObject(clazz.java) } diff --git a/basic/src/main/java/com/dede/basic/utils/dynamic/DynamicObject.kt b/basic/src/main/java/com/dede/basic/utils/dynamic/DynamicObject.kt index 647e01e2..0254fc44 100644 --- a/basic/src/main/java/com/dede/basic/utils/dynamic/DynamicObject.kt +++ b/basic/src/main/java/com/dede/basic/utils/dynamic/DynamicObject.kt @@ -71,6 +71,7 @@ class DynamicResult private constructor( return getTypeValue(kClass.java) } + @JvmStatic @Suppress("UNCHECKED_CAST") fun DynamicResult.getTypeValue(tClass: Class): T? { val value = this.getValue() diff --git a/core/activity-actions/src/main/java/com/dede/android_eggs/util/actions/PlatLogoActivityAction.kt b/core/activity-actions/src/main/java/com/dede/android_eggs/util/actions/PlatLogoActivityAction.kt index 3829867a..d5f4bc9e 100644 --- a/core/activity-actions/src/main/java/com/dede/android_eggs/util/actions/PlatLogoActivityAction.kt +++ b/core/activity-actions/src/main/java/com/dede/android_eggs/util/actions/PlatLogoActivityAction.kt @@ -1,22 +1,22 @@ package com.dede.android_eggs.util.actions import android.app.Activity +import androidx.activity.EdgeToEdgeCompat import com.dede.android_eggs.util.ActivityActionDispatcher import com.dede.android_eggs.views.main.util.EasterEggShortcutsHelp import com.dede.basic.Utils.isPlatLogoActivity -import com.dede.basic.Utils.platLogoEdge2Edge internal class PlatLogoActivityAction : ActivityActionDispatcher.ActivityAction { override fun onPreCreate(activity: Activity) { if (activity.isPlatLogoActivity) { - activity.platLogoEdge2Edge() + EdgeToEdgeCompat.enable(activity) } } override fun onCreate(activity: Activity) { if (activity.isPlatLogoActivity) { - EasterEggShortcutsHelp.reportShortcutUsed(activity, activity.intent) + EasterEggShortcutsHelp.autoReportShortcutUsed(activity, activity.intent) } } -} \ No newline at end of file +} diff --git a/core/shortcut/src/main/java/com/dede/android_eggs/views/main/util/EasterEggShortcutsHelp.kt b/core/shortcut/src/main/java/com/dede/android_eggs/views/main/util/EasterEggShortcutsHelp.kt index 622f6d6a..d2b97dc7 100644 --- a/core/shortcut/src/main/java/com/dede/android_eggs/views/main/util/EasterEggShortcutsHelp.kt +++ b/core/shortcut/src/main/java/com/dede/android_eggs/views/main/util/EasterEggShortcutsHelp.kt @@ -135,7 +135,7 @@ object EasterEggShortcutsHelp { ShortcutManagerCompat.requestPinShortcut(context, shortcut, callback) } - fun reportShortcutUsed(context: Context, intent: Intent) { + fun autoReportShortcutUsed(context: Context, intent: Intent) { val shortcutId = intent.getStringExtra(EXTRA_SHORTCUT_ID) ?: return ShortcutManagerCompat.reportShortcutUsed(context, shortcutId) }