I have a React Native application and I am reading accelerometer data each 20ms using the react-native-sensor-manager package.
I start the listener and log it into Reactotron each time it reads data, each 20ms
SensorManager.startAccelerometer(20)
DeviceEventEmitter.addListener('Accelerometer', function (data) {
console.tron.warn(data)
})
It works well if I leave the application in foreground, and even in background, but if I lock the phone it stops reading data. It also stops if I kill the app from the task manager.
How can I achieve to read data even in background?
You would have to tap into creating background processes in order to do anything of that nature.
react-native-background-task is probably the easiest way to do that...however, you will not be able to get updated data at such a fast pace as there are numerous limitations, for obvious reasons, to using background tasks.
Related
There are different ways to run tasks in the background in Android and iOS respectively. I have found What is the best way to schedule task in android? as well on stack overflow.
I am wondering which is the best way using react-native only. Would it be good enough to use setInterval or setTimeout for tasks that have to run daily or every few hours?
Would not those tasks be killed by the OS?
Any ideas or suggestions?
I will answer my own question to see if this information can be of used by anyone looking for it.
Since the different mobile OSs tend to kill background jobs, or stall them to save battery, there are few deterministic methods to schedule tasks in react native. I use a combination of the following:
Offload timers to the background, which work with the app in both fore and background https://github.com/ocetnik/react-native-background-timer (!If you use create-react-native-app you must eject it)
Use a background-fetch for iOS and HeadlessTask in Android, here is a decent library https://github.com/jamesisaac/react-native-background-task
Use geolocation updates to wake up the app and start threads https://github.com/mauron85/react-native-background-geolocation.
I guess you can follow similar strategies using bluetooth wake-ups.
Push notifications from a server to ensure deterministically that the app wakes app (except it having been killed by the OS). In iOS, ensure that you call notification.finish() to avoid being discriminated by the task handler algorithm.
For Android you can try to use AlarmManager API https://github.com/vikeri/react-native-background-job.
Beware of the dragons: your app might be closed if it abuses execution time or memory usage after a system wake up. You may have to rehydrate all listeners after the phone was left without battery. So the user still needs to interact heavily with your app.
Update:
From Android O there are very strict background execution limits. When using a HeadlessJSTask service, ensure that it is launched as a foreground service if you want it to last longer than a few seconds. It may require a notification with it. Take into account that only loading the bundle can take up to a few seconds, depending on your app and the device.
As a matter of fact there is not any sufficient way for that. but we can remark mauron85 as a way which is better then others on android but also it doesn't work perfectly on IOS. for example if app has killed by user the job would not keep working or there is not any control of job execution quantity the job fires each time device changes its position.
other components like react-native-background-fetch and react-native-background-task have the limitation of job execution period(the job repeats after each 15 minutes and there is no way to decrease this time period) and they just work on android.
it would be great if Facebook react native has some practical solution for this problem.
Is there any way to run some activity after a Windows Store app has been installed?
I'd like to get some data from a webservice (data is rarely changes), but I would not like to make the query on the first start, because it might take some time, and I don't want to ruin the user experience.
Thanks!
You can have it run on a separate background thread while concurrently running the main thread. You can allocate limited resources to this separate background thread, then have it subside on it's own.
You can do an async operation as well from your app, see link from MSDN:
http://msdn.microsoft.com/en-us/library/windows/apps/br230301.aspx#AsyncOps
My codeSHOW app loads data asynchronously when it first starts, and stores the async promise as an app level variable so anything else in the app can await it. It's not exactly what you're looking for, but if it helps, it's available at http://codeshow.codeplex.com.
I'm currently scheduling a background task which then queues a number of tile updates.
When the machine is on power, the background task will schedule the next batch of updates. I'm using a Maintenance type background task which does not run when on battery.
Most of the other types of background task types require the app to be pinned to the lock screen.
I need a background task to run periodically, to schedule the tile updates, including when on battery mode. The information being shown becomes out of date quickly, hence my requirement to frequently update the tile.
I also looked at TileUpdater.StartPeriodicUpdate tile updates but that requires a web service somewhere, my code is local in a background task.
It works as I want as a MaintenanceTask when the machine has power.
I'm pretty sure it is possible, I can see other apps updating when on battery mode, without being pinned.
How can I update tiles periodically (say every minute) regardless of being powered or on battery, from a background task?
There are a few ways an app tile can be updated on battery without the app being pinned to the lock screen. Two of the methods require a web presence: push notifications, and periodic notifications (which you mentioned). This MSDN article goes over each of the delivery methods:
http://msdn.microsoft.com/en-us/library/windows/apps/hh779721.aspx
If the content for tile notifications is not dynamic, scheduled tile notifications can be used. On each launch, an app can schedule some fixed number of tile notifications into the distant future. This MSDN article present an example app scheduling out notifications for a week in advance, and using both app launch and a timer background task to continually keep an app tile up to date:
http://msdn.microsoft.com/en-us/library/windows/apps/hh761464.aspx
I have created a web-service app and i want to populate my view controllers according to the response i fetch(via GET) in main thread. But i want to create a scheduled timer which will go and control my server, if there becomes any difference(let's say if the count of an array has changed) i will create a local notification. As far as i read from here and some google results, i cant run my app in background more then ten minutes expect from some special situations(Audio, Vo-IP, GPS).. But i need to control the server at least one per minute.. Can anyone offer some idea-or link please?
EDIT
I will not sell the app in store, just for a local area network. Let's say, from the server i will send some text messages to the users and if a new message comes, the count of messages array will increment, in this situation i will create a notification. I need to keep this 'controlling' routing alive forever, whether in foreground or background. Does GCD give such a solution do anyone have any idea?
Just simply play a mute audio file in loop in the background, OR, ping the user's location in the background. Yes, that will drain the battery a bit, but it's a simple hack for in-home applications. Just remember to enable the background types in your Info.plist!
Note: "[...] I fetch (via GET) in main thread." This is not a good approach. You should never fetch any network resources on the main thread. Why? Because your GUI, which is maintained by the main thread, will become unresponsive whenever a fetch isn't instantaneous. Any lag spike on the network results in a less than desirable user experience.
Answer: Aside from the listed special situations, you can't run background apps. The way I see it:
Don't put the app in the background. (crappy solution)
Try putting another "entity" between the app and the "server". I don't know why you "need to control the server at least one per minute" but perhaps you can delegate this "control" to another process outside the device?
.
iOS app -> some form of proxy server -> server which requires
"babysitting" every minute.
I started off on the Win8 metro app (javascript) development recently. For notifications, it is clear how the WNS notifications will be useful for creating live tiles.
However the use case for local notifications is not clear to me. I have these two questions:
is it correct to assume local notifications make sense only for apps that would run in the background e.g. when other apps are running or when the system is locked?
if the above is not true, then kindly suggest some examples of when local notifications will be useful.
regards
CGere
Local notifications are useful to update your tile on the start screen that persist after your app was closed/suspended. For example you might want to update the tile when your app closes with some context, perhaps an image from the last level of the game they were on or such.
When your app goes to the background it has a short period of time to suspend after which your app will no longer be running and thus unable o update the tile. You can however create a background task to run on an event/timer to do some work (such as update your tile).