- Home /
Run a script in background when the app is open or closed
Hi,
I want to run a script in background when the app is open or closed. This background script sends a request to the local server and then sends a response as a notification to the user. I can communicate the local server and send a notification but I don't know how running this script in app background. This background script should be running independently of scenes. This background script will be run in android and ios.
Please help me with my this problem.
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using Unity.Notifications.Android;
public class Notification : MonoBehaviour
{
void Start()
{
InvokeRepeating("ErrorUpdate", 0, 0.1f);
}
void ErrorUpdate()
{
StartCoroutine(GetError());
}
IEnumerator GetError()
{
string IpURL = IPClass.url + IPClass.port + "/api/data";
UnityWebRequest _www = UnityWebRequest.Get(IpURL);
yield return _www.SendWebRequest();
if (_www.error == null)
{
ErrorData(_www.downloadHandler.text);
}
}
private void ErrorData(string _url)
{
ErrorListDALClass errorDataJson = JsonUtility.FromJson<ErrorListDALClass>(_url);
foreach (var item in errorDataJson.Value)
{
if (item != null)
{
SendNotification();
break;
}
}
}
public void CreateNotificationChannel()
{
var c = new AndroidNotificationChannel()
{
Id = "channel_id",
Name = "Default Channel",
Importance = Importance.High,
Description = "Generic notifications",
};
AndroidNotificationCenter.RegisterNotificationChannel(c);
}
public void SendNotification()
{
var notification = new AndroidNotification();
notification.Title = "Robot Says";
notification.Text = "System Error";
notification.Color = Color.red;
notification.FireTime = System.DateTime.Now.AddMilliseconds(10);
AndroidNotificationCenter.SendNotification(notification, "channel_id");
}
}
Answer by Bunny83 · Mar 24, 2020 at 06:44 PM
The term "App" on mobile devices is generally reserved for foreground applications. When the app is suspended / in background it is completely halted and at will of the operating system can be completely erased from RAM when needed. So there is nothing there that can reliable continue to run.
What you are looking for is implementing a native background service. This can not be done in Unity or the Unity engine. Such a service has to be programmed natively (i.e. In Java for Android and probably xCode for iOS). You would have to dig quite deep into the APIs of the targetplatform you want to build for.
Just to make that clear: A Unity made App is a foreground application / Activity and as such only works when in foreground. Note that creating a background service is not a simple process and you have to handle all background related thing in the native code outside Unity. When Unity comes back on / is restarted you have to communicate with the background servite to transfer relevant information.
There are little examples on the web how to implement a background service on Android. This is a quite advanced topic and is nothing for beginners. You should have a good understanding of the target OS when you want to attempt this. Also watch out for common practices and guidelines from Google / Apple. Always keep usability and non-intrusive architecture in mind. While foreground applications are relatively free in what they do since the user is actively using it at that point. Background services have to take special care to not cause unnecessary battery drain, network traffic, ...
Thanks for your answer. So is there any way to run IEnumerator in a thread? Another thing I'm trying to do is to download the video when the user enters the video player screen from my application. Even if the user switches to different screens, it should continue to download.
Answer by ShadyProductions · Mar 04, 2020 at 08:38 AM
Take a look at this thread:
https://answers.unity.com/questions/357033/unity3d-and-c-coroutines-vs-threading.html
Thanks for your answer. I've tried this code but doesn't give a solution running IEnumerator in the background.
Answer by nevzatbol · Mar 26, 2020 at 10:53 AM
I was able to send the web request in the background by trying the code below. But Android doesn't allow this code to run in the background.
private BackgroundWorker worker = new BackgroundWorker();
private void Awake()
{
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
GetRequest();
e.Result = "all done";
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// will output "all done" to the console
Debug.Log((string)e.Result);
}
async void GetRequest()
{
string IpURL = IPClass.url + IPClass.port + "/api/data";
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(IpURL))
{
Debug.Log(response.IsSuccessStatusCode);
if (response.IsSuccessStatusCode)
{
using (HttpContent content = response.Content)
{
ErrorData(content.ReadAsStringAsync().Result);
}
}
}
}
}
Answer by Tony-Lovell · Jun 22, 2021 at 12:14 PM
Unity is missing an opportunity by failing to recognize that it offers 80% of what is needed for cross-platform phone app (not necessarily games) for Android and iOS. Rather than spending more time developing the N+Mth generation particle generating system, some time spent abstracting interfaces to SMS, phone calling, cameras, contact data stores, etc would create a much-needed IDE.