Skip to content

禁止截屏/录屏

在实际的开发中,某些场景需要禁用截屏和录屏功能,比如:券码展示页面。微信小程序中提供了几个和截屏/录屏相关的 API,但是其中的大部分 API 并不是 Android 和 iOS 通用的,因此需要做区别处理。

Android

wx.setVisualEffectOnCapture

属性类型默认值必填说明
visualEffectstringnone截屏/录屏时的表现,仅支持 none / hidden,传入 hidden 则表示在截屏/录屏时隐藏屏幕
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行)

设置wx.setVisualEffectOnCapturevisualEffect参数为hidden

示例代码

js
wx.setVisualEffectOnCapture({
  visualEffect: 'hidden', 
})
  • 截屏时,会提示无法抓取屏幕截图
  • 录屏时,无论是先开启录屏后进入小程序,还是先进入小程序后开启录屏,该方法都不会阻止录屏的动作,但是录制的结果中会隐藏屏幕(具体表现:相应的页面是黑色的)。

提示

  1. wx.setVisualEffectOnCapture的调用既可以放在页面的 onShow 生命周期中,也可以放在某个事件回调函数中。比如:点击优惠券查看详情按钮,弹出带有优惠券二维码的详情弹窗时,调用wx.setVisualEffectOnCapture方法也可以实现禁止截屏/录屏的效果。
  2. 在页面onHide以及onUnload时或者关闭券详情弹窗时,需要执行下面的代码放开截屏/录屏的限制,否则进入其他页面时也无法正常截屏/录屏。

示例代码

js
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

示例代码

js
// 监听用户录屏事件
const handler = function (res) {
  console.log(res.state)
}
wx.onScreenRecordingStateChanged(handler)

这样就可以在监听到用户开始录屏时做一些操作,比如:隐藏优惠券二维码。结束录屏时,再显示二维码。
在页面onHide以及onUnload时或者关闭券详情弹窗时,需要调用wx.offScreenRecordingStateChanged方法移除用户录屏事件的监听函数。

示例代码

js
// 监听用户录屏事件
const handler = function (res) {
  console.log(res.state)
}
wx.onScreenRecordingStateChanged(handler)
// 取消监听用户录屏事件 
wx.offScreenRecordingStateChanged(handler) 

但是实际应用中还有一种场景需要处理。考虑以下场景(以打开优惠券详情弹窗为例):
当用户在打开优惠券详情弹窗之前就已经开启了录屏,这个时候wx.onScreenRecordingStateChanged是无法监听到录屏事件的,此时需要用到下面的 API。

wx.getScreenRecordingState

该方法可以查询用户是否在录屏。当打开券详情弹窗时,调用此方法,如果 res.state 等于on,则说明打开弹窗时用户正在录屏,此时可以将券二维码隐藏。

示例代码

js
wx.getScreenRecordingState({
  success: function (res) {
    console.log(res.state)
  },
})

总结

  1. Android 中可以直接使用wx.setVisualEffectOnCaptureAPI 达到禁用截屏/录屏的目的。
  2. iOS 中截屏和录屏需要分别讨论。其中wx.onUserCaptureScreen并不能阻止截屏行为,只能给出一个提示。因此可以有别的方案作为辅助,比如给券二维码添加一个 GIF 格式 的背景图,这样就可以根据该背景图是否变化来区分是否是截图。
  3. iOS 中可以使用wx.onScreenRecordingStateChanged监听录屏事件,根据回调函数中的res.state来进一步处理用户开启录屏时的逻辑。
  4. iOS 中需要注意一个特殊场景,即先开启录屏。这个时候可以使用wx.getScreenRecordingStateAPI 来查询用户是否在录屏。并处理相应的录屏时的逻辑。