Android sometimes restarts my React Native application in the background - react-native

I am creating a fitness application in react-native 0.66.1. To manage my pages, I use react-navigation 6.
My cover page, HomeScreen, allows to load user data before actually entering the application :
import { useFocusEffect } from '#react-navigation/native'
const HomeScreen = ({ navigation }) => {
useFocusEffect(
useCallback(() => {
// load user data and app configuration in context
navigation.navigate('AppScreen')
}, [])
)
return (
<View>
<ActivityIndicator />
<Image ... logo />
</View>
)
}
On one of my pages (StartGymScreen), I have a countdown using the react-native library react-native-countdown-circle-timer.
Everything works fine but sometimes when I put the app in the background and come back to it, it fully recharges via HomeScreen. My countdown is therefore lost (I have to come back to StartGymScreen and restart it).
I think (but I'm not sure) that this is a normal situation and that "Android" sometimes turns off apps to conserve battery power.
But I have a few questions :
I did not find anything on the react-native documentation, what explains this ?
Is it possible to prevent this? Sometimes the application restarts after 1 minute of background. Sometimes 2, sometimes 3 ... it's very random.
I sometimes use another fitness app (Hercules) which also has a countdown timer but not this problem, how does it do ?

As you said, this is normal behavior and not related to your application. The android os will handle these jobs for your applications.
There are some settings in the phone to limit your application from running in the background. But it's not the ideal way to manage this issue.
All your needs are to keep running your application in the background.
So, there are some solutions like using headless Js. read more on RN documentation. You can create an unstoppable service for your application. You can use this article to do it.
Also, there is a solution with using react-native-background-actions package.

Related

Using State For React Native Navigation

I am fairly new to React Native and I am building an app that will be using navigation. I have a solution for navigating screens that seems to work just fine however I do not see many people using this approach. I am using state in a navigation component to render a specific screen(or component).
The main solution(the documented solution) I see is using this package
#react-navigation/native #react-navigation/native-stack
My current solution works like this:
const [screen, setScreen] = useState(0)
const returnScreen = () => {
switch (screen) {
case 0:
return <AccountScreen/>
}
}
When you click a menu icon, it would change the state to say 1, and render a different screen.
Can someone help me understand why this is a bad approach or an uncommon approach(if it is)? My app will only have 5-7 screens, I am mainly looking to understand why the library is the community approach and if I am missing something.
If you wanted the ability to navigate to other screens to exist outside your menu/drawer you will have to either prop drill your setScreen function or create a context to make it accessible to other components. While this isnt hard to do, it is something that all #react-navigation navigators do without requiring additional code.
If you wanted to enable going to the previous screen, your current navigation code becomes obsolete. Just returning a screen is no longer enough, as you need to track and modify navigation history. So you write more code that you have to test and debug (keep in mind that #react-navigation/stack already does this).
If you are certain that your app will remain small and your navigation features wont increase too much then your approach is completely fine. But if your app will increase in size then you probably will find yourself implementing, testing, and debugging features that have already been implemented, tested, and debugged by the #react-navigation community

Uber H3 geoToH3 is not working in React Native

I am developing simple grid location based application in React Native using Uber H3. I installed H3 by
npm install h3-js. Then
I created a file to read H3Index from latitude and longitude.
import {geoToH3} from 'h3-js';
const getH3Index = () => {
const result = geoToH3(37.3615593, -122.0553238, 7);
console.log(result);
};
When I start to run my React Native application, app hangs on white screen(splash screen) and blocks the whole application. If I comment these lines, app works fine. If uncomment this line, both iOS and Android app is not working.
Any help would be much appreciated!
Please see https://github.com/uber/h3-js/issues/35
This is likely due to a document is not defined error. See the issue thread for several possible workarounds, including this fork which is intended for React Native.

Websocket disconnecting when app is on background (REACT NATIVE)

Im doing an "Uber like" app, and using a websocket to keep an eye on the driver (to get his location). Within 1~10 minutes (it varies) and on background, the connection dies, i'm guessing it's not the websocket, the onclose event doesn't even return anything. It's like something is force closing the app or something alike. Anyone has any clue on what is happening? I'm using Expo.
The websocket function is this one: (i'm using reconnecting-websocket)
connect = () => {
var URL = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXxx';
var token = 'XXXXXXXXXXXXXXXXXXXXXXX';
var ws = new ReconnectingWebSocket(URL,token, { debug: true, reconnectInterval: 3000 });
ws.onopen = () => {
console.log('Entered!');
}
ws.onclose = () => {
console.log('Left!')
}
}
The "Entered!" is printed, the "Left!" isn't.
Operating system is killing your app after some period in the background. You can use Headless JS (Android only) to run some background tasks periodically (can't keep websocket connection active though) or things like react-native-background-task or react-native-background-fetch that work on both iOS and Android but are not able to run tasks more frequently than once per 15 minutes. To my knowledge, the only way to achieve what you want is to write separate native modules for Android and iOS suited for your needs (and that's still not guaranteed to work, as operating systems nowadays are eager to kill any battery draining background apps). Consider enforcing foreground mode for your app

React Native Linking vs. React Native Navigation

I have a use case in which the user should be able to click on a slider that has its data served from server.
The data contains some information that would be used to:
Open another view and initialize it with some parameters.
Open external app(s) and send data to it.
Can I use the Linking api in react to make it navigate internally within the app or is that reserved only for react navigation? My intuition is to use something like this:
Linking.canOpenURL(retrievedDate).then(supported => {
if (!supported) {
// use react navigation
} else {
Linking.openURL(retrievedData);
}
}).catch(err => console.error('An error occurred', err));
But I'm not sure if that's going to be the best practice/most generic one?
Your suggestions are highly appreciated.
Linking means you are online and running a web application.
React-Native is for developing (with React type coding) MOBILE apps. A mobile app is not running in a browser and its pages are not linked to URLs. So you should be using the navigation, which creates a certain UI for Android devices and a different UI for IOS (Apple) devices, and allows the user (and/or the programmer) to "navigate" between the "screens".
If for some obscure reason you are developing a web app with React-Native, you can of course use the linking api. https://facebook.github.io/react-native/docs/linking

Enable haptic Feedback on react-native touchable view

I an writing a react-native app, And I noticed that while the buttons look like native buttons when clicked - they do not behave as one (At lease not like android button behave).
Clicking on android app button - make a sound and give the user an haptic Feedback.
On the sound I saw that there is github discussions and open issue, but I could not found anywhere anything about the haptic Feedback.
How can I make my view (any touchable view..) to make haptic feedback on click?
This is really important feeling in an app.
I want something like this (In android)
View view = findViewById(...)
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
This doesn't require from the app to have permission for Vibrate.
And managing haptic feedback on my own with the Vibrate api will cause users that disable this option globally to experience bad behavior
Thanks
If you are using Expo with react-native, I recommend you to use Expo haptics
After installing the library You can use it like:
<TouchableOpacity onPress = { ()=> {
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)
or
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)
or
Haptics.selectionAsync()
} } > </TouchableOpacity>
I found this component on github https://github.com/charlesvinette/react-native-haptic
I didn't try it yet, but it should help you to get the haptic feedback you want.
I also have nearly the same requirements and I ended up using this library react-native-haptic-feedback.
Keep in mind that haptic feedback is available only on some latest android devices and in iOS above iPhone 6s. Here is a simple code snippet:
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
const options = {
enableVibrateFallback: true,
ignoreAndroidSystemSettings: false
};
ReactNativeHapticFeedback.trigger("impactMedium", options);
In your case, it will work directly with the button's onPress method such as:
<TouchableOpacity onPress={()=>{ReactNativeHapticFeedback.trigger("impactMedium", options);}} />
Note: I found that the most versatile type which is supported by maximum devices is impactMedium.
You can use the built-in Vibration module facebook.github.io/react-native/docs/touchablewithoutfeedback
import { Vibration } from 'react-native';
...
<TouchableWithoutFeedback
onPressIn={() => Vibration.vibrate()}
/>
Remember to include this in your AndroidManifest
<uses-permission android:name="android.permission.VIBRATE" />
I published a project on Github which provides this functionality.
Check this repo out: react-native-haptic-view