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

使用Kotlin开发闹钟APP如何实现全局弹出局部悬浮小窗口?

实现方案说明

先明确你的核心疑问:

  • 不能直接启动Fragment:Fragment必须依附于宿主Activity存在,无法脱离Activity单独触发
  • 推荐通过AlarmManager先触发广播,再跳转专用的悬浮Activity实现,稳定性更高
  • 小窗口样式通过自定义Activity主题即可实现,不需要做全屏适配

1. 前置权限配置

在AndroidManifest.xml中添加所需权限:

<!-- 悬浮窗权限,用于在其他应用上层显示窗口 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- Android 12+ 精确闹钟权限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!-- 可选:重启后保留闹钟设置 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

注意:Android 6.0以上需要提前引导用户手动开启悬浮窗权限,否则窗口无法弹出

2. AlarmManager定时触发逻辑

不要直接用AlarmManager启动Activity,建议先触发广播接收器,做权限、状态校验后再跳转,避免崩溃:

// 构造触发闹钟的广播PendingIntent
val alarmIntent = Intent(context, AlarmTriggerReceiver::class.java).apply {
    putExtra("alarm_id", yourAlarmId)
}
val pendingIntent = PendingIntent.getBroadcast(
    context,
    yourAlarmId,
    alarmIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
// 设置精确闹钟,低电模式也能触发
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setExactAndAllowWhileIdle(
    AlarmManager.RTC_WAKEUP,
    triggerTimeInMillis,
    pendingIntent
)

3. 自定义悬浮小窗口Activity主题

在res/values/styles.xml中添加专属主题,实现非全屏透明效果:

<style name="AlarmPopupTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowCloseOnTouchOutside">false</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:backgroundDimAmount">0.3</item>
</style>

在Manifest中注册Activity时应用该主题,同时添加锁屏显示属性:

<activity
    android:name=".AlarmPopupActivity"
    android:theme="@style/AlarmPopupTheme"
    android:showOnLockScreen="true"
    android:turnScreenOn="true"
    android:excludeFromRecents="true"
    android:exported="false" />

4. Activity适配逻辑

在Activity的onCreate方法中添加适配代码,保证锁屏、息屏状态也能弹出:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_alarm_popup)
    
    // 适配锁屏、亮屏
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true)
        setTurnScreenOn(true)
    } else {
        window.addFlags(
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
        )
    }

    // 窗口大小调整,按你的需求设置宽高即可
    window.attributes = window.attributes.apply {
        width = (resources.displayMetrics.widthPixels * 0.85).toInt()
        height = WindowManager.LayoutParams.WRAP_CONTENT
    }

    // 后续添加停止、贪睡等按钮逻辑即可
}

可选替代方案

如果需要实现更自由的悬浮效果(比如可拖拽),也可以直接通过WindowManager.addView()的方式直接添加全局悬浮View,无需启动Activity,但需要处理更多触摸、权限适配逻辑,复杂度更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:39:02