Android 13 最近任务为何显示 App content hidden?
结论
“App content hidden”不表示 App 被锁定,也不是 Android 13 出了故障。它的意思是,这个任务在最近任务界面中的缩略图被 App 主动设为不可显示。
支付、银行、密码管理器等 App 通常会设置 WindowManager.LayoutParams.FLAG_SECURE,或在 Android 13 及以上版本调用 Activity.setRecentsScreenshotEnabled(false),防止系统将敏感页面保存为最近任务预览。系统或厂商桌面检测到这项限制后,会用白色占位页、闭眼图标或”App content hidden”替代真实内容。
这与 App 当前是否要求解锁没有必然关系。只要对应的 Activity 或窗口仍启用了隐私保护,最近任务预览就会保持隐藏。
具体作用
Android 的最近任务界面不会实时显示每个 App。Activity 进入后台时,系统通常会生成一张任务快照(Task Snapshot),交给 Launcher 或 System UI 显示。
这张快照可能包含敏感信息,例如:
- 银行余额、银行卡号和交易记录
- 支付二维码或付款码
- 身份证件、手机号等个人信息
- 登录凭据、验证码
- App 退到后台前显示的敏感页面
即使 App 本身已经加锁,旁人仍有可能看到此前生成的最近任务缩略图。因此,这类保护通常作用于窗口或 Activity,而不是取决于”App 是否已锁定”。
常见实现方式
使用 FLAG_SECURE
这是最常见且兼容范围较广的实现:
import android.os.Bundle
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
class PaymentActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.addFlags(
WindowManager.LayoutParams.FLAG_SECURE
)
setContentView(R.layout.activity_payment)
}
}
FLAG_SECURE 的保护范围比较广,通常可以:
- 阻止普通屏幕截图
- 阻止系统录屏捕获该窗口
- 防止窗口内容显示在不安全的外部显示设备上
- 让最近任务无法使用正常的页面快照
不同 Android 版本和厂商系统采用的占位样式并不一致。有的显示纯色画面,有的显示 App 图标,还有的显示”App content hidden”。这些都是系统界面的表现形式,并非 App 自己绘制的标准提示。
如果需要恢复正常捕获,可以移除该标志:
window.clearFlags(
WindowManager.LayoutParams.FLAG_SECURE
)
对于支付页面,不建议只是为了显示最近任务缩略图而移除它。
仅关闭最近任务截图
Android 13(API 33)为 Activity 提供了更有针对性的控制方式:
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class PaymentActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
setRecentsScreenshotEnabled(false)
}
setContentView(R.layout.activity_payment)
}
}
这种方式用于阻止该 Activity 的截图出现在最近任务预览中,但不能完全替代 FLAG_SECURE。如果还要阻止用户截图、录屏或将内容显示在不安全的设备上,仍应使用 FLAG_SECURE。
也可以根据系统版本组合处理:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
setRecentsScreenshotEnabled(false)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
不过,这段代码会在旧版本上同时禁止普通截图。如果需求只是隐藏最近任务预览,就要考虑这种行为差异,不能直接将两个 API 视为等价实现。
如何排查
App 开发者可以按以下顺序检查:
- 搜索代码中是否设置了
FLAG_SECURE:
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
- 检查公共基类、支付 SDK 或安全 SDK 是否自动设置了该标志。
- 检查 Android 13 的代码路径是否调用了:
setRecentsScreenshotEnabled(false)
- 确认该标志是否在某个敏感页面设置后一直没有清除。
- 分别测试普通页面、支付页面,以及 App 从后台返回后的行为。
如果只需要保护特定页面,可以在进入和离开页面时设置与清除:
override fun onStart() {
super.onStart()
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
override fun onStop() {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
super.onStop()
}
是否应该在 onStop() 中清除,要根据业务的安全要求决定。清除时机不合适,系统可能在 Activity 切换期间捕获敏感内容,所以支付类 App 通常会选择继续保持保护状态。
普通用户能否关闭
通常不能通过 Android 系统设置强制关闭。这项限制由 App 的安全策略决定,系统只负责执行限制并显示占位内容。
如果 App 提供了”允许截图”或”在最近任务中显示内容”之类的开关,用户可以在 App 设置中调整。没有这类选项时,只能由开发者修改实现。通过 Root、修改系统或绕过安全标志并非常规解决办法,而且会削弱对支付信息的保护。
注意事项
- “App content hidden”不表示 App 已被锁定,也不表示后台进程已经终止。
- 它通常只会隐藏最近任务缩略图,不会清除 Activity 数据或退出登录。
- 占位文字和图标可能来自原生系统,也可能由手机厂商的 Launcher 或 System UI 定制。
FLAG_SECURE可以降低意外泄露风险,但不能替代登录鉴权、数据加密和支付风控。- 如果只有某一品牌的手机显示这段文字,而其他设备只显示空白缩略图,通常只是界面实现不同,不代表底层安全机制存在差异。
备注:内容仅供参考。
