Websocket disconnecting when app is on background (REACT NATIVE) - 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

Related

Android sometimes restarts my React Native application in the background

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.

React native callkeep incoming call expiration time

I'm using callkeep to show an incoming call screen when a VoIP push notification is triggered. What I want to accomplish, is to ring the user for just 20 seconds. In case the user never answers, the incoming call screen should just disappear. How can I do that with callkeep?
Should it be modified in the javascript code or in the AppDelegate?
There's a solution, which is done on front end part.
First of all, run
npm i react-native-background-timer
This will help you run scheduled tasks when the app is closed.
Then, you will need to add the listener:
RNCallKeep.addEventListener("didDisplayIncomingCall", onIncomingCallDisplayed);
Which is fired when call is displayed.
And then implement it like this:
const onIncomingCallDisplayed = ({callUUID, handle, fromPushKit, payload,}) => {
BackgroundTimer.setTimeout(() => {
RNCallKeep.endAllCalls();
}, 120000);
};
Where 120000 is time in milliseconds when you want to end the call.
You could also add a backend request to notify your server that the call is rejected.

For an unejected expo app, how to do location tracking in background (periodically if location changes frequently) to prevent app from being killed?

For an expo app that is not ejected and runs in the background, my goal is to do a location tracking periodically or when location changes.
I am sticking with Expo's base APIs including its Location, TaskManager API.
Location tracking only works for a first couple of times before it completely stops.
Following what was written in the Documentation here: https://docs.expo.io/versions/v32.0.0/sdk/location/, I was able to make an app that tracks location with the API: Location.startLocationUpdatesAsync of Expo. I had also defined a "Expo.TaskManager" and this should log a new location every time a new location is detected.
However, if the app runs in the background for more than a few seconds, geolocation service tracking no longer works. No further logging will not be written in the console.
Define Task:
TaskManager.defineTask(PUSH_LOCATION_IN_BACKGROUND, ({ data, error }) => {
if (error) {
return;
}
if (data) {
const { locations } = data;
console.log('locations are ', locations)
}
});
Start (register) the task:
await Location.startLocationUpdatesAsync('PUSH_LOCATION_IN_BACKGROUND', {
accuracy: Location.Accuracy.Balanced,
distanceInterval:3,
});
I expect that every time I change the location of my device (by either moving to a new location of faking my GPS data), I would receive a logging of the new location if the app runs in the background. However, as soon as the app enters the background, it only logs the data for a couple of times before it completely stops.
I would expect that the app will run stably in the background and if possible, avoid being killed by the OS even if the resource consumption in the device is already high.
And as someone who is not experienced in Android developemnt, do I need to set up an undismissable (user cannot dismiss it nor remove it by clicking on it) notification in order to keep the background task of the app alive? Can I do it with an unejected Expo app.

Is there any way to intercept reloading event for Android?

When I am running my application on Android device (virtual device) It connects using WebSocket. It's normal flow and there is no question here. When I am using the virtual device for developing I use "Reload" all the time (sure). Can I intercept the reloading process for disconnecting the WS connect? If I do not it manually that my backend won't get relevant event.
You can try to emit the disconnect message in the componentWillUnmount() function. It is bad to use it in a normal app flow (in a back button for example) as it is normally an async function and it is not a good approach to call async functions in the componentWillUnmount(), but in cases that you will only handle the "quit" (reload in your case) I think that this solution can help.

Tizen Web : How to get a call back regarding which application is launched

I am developing an App Lock app. Here whenever an application is launched by user
i want a callback in my app regarding which app is launched. Based on some predefined settings i want to show lock screen.
I don't know which API i should use. Whats the in "TI ZEN" using which i can
monitor the app launch.Basically i need to know which application is in foreground.
Using the existing API i have a list of applications installed but need to monitor them.
function onError(err) {
console.log('Error occurred : ' + err.message);
}
function onsuccess(applications) {
var appInfo;
for (var i = 0; i < applications.length; i++) {
appInfo = applications[i];
console.log('Application ID: ' + appInfo.id);
console.log('Icon Path: ' + appInfo.iconPath);
console.log('Name: ' + appInfo.name);
console.log('Version: ' + appInfo.version);
console.log('Show: ' + appInfo.show);
}
}
tizen.application.getAppsInfo(onsuccess, onError);
My Answer is a bit late, but in case you still need it -
Native API
I cant tell what version of Tizen you are using, but for Tizen 3.0, you can get callbacks for whenever an app in launched using the Application Manager API (native API).
Specifically, the function app_manager_set_app_context_event_cb will give you callbacks for when an app is launched or terminated.
Web API
Currently the Javascript API does not have the corresponding function.
Ideally, you need to create a hybrid application and call the above mentioned native API - its not too difficult.
If, however, you want to stick to JavaScript, you can keep calling the function tizen.application.getAppsContext() to monitor which apps are currently running. You won't get a callback when an app launches, but you can poll the above method once every half second to check the currently running apps and kill the appp if you want it locked.
Note that polling too often might affect device performance.
You have to use Tizen Background Service application as your app have to always check which app is coming to foreground.
And for detecting app launching, you may use Tizen App Control API.