Abhirup Mukherjee
Abhirup Mukherjee

Reputation: 499

Disable Screen Capture/ScreenShot in React Native App

I have came across few solutions specific for ios and Android to prevent screen-capturing and taking screenshots. But how do i disable screen-capturing in react native?

Upvotes: 25

Views: 44331

Answers (7)

STEPHEN bui
STEPHEN bui

Reputation: 628

You can use my own custom-made library react-native-screenguard.

yarn add react-native-screenguard

npm i --save react-native-screenguard

Guide:

https://gbumps.github.io/react-native-screenguard

Upvotes: 1

ND verma
ND verma

Reputation: 287

screen shot false in your app put this complete code in your

android/app/src/main/javacom/mainactivity/java

package com.Yourprojectname;
import com.facebook.react.ReactActivity;
import android.os.Bundle;
import android.view.WindowManager;


public class MainActivity extends ReactActivity {
  @Override
  protected String getMainComponentName() {
    return "YOUR PROJECT NAME";
  }
   
  @Override
  protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_SECURE,
    WindowManager.LayoutParams.FLAG_SECURE
  );}}

Upvotes: 0

alireza_k74
alireza_k74

Reputation: 1

  1. Add this lines in appDelegate.m below didFinishLaunchingWithOptions when user being screen record exit app and if screen record is on app not open just for ios react-native

Upvotes: 0

griffins
griffins

Reputation: 8246

Android

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

you may add the following lines. Prevent capture screen by setFlag FLAG_SECURE, use code below as an example:

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);
}

later when you want to remove secure flag

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

iOS

overlay screen in AppDelegate.m, take this example:

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

Upvotes: 41

Naren
Naren

Reputation: 1702

So there is little work for the iOS side build on React Native platform. So be patient with me to read the following approach.

I am using the react-native-video package for playing media. My requirement was to show spinner if user has screen recording enabled.

  1. From https://developer.apple.com/documentation/uikit/uiscreen/2921651-captured?language=objc I understood that captured property is set to YES. I added observer in AppDelegate.m, under didFinishLaunchingWithOptions method.

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

  2. Since RN allows communication with Native modules, I decided to add bridge so notify when capture flag is set to YES.

I created two files ScreenRecordingNotification.h and .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 */

and .m looks like

#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. import #import "ScreenCaptureNotification.h" in AppDelegate and added the following method.

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

And also add [[UIScreen mainScreen] addObserver:self forKeyPath:@"captured" options:NSKeyValueObservingOptionNew context:nil]; in didFinishLaunchingWithOptions. This concludes changes at iOS side.

  1. Now you need to add Listener in .js files for notification which iOS sending. Once you get notification, it's up to you to decide what to do with it. Roughly it will look like below.
  addListener() {  
    let bridge = new NativeEventEmitter(NativeModules.ScreenCaptureNotification);

    this.screenCaptureEnabled = bridge.addListener("isScreenCaptureEnabled",res => { 
      this.setState({ screenCapture: true })
    })
  }

and

render() {
  if (this.state.screenCapture) {
     //Show spinner
     return <Spinner />
  }
  return (
  <Vido uri ... /> 
  )
}

I am open to suggestions to make changes to this post. Don't forget to upvote if this post helped you.

Upvotes: 11

Dharmendra Vaishnav
Dharmendra Vaishnav

Reputation: 305

In android

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

write some Import Statements

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

Prevent capture screen by setFlag secure use below code inside the MainActivity class

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

Upvotes: 5

Masum Billah
Masum Billah

Reputation: 1093

Prevent Capture Screen

Android

Prevent capture screen by setFlag secure

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

If you want to remove flag secure

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

Upvotes: 5

Related Questions