Schedule a function to play after a certain time in xamarin - xamarin

So what i want to do (if posible) is to execute a function after a certain time even if the app gets closed by the user, what the function does is send a mqtt message to a server. I heard about AlarmManager and BackgroundReciver, but i dont know if that can play a whole function. Can someone tell me if it's possible?

In android, you can try to use Services to achieve this.
And from document Background Execution Limits in Android 8.0,we know that
Starting in Android 8.0 (API level 26), an Android application no longer have the ability to run freely in the background. When in the foreground, an app can start and run services without restriction. When an application moves into the background, Android will grant the app a certain amount of time to start and use services. Once that time has elapsed, the app can no longer start any services and any services that were started will be terminated. At this point it is not possible for the app to perform any work. Android considers an application to be in the foreground if one of the following conditions are met:
There is a visible activity (either started or paused).
The app has started a foreground service.
Another app is in the foreground and is using components from an app
that would be otherwise in the background. An example of this is if
Application A, which is in the foreground, is bound to a service
provided by Application B. Application B would then also be
considered in the foreground, and not terminated by Android for being
in the background.
There are some situations where, even though an app is in the background, Android will wake up the app and relax these restrictions for a few minutes, allowing the app to perform some work:
A high priority Firebase Cloud Message is received by the app.
The app receives a broadcast.
The application receives and executes a PendingIntent in response to
a Notification.
You can also refer to https://robertohuertas.com/2019/06/29/android_foreground_services/.

Related

How can I keep my app on Galaxy watch4 alive and the service running during watch idle mode?

I'm an Android developer and working on a wearable app that runs on Galaxy watch 4.
In short description, this app use a foreground service that's connected to Mqtt broker and receives real-time alerts and displays them to the user.
Up until recent system SW upgrade I used a Wifi Lock to keep the network alive for my app and the foreground service allowed my app to keep running in the back during idle mode. I also used a Wake Lock to wake the watch when an alert was received so it can be displayed to the user.
On 16.02.22 the watches were updated and after that, whenever the watch turns off the screen and goes into idle mode, my application disconnects from all OS resources (network, even CPU). It seems like the process is suspended. When I bring the watch back from idle, my application continues running but its stays in the background and not returned to the fore.
I tried different approaches to solve this, such as Ambient mode and more, all my efforts to come up with a workaround met a brick wall.
Am I missing something?
I see other apps that use body monitoring via the sensors for example, that keep working and throw notifications even when the watch is idle.
Please help, how can I keep my app alive and the service running (and using the network) during watch idle mode?

Confusion between all backgrounding options (and their evolution in time) with Xamarin.Forms Android

I've tested various backgrounding options (xamarin samples, xamarin blog articles, various sources) but I'd like some clarification on the pro/cons of each one, and if some are deprecated/obsolete.
My case is an app (wifi, on client premises) that should periodically poll a server for new data, or push collected data to the server as soon as it has connection (it should continue to collect data if no connection is available, but push to the server as soon as it has connection).
I want this sync to be in the background for the user, who in the meantime can continue to work.
I would like the push (if data is present) to be done each 1 or 2 minutes, so I can just create a task in the background job with an infinite while that checks every 1/2 minutes.
I made some basic samples to test:
1) using a LongRunningTaskService : Service
2) using Firebase.JobDispatcher
3) using WorkManager (but scheduled jobs can't be less than 15 minutes)
4) looking at Shiny, but currently having trouble integrating with Prism (but I guess I'll make it work)(but don't understand if it is a wrapper of what exactly?)
Which solution do you think is appropriate for my use case?
With all the 4 solutions, data should be pushed when the app is in foreground or background (right?)
In case I need to push data only when the app is in the foreground, would it be wrong to start my Task in App class?
UPDATE
Tried this in the OnInitialized() of the App.cs:
Task.Factory.StartNew(async () =>
{
while (true)
{
await BackgroundTasks.TestPushDataRepeat();
await Task.Delay(60000);
}
}
, TaskCreationOptions.LongRunning);
It works every minute when the app is in foreground (and doesn't block the UI), but unexpectedly works also when the app is backgrounded (that is a not needed plus, for my case). Not being a service, I thought it should have freezed, why is that?
I'm trying to better understand/separate how the TPL works with Xamarin on Android, and how Android backgrounding (services/workers etc) works, to see if this solution has drawbacks.
On Android, you cannot run a background task/job/worker every 30 seconds. Such behavior can have a negative impact on the battery and can only be achieved with a Foreground Service that requires a notification visible to the user.
The limit you see for WorkManager about the 15 minutes minimum interval is an OS constraint, not a library constraint. You have the same limit if you use JobScheduler. Also a Worker (or Job if you're using JobScheduler) can run only for 10 minutes.
So, you need to have a Foreground Service. You can still use WorkManager and its advanced features in this case, but you need to use WorkManager 2.3+ and "promote" your worker to a Foreground Service. WorkManager's documentation covers this use case.
This for native Android (Java/Kotlin). I don't know how the latest Xamarin binding cover this use case.

Wear Actions execute very slow or not at all when phone is in doze mode

I am building an Android App to control power outlets with a smartphone. The app features an Android Wear app so people can control their lights right from their wrist.
When the user wants to control a light I send a String action via the MessageApi from the smartwatch to the smartphone, which receives this action in a WearableListenerService and sends the appropriate network signal to the power outlet/gateway in an AsyncTask.
This works fine as long as the phone has not been in idle for too long. However if the phone is still on the table for too long and doze kicks in Wear actions do execute very slow or sometimes not at all. I guess this is in part intended behavior however it is not practical in my case as the user cant wait that long for his lights to turn on if he wants to enter a dark room.
I am aware that doze completely cuts the networking for everything except FCM/GCM if you are not on the doze whitelist. But even when my app is on this whitelist and the networking part works actions can take a long time to execute on the phone.
So my specific question is:
Whats the recommended way to handle this scenario, where an action from a wearable device needs to be done via network on the connected smartphone which is in doze mode?
Is there a way to exit doze for a quick amount of time to execute calculations triggered by the wearable companion app faster?
I know the AlarmManager has a new method that works even in doze mode, but will this fix the processing delay too? Firing an alarm after receiving a MessageEvent from MessagApi seems like a workaround to me.
Or maybe is an AsyncTask just the wrong way to handle background networking and thats where the delay comes from?
Actually, there are a few options that you can do to handle Doze's effects as given in Adapting your app to Doze. You may want to consider the following options:
If your app requires a persistent connection to the network to receive messages, you should use Google Cloud Messaging (GCM) if possible.
GCM is optimized to work with Doze and App Standby idle modes by means of high-priority GCM messages. GCM high-priority messages let you reliably wake your app to access the network, even if the user’s device is in Doze or the app is in App Standby mode.
To help with scheduling alarms, Android 6.0 (API level 23) introduces two new AlarmManager methods: setAndAllowWhileIdle() and setExactAndAllowWhileIdle(). With these methods, you can set alarms that will fire even if the device is in Doze.
However, please note that with these methods, neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.
Please try going through Optimizing for Doze and App Standby for a more detailed information or discussion.
In addition to these given documentations, the same options in handling Doze were also given and discussed in Diving into Doze Mode for Developers which might also help.

How to run a service without being depending on activity going to background

I'm building an application that must does the following
when the user opens the application, the application starts (in the background) searching for some places using GPS and WiFi. and gives the user a notification when finding a location.
The searching process must start working in the background when the MainActivity launches, not when the MainActivity become in background
and mustn't stop if I finished the MainActivity,
it shouldn't stop also if the user opened another application.
It may only be stopped when the application is closed.
I searched for a way to make these four steps and I found that I can use services to run my code in background, but the problem with services is that it's bounded with activities; if activity is destroyed then the service would stop working [xamarin documentation].
How can I achieve those five conditions?

background process and UI interaction

I am working on an application that is receiving XMPP notifications using the Matrix SDK. As well I am using async web service calls to receive an initial set of data from the server.
Now, I am aware that with Mango I can close the app or move it to the background and have a background task that is able to be run every 30 mins (or so) for 15sec max which obviosuly means the XMPP push isn't going to work in this scenario. Is there any way to get background apps to execute more frequently than this?
Failing that for the syncing process all I can do is every 30 mins use a web service call to get any updates and store into Isolated storage for my app to pick up when it's next run. But I believe I cannot use any UI from a background task so cannot tell the user of updates?
So, if I get an important message can I somehow override the slowness here and force my app to run and inform the user visibly that something has happened and he needs to look at it? Is this where push notifications come in?
You can use the ShellTile API to update the application's tile on the Start screen, or use the ShellToast API to show a toast to the user. Both of these can be configured to launch into a specific part of your application (deep-linking) when tapped.
If you need a constant monitoring/update/notification system for your application when it's not running, then using push notifications is probably the more appropriate approach.

Resources