Block screenshot in React Native for specific screen (Android)

Lakshya Munjal
VectoScalar
Published in
3 min readDec 7, 2023

Hey folks!
Today we will understand how we can disable screenshot and screen recording on specific screens in React Native (Android). There can be screens in your app which have sensitive data and we need to not allow the user to take the screenshot.
We need to write Native Modules to achieve this.

Let’s do some coding now!

  1. Move to android/app/src/main/java/com/your-app-name/
  2. Create a file PreventScreenshotModule.java or any name you want.
package com.your-app-name;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

import android.view.WindowManager;

import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;

public class PreventScreenshotModule extends ReactContextBaseJavaModule {
private static final String PREVENT_SCREENSHOT_ERROR_CODE = "PREVENT_SCREENSHOT_ERROR_CODE";
private final ReactApplicationContext reactContext;

PreventScreenshotModule(ReactApplicationContext context) {
super(context);
reactContext = context;
}

@Override
public String getName() {
return "PreventScreenshotModule";
}

@ReactMethod
public void forbid(Promise promise) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
getCurrentActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
promise.resolve("Screenshot taking locked.");
} catch(Exception e) {
promise.reject(PREVENT_SCREENSHOT_ERROR_CODE, "Forbid screenshot taking failure.");
}
}
});
}

@ReactMethod
public void allow(Promise promise) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
getCurrentActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
promise.resolve("Screenshot taking unlocked.");
} catch (Exception e) {
promise.reject(PREVENT_SCREENSHOT_ERROR_CODE, "Allow screenshot taking failure.");
}
}
});
}
}

3. Now it’s time to create PreventScreenshotPackage.java in the same directory as above android/app/src/main/java/com/your-app-name/

package com.your-app-name;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class PreventScreenshotPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new PreventScreenshotModule(reactContext));
}
}

4. Add this package to your MainApplication.java

@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new PreventScreenshotPackage());

return packages;
}

Now it’s time to access the methods defined in PreventScreenshotModule.java in your component/screen.

For accessing this, we’ll create a custom hook.

5. Navigate to src/hooks/ and create a hook with whatever name you like. I’m creating useCustomScreenshot.js

import { useEffect } from 'react';
import { NativeModules } from "react-native";
import { useNavigation } from "@react-navigation/native";

const useCustomScreenshot = () => {
const navigation = useNavigation();

const forbidScreenshot = async () => {
try {
const result = await NativeModules.PreventScreenshotModule.forbid();
console.log(result);
} catch (e) {
console.log(e);
}
};

const allowScreenshot = async () => {
try {
const result = await NativeModules.PreventScreenshotModule.allow();
console.log(result);
} catch (e) {
console.log(e);
}
};

useEffect(() => {
navigation.addListener('blur', () => {
// when user moves to some other screen 'blur' event will be triggered,
// again enable screenshot
allowScreenshot();
});
}, []);

return { allowScreenshot, forbidScreenshot };
};

export default useCustomScreenshot;

6. Now move to the screen where you need to disable the screen and use this piece of code there.

import React from "react";
import { View } from "react-native";
import { useFocusEffect } from "@react-navigation/native";

const HomeScreen = () => {
const { forbidScreenshot } = useCustomScreenshot();

useFocusEffect(
useCallback(() => {
forbidScreenshot();
}, [])
);

return (
<View style={styles.container}>
<Text>Home</Text>
</View>
);
};

Done! This is all you need to make things work.

Note: This will also record a black screen while screen recording and show a black screen when screen is shared on a call.

Happy Coding!

--

--