如何定义android compose屏保程序

当设备息屏的时候,如何有定义的DreamService的程序,则会启动屏保程序,现在通过compose写一个简单的屏幕保护程序:

定义屏保服务

<service
            android:name=".ComposeDreamService"
            android:exported="true"
            android:icon="@drawable/ic_launcher_foreground"
            android:label="ComposeDreamService"
            android:permission="android.permission.BIND_DREAM_SERVICE">
            <intent-filter>
                <action android:name="android.service.dreams.DreamService" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

定义 DreamService

class ComposeDreamService : DreamService(),LifecycleOwner, ViewModelStoreOwner ,
    SavedStateRegistryOwner {

    private val lifecycleRegistry = LifecycleRegistry(this)
    private val mViewModelStore = ViewModelStore()
    private val mSavedStateRegistryController = SavedStateRegistryController.create(this)

    override val lifecycle: Lifecycle
        get() = lifecycleRegistry

    override val viewModelStore: ViewModelStore
        get() = mViewModelStore

    override val savedStateRegistry: SavedStateRegistry
        get() = mSavedStateRegistryController.savedStateRegistry


    override fun onCreate() {
        super.onCreate()
        mSavedStateRegistryController.performAttach()
        mSavedStateRegistryController.performRestore(null)
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }


    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
        // 允许交互(如果需要)
        isInteractive = true

        // 防止屏幕变暗
        isFullscreen = true

        // 创建 ComposeView
        val composeView = ComposeView(this).apply {
            setViewTreeLifecycleOwner(this@ComposeDreamService)
            setViewTreeViewModelStoreOwner(this@ComposeDreamService)
            setViewTreeSavedStateRegistryOwner(this@ComposeDreamService) // 👈 必须加这个!
            setContent {
                ScreenSaverContent()
            }
        }
        setContentView(composeView)
    }
    override fun onDreamingStopped() {
        super.onDreamingStopped()
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
        viewModelStore.clear()
    }

}

漂浮时钟


@Composable
fun ScreenSaverContent() {
    var currentTime by remember { mutableStateOf(System.currentTimeMillis()) }

    // 定时更新时间
    LaunchedEffect(Unit) {
        while (true) {
            delay(1000)
            currentTime = System.currentTimeMillis()
        }
    }

    BoxWithConstraints(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Black)
    ) {
        val maxWidthPx = with(LocalDensity.current) { maxWidth.toPx() }
        val maxHeightPx = with(LocalDensity.current) { maxHeight.toPx() }

        // 当前目标偏移量
        val offsetX = remember { Animatable(0f) }
        val offsetY = remember { Animatable(0f) }

        // 定期随机移动位置
        LaunchedEffect(Unit) {
            val random = Random(System.currentTimeMillis())
            while (true) {
                // 随机新位置(边缘预留100px避免被裁剪)
                val newX = random.nextFloat() * (maxWidthPx - 200f) + 100f
                val newY = random.nextFloat() * (maxHeightPx - 200f) + 100f

                // 动画移动过去
                coroutineScope {
                    launch {
                        offsetX.animateTo(newX, animationSpec = tween(4000, easing = LinearEasing))
                    }
                    launch {
                        offsetY.animateTo(newY, animationSpec = tween(4000, easing = LinearEasing))
                    }
                }

                // 每10秒换一次位置
                delay(10_000)
            }
        }

        // 绘制时钟
        Text(
            text = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(currentTime),
            color = Color.White,
            fontSize = 48.sp,
            fontWeight = FontWeight.Bold,
            modifier = Modifier
                .offset { IntOffset(offsetX.value.toInt(), offsetY.value.toInt()) }
        )
    }
}

完整代码 https://gitee.com/lynn8570/screen-saver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值