JHHK

欢迎来到我的个人网站
行者常至 为者常成

防截屏

-参考文章1:应用权限列表
-参考文章2:如何声明权限
-参考文章3:window.getLastWindow

目录

原理

先申请权限

在下面文件中添加权限
/df-flutter/ohos/entry/src/main/module.json5

{
"name": "ohos.permission.PRIVACY_WINDOW",
"reason": "$string:get_oaid",
"usedScene": {
    "abilities": [],
    "when": "inuse"
   }
}

设置隐私模式

一、设置隐私模式

try{
    //需要获取到顶层的window
    let windowClass = xx;
    
    // 设置当前window的隐私模式
    windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => {
      const errCode: number = err.code;
      if (errCode) {
        console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err));
        return;
      }
      console.info('Succeeded in setting the window to privacy mode.');
    });
} catch(exception){
    console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
}

二、如何获取window对象

1、在Ability中获取window对象

onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.getMainWindow((err, data) => {
      // 主window对象
      // xy:注意主window和最后显示的window是不同的,如果当前只有一个window那么他们是相同的
      let windowClass = data;
    })
}

2、在组件中获取window对象

try {
  // 返回当前应用内最后显示的窗口对象,this是当前的组件
  window.getLastWindow(getContext(this), (err: BusinessError, data) => {
    const errCode: number = err.code;
    if (errCode) {
      console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err));
      return;
    }
    console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));

    // 顶层的window对象
    let windowClass = data;

  });
} catch (exception) {
  console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
}

使用

全局开启关闭

在Ability的方法回调中进行处理

onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.getMainWindow((err, data) => {
         // 主window对象
         let windowClass = data;
         isPrivacyMode = true;
         try{
            // 设置当前window的隐私模式
            windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => {
              const errCode: number = err.code;
              if (errCode) {
                console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err));
                return;
              }
              console.info('Succeeded in setting the window to privacy mode.');
            });
        } catch(exception){
            console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
        }
    })
}

在页面中单独开启关闭

封装一个方法

openPrivacyMode(isPrivacyMode: boolean) {
    try {
      // 返回当前应用内最后显示的窗口对象,this是当前的组件
      window.getLastWindow(getContext(this), (err: BusinessError, data) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err));
          return;
        }
        console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
    
        // 顶层的window对象
        let windowClass = data;
    
        // 设置当前window的隐私模式
        windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => {
          const errCode: number = err.code;
          if (errCode) {
            console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err));
            return;
          }
          console.info('Succeeded in setting the window to privacy mode.');
        });
        
      });
    } catch (exception) {
      console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
    }
}

在页面的生命周期中进行处理

// 页面显示的时候把隐私模式打开
.onShown(()=>{
  this.openPrivacyMode(getContext(this), true)
})
// 页面消失的时候把隐私模式关闭,如果不关闭,防截屏会在任何页面都开启
.onHidden(()=>{
  this.openPrivacyMode(getContext(this), false)
})

四、如果不想在每个页面都添加,可以在路由拦截中使用

在路由拦截器中处理

  public static createNavPathStack(navPathStack: NavPathStack): void {
    DfRouter.navPathStack = navPathStack;
    
    // 路由拦截回调
    navPathStack.setInterception({
      willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar", operation: NavigationOperation, animated: boolean) => {
        if (typeof to === "string") {
          console.log("target page is navigation home page.");
          return;
        }

        ShotScreenUtil.openPrivacyMode(to);
      }
    })
  }

ShotScreenUtil的初始化

onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.getMainWindow((err, data) => {
      let windowClass = data;
      ShotScreenUtil.init(data);
    })
}

封装的工具类ShotScreenUtil

export class ShotScreenUtil {
    
  //静态变量,存储Window对象
  private static windowClass : window.Window | null = null;
  
  //初始化时需要将window传递过来,并存储在变量中
  public static init(windowClass: window.Window) {
    ShotScreenUtil.windowClass = windowClass;
  }


  // 根据传递过来的参数来动态决定是否开启隐私模式(防截屏)
  public static openPrivacyMode(target: NavDestinationContext) {
  
    //观察到:页面被push或pop都会携带,打开页面时传递给页面的参数
    let pageParam = target.pathInfo.param as Map<string,object | string>;
    
    
    let isPrivacyMode = false;

    if (pageParam && pageParam.has("source")) {
      let source:string = pageParam.get("source") as string;
      let userInfo = DfGlobalContext.getContext().getObject('currentUser') as UserInfoOa;
      let screenShotInfo = userInfo.screenshotInfo;
      if (screenShotInfo && screenShotInfo.screenshot == true) {
        screenShotInfo.sources?.forEach(element => {
          if (element == source) {
            isPrivacyMode = true;
          }
        })
      }
    }

    try {
      ShotScreenUtil.windowClass?.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err));
          return;
        }
        console.info('Succeeded in setting the window to privacy mode.');
      });

    } catch (exception) {
      console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
    }
  }
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.