Android实战——系统悬浮窗踩坑记
Posted callme大帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战——系统悬浮窗踩坑记相关的知识,希望对你有一定的参考价值。
1.背景介绍
开启悬浮窗后,小窗悬浮在app内及桌面上,并保持悬浮窗页面所有状态
预览
路由介绍
功能概览(⚠️:【】标记处有坑,后面有解释和解决办法)
- splash->首页->详情页->悬浮窗页->回到桌面->点击桌面App图标->【悬浮窗页】
- splash->首页->详情页->悬浮窗页->开启悬浮窗->点击悬浮窗->悬浮窗页
- splash->首页->详情页->悬浮窗页->开启悬浮窗->回到桌面->点击悬浮窗->悬浮窗页->【返回详情页】
2.功能实现
- 在androidManifest.xml将悬浮窗页面android:launchMode=“singleInstance”
- 添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- 检查悬浮窗权限
- 点击开启,将悬浮窗页置于后台,同时添加小窗
moveTaskToBack(true)
var windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.addView(...)
- 点击小窗将浮窗页置于前台
var intent = Intent(it, FloatWindowActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
it.startActivity(intent)
- 进入悬浮窗页面关闭小窗,保留悬浮窗页面
override fun onRestart()
super.onRestart()
closeFloatWindow(this, exitFloatActivity = false)
- 点击关闭小窗, 同时将后台的悬浮窗页面finish
closeFloatWindow(this, exitFloatActivity = true)
3.踩坑级解决方案
- 功能预览中第一条,点击桌面App图标会显示详情页面,期望显示悬浮窗页
解释:
由于设置了悬浮窗页为singleInstance,所以默认打开的是路由栈A的最上面路由,而不是路由栈B的悬浮窗页面。
解决:
在悬浮窗页面监听app回到前台,如果不在小窗中,将该路由栈拉回前台
if (FloatWindowHelper.instance.dragFloatWrapper == null)
var intent = Intent(this, FloatWindowActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
startActivity(intent)
2.功能预览中第三条,悬浮窗页面点击返回会回到桌面,期望回到详情页
解释:
上一步点击悬浮窗,路由跳转到悬浮窗页面,此时启动的只有路由栈B,所以返回就直接回到桌面了
解决:
如果在桌面点击悬浮窗时,先启动app(默认路由栈A),这里有个小细节,会启动我们清单文件里设置了LAUNCHER的页面,即Splash页面,这里只需要finish掉不需要再自动跳到主页
// 先启动app,默认standard路由栈
if (isAppInBg)
context.let
val intent = it.packageManager.getLaunchIntentForPackage(it.packageName)
it.startActivity(intent)
// 告诉splash不需要跳转到主页,然后再恢复需要跳转
needJumpToMain = false
timer.schedule(object : TimerTask()
override fun run() [link](https://note.youdao.com/)
needJumpToMain = true
, 1200)
isAppInBg = false
源码已上传至github
以上是关于Android实战——系统悬浮窗踩坑记的主要内容,如果未能解决你的问题,请参考以下文章