禁止截屏/录屏
在实际的开发中,某些场景需要禁用截屏和录屏功能,比如:券码展示页面。微信小程序中提供了几个和截屏/录屏相关的 API,但是其中的大部分 API 并不是 Android 和 iOS 通用的,因此需要做区别处理。
Android
wx.setVisualEffectOnCapture
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
visualEffect | string | none | 否 | 截屏/录屏时的表现,仅支持 none / hidden,传入 hidden 则表示在截屏/录屏时隐藏屏幕 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
设置wx.setVisualEffectOnCapture
的visualEffect
参数为hidden
示例代码
wx.setVisualEffectOnCapture({
visualEffect: 'hidden',
})
- 截屏时,会提示
无法抓取屏幕截图
。 - 录屏时,无论是先开启录屏后进入小程序,还是先进入小程序后开启录屏,该方法都不会阻止录屏的动作,但是录制的结果中会隐藏屏幕(具体表现:相应的页面是黑色的)。
提示
wx.setVisualEffectOnCapture
的调用既可以放在页面的 onShow 生命周期中,也可以放在某个事件回调函数中。比如:点击优惠券查看详情
按钮,弹出带有优惠券二维码的详情弹窗时,调用wx.setVisualEffectOnCapture
方法也可以实现禁止截屏/录屏的效果。- 在页面
onHide
以及onUnload
时或者关闭券详情弹窗时,需要执行下面的代码放开截屏/录屏的限制,否则进入其他页面时也无法正常截屏/录屏。
示例代码
wx.setVisualEffectOnCapture({
visualEffect: 'hidden',
visualEffect: 'none',
})
iOS
在 iOS 中需要下面的几个 API 结合起来使用。
wx.onUserCaptureScreen
wx.onUserCaptureScreen
方法注册一个截屏的监听,在用户截屏时给出 toast 提示,比如本优惠劵仅限本人使用,转发或分享无效
。
但是wx.onUserCaptureScreen
并不能阻止截屏的行为。而且还需要在页面onHide
以及onUnload
时或者关闭券详情弹窗时,需要调用wx.offUserCaptureScreen方法取消事件监听。
wx.onScreenRecordingStateChanged
通过wx.onScreenRecordingStateChanged
监听用户录屏事件,当开始录屏时,res.state 等于start
,当结束录屏时,res.state 等于stop
示例代码
// 监听用户录屏事件
const handler = function (res) {
console.log(res.state)
}
wx.onScreenRecordingStateChanged(handler)
这样就可以在监听到用户开始录屏时做一些操作,比如:隐藏优惠券二维码。结束录屏时,再显示二维码。
在页面onHide
以及onUnload
时或者关闭券详情弹窗时,需要调用wx.offScreenRecordingStateChanged方法移除用户录屏事件的监听函数。
示例代码
// 监听用户录屏事件
const handler = function (res) {
console.log(res.state)
}
wx.onScreenRecordingStateChanged(handler)
// 取消监听用户录屏事件
wx.offScreenRecordingStateChanged(handler)
但是实际应用中还有一种场景需要处理。考虑以下场景(以打开优惠券详情弹窗为例):
当用户在打开优惠券详情弹窗之前就已经开启了录屏,这个时候wx.onScreenRecordingStateChanged
是无法监听到录屏事件的,此时需要用到下面的 API。
wx.getScreenRecordingState
该方法可以查询用户是否在录屏。当打开券详情弹窗时,调用此方法,如果 res.state 等于on
,则说明打开弹窗时用户正在录屏,此时可以将券二维码隐藏。
示例代码
wx.getScreenRecordingState({
success: function (res) {
console.log(res.state)
},
})
总结
- Android 中可以直接使用
wx.setVisualEffectOnCapture
API 达到禁用截屏/录屏的目的。 - iOS 中截屏和录屏需要分别讨论。其中
wx.onUserCaptureScreen
并不能阻止截屏行为,只能给出一个提示。因此可以有别的方案作为辅助,比如给券二维码添加一个 GIF 格式 的背景图,这样就可以根据该背景图是否变化来区分是否是截图。 - iOS 中可以使用
wx.onScreenRecordingStateChanged
监听录屏事件,根据回调函数中的res.state
来进一步处理用户开启录屏时的逻辑。 - iOS 中需要注意一个特殊场景,即先开启录屏。这个时候可以使用
wx.getScreenRecordingState
API 来查询用户是否在录屏。并处理相应的录屏时的逻辑。