Closed buekera closed 2 years ago
@buekera That is happening because of how react native sees/defines background and foreground states. React native uses your app activity as the owner of the UI thread. When something is in front of your app (alerts, dialogs, file pickers, etc.) onPause callback will be called and trigger "background" event.
That false report happens really fast, what you could do is to measure time between background/foreground and to ignore those false reports. But to measure it in background you need this package since when react native app goes to background state it is paused and code will not execute until you are back in the app again, so measuring is not possible without running some code in background. For example setTimeout or setInterval.
Package for running background code: https://github.com/ocetnik/react-native-background-timer
I've already recently reported this to react-native community repo and it was already reported couple years ago, I think in 2018 but old report was closed due to inactivity.
You can see they are not interested in this issue: https://github.com/facebook/react-native/issues/32036 https://github.com/react-native-community/discussions-and-proposals/issues/399
@buekera might relate to #438 please try the latest v3.10.1
. Thanks!
I "fixed" it by measuring how long "background" state was on until "active" state was back on.
If it's less than 1 second, I assume it's from nfc reading.
I had to use reference variables because my state variable was not updated in my callback function in AppState.addEventListener("change", onChangeState)
.
const blockTsRef = useRef<number>(null);
const onChangeState = (newState) => {
setCurrAppState(newState);
if(newState === "background") {
// set timestamp
blockTsRef.current = new Date().getTime();
}
else if(newState === "active") {
if(typeof blockTsRef.current === "number") {
const tsNow = new Date().getTime();
// calculate difference
if(tsNow - blockTsRef.current <= 1000) {
// reset blockTsRef
blockTsRef.current = null;
// don't do
return;
}
}
// do
}
};
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
This issue was closed because it has been stalled for 5 days with no activity.
I fixed it similarly to the solution provided above but just set the difference to 500 ms because it usually takes 20-40 ms if its the NFC triggering the state changes and it works for me.
const appState = useRef(AppState.current);
const [lastBackgroundTime, setLastBackgroundTime] = useState(null);
useEffect(() => {
const handleAppStateChange = nextAppState => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === ‘active’
) {
const currentTime = new Date().getTime();
if (lastBackgroundTime && currentTime - lastBackgroundTime > 500) {
// App was in background
} else {
// App state falsely triggered by NFC
return;
}
}
if (nextAppState === ‘background’) {
setLastBackgroundTime(new Date().getTime());
}
appState.current = nextAppState;
};
// Subscribe to app state changes
const appStateSubscription = AppState.addEventListener(
‘change’,
handleAppStateChange,
);
return () => {
// Clean up the subscription on unmount
appStateSubscription.remove();
};
}, [lastBackgroundTime]);
On Android, the background
state means that the React Native Activity is in background, and not necessary the entire app.
To handle this, I created a package that implements the Android Lifecycle API for React Native: https://github.com/douglasjunior/react-native-applifecycle
Why Use This?
The original AppState API provided by React Native behaves differently between Android and iOS, particularly regarding the background state:
- On iOS, the
background
state signifies that the entire app is in the background.- On Android, the
background
state indicates that the React Native Activity is in the background, which might not necessarily mean the entire app is in the background.By using
react-native-applifecycle
, you can handle these differences seamlessly across both platforms, ensuring that the statebackground
will be dispatched only when the entire app is in background.
Hey there, I just noticed some odd behavior while scanning nfc chips. The moment you put your nfc chip to the phone and the scanner detects it the AppState changes from
active
tobackground
back toactive
again.Due to this behavior some other parts which listen to the AppStage change behave strangely. Is there any way to work around this or might this even be a bug?
OS: Android tested nfc manager versions: 3.7.0 - 3.10.0
Code:
So when putting a nfc chip to the scanner the following logs within a split second:
Regards