You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin Multiplatform Compose中实现屏幕亮度调节并解决Android端依赖问题?

解决KMM Compose中跨平台设置屏幕亮度的问题

问题根源

shared模块的androidMain无法直接调用requireActivity(),因为该方法是Android原生Activity的扩展,shared模块没有绑定具体的Activity上下文,导致无法获取Window实例调整亮度。


方案一:全局Activity引用 + 顶层函数适配

这种方式改动最小,适合快速实现:

  1. commonMain中保持原有expect函数
expect fun setBrightness(brightness: Float)
  1. androidMain中实现actual函数,并添加Activity全局管理
import android.app.Activity

// 全局存储当前Activity引用
private var currentActivity: Activity? = null

// 供Android原生层调用,传入当前Activity
fun setCurrentActivity(activity: Activity?) {
    currentActivity = activity
}

actual fun setBrightness(brightness: Float) {
    val activity = currentActivity ?: return
    val window = activity.window
    val layoutParams = window.attributes
    // 确保亮度值在0-1的有效范围内
    layoutParams.screenBrightness = brightness.coerceIn(0f, 1f)
    window.attributes = layoutParams
}
  1. Android原生Activity中绑定上下文
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 传入当前Activity到shared模块
        setCurrentActivity(this)
        setContent {
            // 你的Compose界面
            Button(onClick = { setBrightness(1f) }) {
                Text("设置最大亮度")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 销毁时清空引用,避免内存泄漏
        setCurrentActivity(null)
    }
}
  1. iosMain中保持原有实现
import platform.UIKit.UIScreen

actual fun setBrightness(brightness: Float) {
    // 同样限制亮度值范围
    UIScreen.main.brightness = brightness.coerceIn(0f, 1f)
}

方案二:使用BrightnessManager类 + CompositionLocal(更优雅)

这种方式遵循依赖注入思想,避免全局变量,更适合复杂项目:

  1. commonMain中定义expect类
expect class BrightnessManager {
    fun setBrightness(brightness: Float)
}
  1. androidMain中实现actual类,通过构造函数接收Activity
import android.app.Activity
import android.view.WindowManager

actual class BrightnessManager(private val activity: Activity) {
    actual fun setBrightness(brightness: Float) {
        val window = activity.window
        val layoutParams = window.attributes
        layoutParams.screenBrightness = brightness.coerceIn(0f, 1f)
        window.attributes = layoutParams
    }
}

// 创建Compose的CompositionLocal,用于在界面中提供实例
val LocalBrightnessManager = compositionLocalOf<BrightnessManager> {
    error("BrightnessManager未提供,请在CompositionLocalProvider中初始化")
}
  1. Android原生Activity中提供实例
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val brightnessManager = BrightnessManager(this)
        setContent {
            // 通过CompositionLocal传递实例到Compose树中
            CompositionLocalProvider(LocalBrightnessManager provides brightnessManager) {
                BrightnessControlButton()
            }
        }
    }
}
  1. iosMain中实现actual类
import platform.UIKit.UIScreen

actual class BrightnessManager {
    actual fun setBrightness(brightness: Float) {
        UIScreen.main.brightness = brightness.coerceIn(0f, 1f)
    }
}

// iOS端同样创建CompositionLocal
val LocalBrightnessManager = compositionLocalOf<BrightnessManager> {
    // iOS端无需依赖上下文,直接创建实例
    BrightnessManager()
}
  1. Compose界面中调用
@Composable
fun BrightnessControlButton() {
    val brightnessManager = LocalBrightnessManager.current
    Button(onClick = { brightnessManager.setBrightness(1f) }) {
        Text("设置最大亮度")
    }
}

注意事项

  • 无论哪种方案,都要通过coerceIn(0f, 1f)限制亮度值,避免传入无效数值导致异常
  • Android端调整亮度后,退出App可能会恢复系统原有亮度,如果需要持久化,需额外保存系统亮度并在退出时恢复
  • iOS端在后台时无法调整亮度,需确保App处于前台状态

内容的提问来源于stack exchange,提问作者jasiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:55:44