How to detect screenshots with React Native (both Android and iOS) - react-native

I am trying to detect if a user takes a screenshot while using a smartphone app that I have built. I am building my project with React Native.
I have been told that I can possibly prevent screenshots for Android but not for iOS. but can I still detect whether a user attempts to take a screenshot so that I can at least send a warning via Alert?
Thanks in advance
I tried react-native-screenshot-detector but it did not work

you can use this package it supports android&ios screenshot detecting react-native-detector
import {
addScreenshotListener,
removeScreenshotListener,
} from 'react-native-detector';
// ...
React.useEffect(() => {
const userDidScreenshot = () => {
console.log('User took screenshot');
};
const listener = addScreenshotListener(userDidScreenshot);
return () => {
removeScreenshotListener(listener);
};
}, []);

There is no package for it currently.

Related

OneSignal notification does not appear on iOS, but it does on Android (In App message works perfectly on both)

So I added onesignal-expo-plugin and react-native-onesignal to my project, I made everything what was wrote on the website
After this i made a developmen-simulator build for my app
I tested the app on IOS and on Android too, on android i get the notification instantly but on IOS i'm not.
So i checked the notification report on OneSignal dashboard and the ios fall into failed. I checked everything, I added everything what i had to, the p12 file is correct, I did everything multiple times before i write here,
I haven't ejected my ios app because I want to keep expo managing my ios/android application well.
What should I try to fix this issue?
Android works correctly but ios don't and I really need your help!
The in-app message works correctly just the push notification don't
Versions:
"react-native-onesignal": "^4.5.0",
"onesignal-expo-plugin": "^1.3.0",
I don't want to eject my ios code and I saw too many articles and videos how others use it and works. Please help me whats wrong.
My code example what I tried just now:
const initialOnesignal = async () => {
OneSignal.setAppId('HIDEN FOR STACKOVERFLOW');
OneSignal.promptForPushNotificationsWithUserResponse();
OneSignal.setNotificationWillShowInForegroundHandler(
notificationReceivedEvent => {
console.log(
'OneSignal: notification will show in foreground:',
notificationReceivedEvent,
);
let notification = notificationReceivedEvent.getNotification();
console.log('notification: ', notification);
const data = notification.additionalData;
console.log('additionalData: ', data);
notificationReceivedEvent.complete(notification);
},
);
OneSignal.setNotificationOpenedHandler(notification => {
console.log('OneSignal: notification opened:', notification);
});
};
And I also tried this way:
useEffect(() => {
OneSignal.setAppId('HIDEN FOR STACKOVERFLOW');
OneSignal.promptForPushNotificationsWithUserResponse(response => {
console.log('Prompt response:', response);
});
OneSignal.setNotificationWillShowInForegroundHandler(
notificationReceivedEvent => {
console.log(
'OneSignal: notification will show in foreground:',
notificationReceivedEvent,
);
let notification = notificationReceivedEvent.getNotification();
console.log('notification: ', notification);
const data = notification.additionalData;
console.log('additionalData: ', data);
// Complete with null means don't show a notification.
notificationReceivedEvent.complete(notification);
},
);
OneSignal.setNotificationOpenedHandler(notification => {
console.log('OneSignal: notification opened:', notification);
});
}, []);
Tried to only add my AppId as well. I guess i tried everyting.
I have tried to regenerate p12 file, try multiple code examples, run on simultaor and on device too.
Tried to use useEffect and simple function as well.

How can I obtain a reference to the URL that was used to open my app with a link in iOS

I have a problem with the situation where my React Native Expo app is running in the background / inactive modus and the app is brought back to the foreground / active mode as a result of the user opening a deep link to my app from the mobile browser.
When this situation occurs, my app needs to get a reference to the deep link in order to show the expected content to the user. The problem is that Linking.getInitialURL() always returns the link that was used to open the app from cold start and not the link that was used to bring the app back to foreground / active modus.
Advice on how to fix this problem would be greatly appreciated.
Found it out by myself :-)
useEffect(() => {
Linking.addEventListener('url', handleLinkEvent);
return () => {
Linking.removeEventListener('url', handleLinkEvent);
};
}, []);
For these cases you should use Linking.addEventListener
To complete #timboektoe's answer, react-navigation offers a subscribe function to listen to any URL received.
const subscribe = (listener) => {
const onReceiveURL = ({ url }) => { listener(url); };
const subscription = Linking.addEventListener('url', onReceiveURL);
return () => {
subscription.remove();
};
};
const linking = {
prefixes,
config,
getInitialURL,
subscribe,
};

How to use setTimeout in react native?

Hi I working on a react native project I need to support my app offline.
I used NetInfo Library from expo documentation.
like below
const netInfo = useNetInfo();
const networkCheck = () => {
setTimeout(() => {
const net = netInfo.isInternetReachable;
console.log(net);
if (net === false) {
setloadCachedListings(true);
}
}, 2000);
};
networkCheck();
I want to wait for some time at this step of my code because this hook always returns null first time then after few milliseconds it tells the real network status.
But this code is not working as I an trying to do.
Is there any way to achieve this?
I just want to wait a little bit to get real network connection and then go further with my code.
logs for netInfo hook.

How to force users to update the app using react native

I have updated my app on app and play store and I want to force my app users to update the new version of app in App store and playstore.
You can check for the App Store / Play Store version of your app by using this library
react-native-appstore-version-checker.
In expo app you can get the current bundle version using Constants.nativeAppVersion. docs.
Now in your root react native component, you can add an event listener to detect app state change. Every time the app transitions from background to foreground, you can run your logic to determine the current version and the latest version and prompt the user to update the app.
import { AppState } from 'react-native';
class Root extends Component {
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextState) => {
if (nextState === 'active') {
/**
Add code to check for the remote app version.
Compare it with the local version. If they differ, i.e.,
(remote version) !== (local version), then you can show a screen,
with some UI asking for the user to update. (You can probably show
a button, which on press takes the user directly to the store)
*/
}
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
}
import VersionCheck from 'react-native-version-check';
i have used version check lib for this purpose and approach i used is below. if version is lower i'm opening a modal on which an update button appears, and that button redirects to app store/google play
componentDidMount() {
this.checkAppUpdate();
}
checkAppUpdate() {
VersionCheck.needUpdate().then(res => {
if (res.isNeeded) {
setTimeout(() => {
this.setState({openModal: true});
});
}
});
}
updateApp = () => {
VersionCheck.getStoreUrl({
appID: 'com.showassist.showassist',
appName,
})
.then(url => {
Linking.canOpenURL(url)
.then(supported => {
if (!supported) {
} else {
return Linking.openURL(url);
}
})
.catch(err => console.error('An error occurred', err));
})
.catch(err => {
console.log(`error is: ${err}`);
});
};
For future readers.
If you are using Expo managed workflow, install this package react-native-version-check-expo using yarn add react-native-version-check-expo or npm install react-native-version-check-expo.
Consult the package documentation on Github for usage guidelines.
I'm using react-native-version-check-expo library to achieve this. Working fine for me.
if you are looking for an easy to integrate built in solution. You can use App Upgrade https://appupgrade.dev/ service to force update your mobile apps.
Create new version entry for your app version that you want to update in the app upgrade service and select whether you want to force it or just want to let users know that new version is available.
Integrate your app with App Upgrade using available SDK. Official SDK are available for React Native, Flutter, Expo, Android and iOS(Swift).
The SDK will take care of the rest.
Whenever you want to force upgrade a version just create a version entry in app upgrade dashboard.
You can also integrate using API. Just call the appupgrade api from your app with the required details such as your app version, platform, environment and app name.
The API will return you the details.. that this app needs to be updated or not.
Based on the response you can show popup in your app.You can call this API when app starts or periodically to check for the update. You can even provide a custom message.
API response:
See the response has force update true. So handle in the app by showing popup.
You can find the complete user documentation here. https://appupgrade.dev/docs
Thanks.

How to register a headset button event in react native?

I'm using the latest version of React Native. I'm trying to console log something whenever the headset button is clicked on Android. So far, I've been unsuccessful.
I tried the react-native-music-control. In the docs it says that
MusicControl.on('togglePlayPause', ()=>{console.log('clicked')})
should work. But I'm not sure if its only for ios or android too.
This is my componentDidMount (the render returns a 'hello' text).
componentDidMount() {
MusicControl.enableControl('play', true);
MusicControl.enableControl('pause', true);
MusicControl.enableControl('stop', true);
MusicControl.enableControl('togglePlayPause', true);
MusicControl.on('play', () => { console.log('----'); });
MusicControl.on('pause', () => { console.log('----'); });
MusicControl.on('togglePlayPause', () => { console.log('----'); });
}
'----' is logged only when I disconnect the headset and not any other time.
The official doc on github says:
MusicControl.on('togglePlayPause', ()=> {}); // iOS only
The iOS only comment states pretty clearly that this event is only available on iOS and would not trigger on Android
So, the package react-native-keyevent works really well with android. After linking the package, I had to configure it in the MainActivity.java (which I was skipping by mistake).
After I did that, it worked properly in Android.