在React Native App中禁用Screen Capture / ScreenShot

Abh*_*jee 3 android screenshot ios reactjs react-native

我遇到过几种专门针对ios和Android的解决方案,以防止屏幕捕获和截屏。但是如何在React Native中禁用屏幕捕获?

G g*_*ffo 6

在Android中

/android/app/src/main/java/com/{Project_Name}/MainActivity.java

写一些导入声明

import android.os.Bundle;
import android.view.WindowManager;
Run Code Online (Sandbox Code Playgroud)

通过setFlag安全地使用MainActivity类中的以下代码来防止捕获屏幕

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }
Run Code Online (Sandbox Code Playgroud)

如果要删除标志安全

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
Run Code Online (Sandbox Code Playgroud)

的iOS

//通过在appDelegate.m中添加2个来覆盖屏幕

   - (void)applicationWillResignActive:(UIApplication *)application {

// fill screen with our own colour
UIView *colourView = [[UIView alloc]initWithFrame:self.window.frame];
colourView.backgroundColor = [UIColor whiteColor];
colourView.tag = 1234;
colourView.alpha = 0;
[self.window addSubview:colourView];
[self.window bringSubviewToFront:colourView];

// fade in the view
[UIView animateWithDuration:0.5 animations:^{
  colourView.alpha = 1;
}];
}

- (void)applicationDidBecomeActive:(UIApplication \*)application {
// grab a reference to our coloured view
UIView \*colourView = [self.window viewWithTag:1234];
// fade away colour view from main view
[UIView animateWithDuration:0.5 animations:^{
colourView.alpha = 0;
} completion:^(BOOL finished) {
// remove when finished fading
[colourView removeFromSuperview];
}];
}
Run Code Online (Sandbox Code Playgroud)

  • 您能解释一下 iOS 解决方案的作用吗?在我的应用程序上,它只会使应用程序淡入白屏,使应用程序从后台“无法屏幕截图”,但您仍然可以在应用程序内进行屏幕截图 (2认同)

Nar*_*ren 6

所以在 React Native 平台上 iOS 端构建的工作很少。所以请耐心阅读以下方法。

我正在使用 react-native-video 包来播放媒体。如果用户启用了屏幕录制,我的要求是显示微调器。

  1. https://developer.apple.com/documentation/uikit/uiscreen/2921651-captured?language=objc我了解到该captured属性设置为 YES。我在 AppDelegate.m 中的didFinishLaunchingWithOptions方法下添加了观察者。

    [[UIScreen mainScreen] addObserver:self forKeyPath:@"captured" options:NSKeyValueObservingOptionNew context:nil];

  2. 由于 RN 允许与 Native 模块通信,我决定添加桥接器,以便在capture标志设置为 YES时通知。

我创建了两个文件 ScreenRecordingNotification.h 和 .m

。H

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#ifndef ScreenCaptureNotification_h
#define ScreenCaptureNotification_h


@interface ScreenCaptureNotification : RCTEventEmitter <RCTBridgeModule>
-(void) isScreenCaptureEnabled:(BOOL)isCaptured;
@end

#endif /* ScreenCaptureNotification_h */
Run Code Online (Sandbox Code Playgroud)

.m 看起来像

#import <Foundation/Foundation.h>
#import "ScreenCaptureNotification.h"
#import <React/RCTLog.h>
@implementation ScreenCaptureNotification

+ (id)allocWithZone:(NSZone *)zone {
  static ScreenCaptureNotification *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents {
  return @[           
           @"isScreenCaptureEnabled"];
}

-(void) isScreenCaptureEnabled:(BOOL)isCaptured {
  [self sendEventWithName:@"isScreenCaptureEnabled" body:@{@"value": @(isCaptured)}];
}

@end
Run Code Online (Sandbox Code Playgroud)
  1. #import "ScreenCaptureNotification.h"在 AppDelegate 中导入并添加以下方法。

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([keyPath isEqualToString:@"captured"]){
          NSLog(@"Screen Capture is Enabled");
          RCTLog(@"Screen Capture is Enabled");
          if (@available(iOS 11.0, *)) {
            ScreenCaptureNotification *manager = [ScreenCaptureNotification allocWithZone: nil];
            [manager isScreenCaptureEnabled:UIScreen.mainScreen.isCaptured];
          }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

并且还添加[[UIScreen mainScreen] addObserver:self forKeyPath:@"captured" options:NSKeyValueObservingOptionNew context:nil];didFinishLaunchingWithOptions. iOS 端的更改到此结束。

  1. 现在您需要在 .js 文件中添加 Listener 以通知 iOS 发送。收到通知后,由您决定如何处理。大致如下所示。
  addListener() {  
    let bridge = new NativeEventEmitter(NativeModules.ScreenCaptureNotification);

    this.screenCaptureEnabled = bridge.addListener("isScreenCaptureEnabled",res => { 
      this.setState({ screenCapture: true })
    })
  }
Run Code Online (Sandbox Code Playgroud)

render() {
  if (this.state.screenCapture) {
     //Show spinner
     return <Spinner />
  }
  return (
  <Vido uri ... /> 
  )
}
Run Code Online (Sandbox Code Playgroud)

我愿意接受对这篇文章进行更改的建议。如果这篇文章对您有帮助,请不要忘记点赞。


Mas*_*sum 5

防止捕获屏幕

安卓

通过 setFlag secure 防止捕获屏幕

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
Run Code Online (Sandbox Code Playgroud)

如果要删除标志安全

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
Run Code Online (Sandbox Code Playgroud)

  • 你至少可以提到我们应该把那行代码放在哪里。 (3认同)
  • 这个答案不够清楚,您没有说明我们应该在何处插入该行代码! (3认同)
  • 感谢回复。IOS呢? (2认同)
  • @BurimSyla 看看我的答案,以获取应该放置该行代码的确切位置。 (2认同)

Dha*_*nav 5

在安卓中

/android/app/src/main/java/com/{Project_Name}/MainActivity.java

写一些进口声明

import android.os.Bundle;
import android.view.WindowManager;
Run Code Online (Sandbox Code Playgroud)

通过 setFlag 防止捕获屏幕 在 MainActivity 类中安全使用下面的代码

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }
Run Code Online (Sandbox Code Playgroud)