在 React Native 应用程序中禁用屏幕捕获/屏幕截图

新手上路,请多包涵

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

原文由 Abhirup Mukherjee 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 820
2 个回答

安卓

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

您可以添加以下行。通过 setFlag FLAG_SECURE 防止截屏,代码如下:

 import android.os.Bundle;
import android.view.WindowManager;

...

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

稍后当你想删除安全标志时

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);

iOS

AppDelegate.m 覆盖屏幕,以这个例子:

 - (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];
    }];
}

原文由 griffins 发布,翻译遵循 CC BY-SA 4.0 许可协议

因此,在 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];

  1. 由于 RN 允许与本机模块通信,我决定添加网桥,以便在 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 */

.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

  1. 在 AppDelegate 中导入 #import "ScreenCaptureNotification.h" 并添加以下方法。
 - (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];
      }
    }
}

并在 [[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 })
>     })
>   }
>
> ```

和

render() { if (this.state.screenCapture) { //Show spinner return } return ( ) }

”`

我愿意接受对这篇文章进行更改的建议。如果这篇文章对你有帮助,别忘了点赞。

原文由 Naren 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题