gbumps / react-native-screenguard

A Native screenshot blocking library for React-Native developer, with background customizable after captured. Screenshot detector are also supported.
https://gbumps.github.io/react-native-screenguard/
MIT License
231 stars 28 forks source link

Just want to use it for screen protection when the app is in the background #65

Closed Unich-HieuDT closed 4 months ago

Unich-HieuDT commented 4 months ago

After declaring ScreenGuardModule.register in the root, a protection view appears. Everything works well when the app goes to the background. But the problem is I don’t want to block screenshots. How should I handle this?

gbumps commented 4 months ago

Hi @Unich-HieuDT, just want to know which one of these in your concern:

  1. Screenshot blocking activated, but unblock after the app goes to background.
  2. Just screenshot detector only
Unich-HieuDT commented 4 months ago

Hi @gbumps Thank you for your response. I want to ensure that declaring ScreenGuardModule.register does not block screenshots. I only want the screen to be protected when the app is in the background.

Yeah. The image below is all I want, I do not need to block screenshots. Simulator Screenshot - iPhone 15 Pro Max - 2024-07-09 at 17 45 49

gbumps commented 4 months ago

You can use AppState of React Native, or a custom-made React Native lib which handle and listen for this event, then register when in background state, unregister on the foreground state. You can check my example below

import React, {useRef, useState, useEffect} from 'react';
import {AppState, StyleSheet, Text, View} from 'react-native';
import ScreenGuardModule from 'react-native-screenguard';

const AppStateExample = () => {
  const [appState, setAppState] = useState(AppState.currentState);

  useEffect(() => {
    const handleAppStateChange = (nextAppState) => {
      if (nextAppState === 'inactive' || nextAppState === 'background') {
        ScreenGuardModule.register();
      } else if (nextAppState === 'active') {
        console.log('foreground');
        ScreenGuardModule.unregister();
      }
      setAppState(nextAppState);
    };

    const subscription = AppState.addEventListener('change', handleAppStateChange);

    return () => {
      subscription.remove();
    };
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Current app state is: {appState}</Text>
    </View>
  );
};

export default AppStateExample;
Unich-HieuDT commented 4 months ago

Hi @gbumps Thank you for providing a solution. It works very well on iOS, but not on Android. After ScreenGuardModule.unregister when the app goes to active, the AppState status falls into an infinite loop (see image below). Is there a way to solve this problem on Android?

Screenshot 2024-07-11 at 00 45 27
gbumps commented 4 months ago

i think with Android on this case, you can use registerWithoutEffect instead

Unich-HieuDT commented 4 months ago

Oh, thank you. It seems to be working quite well. But it goes back to the initial issue: Even though I have already unregister(), it seems like the app is still blocking screenshots. Screenshot_1720635788

gbumps commented 4 months ago

the app is still in inactive state based on the image you provide, please be more specific.

gbumps commented 4 months ago

Hi @Unich-HieuDT, I have not received the answer yet. So I'll suggest for you based on my assumption: While your app fallback to foreground, set up unregister at return of the useEffect() (unmounting a view), for completely removing the guard.

Thanks and happy hacking !

Unich-HieuDT commented 4 months ago

Hi @gbumps Thank you for your feedback. It seems like I’ve resolved all the issues.