For my app I need to be able to let the user specify a given time and let my app run a background task at that specific time.
I understand that with wp8.1 a timetrigger background task can only run every 15 minutes. Is there anything I can do to ensure my app will run the task if the time has gone 10 minutes over the user's specified time?
For what I understand tasks are only executed in intervals multiple of 15 minutes in Windows 8.1 and 30 minutes in Windows Phone 8.1. Have a look here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh977059.aspx
I can not add a comment, that's why I share my experiences as an answer.
We had a similar problem in an application - we target the Windows Store 8.1 platform but our experiences can be relevant for you as the app cycles in the two platform are converged (http://msdn.microsoft.com/en-us/library/windows/apps/dn632424.aspx).
In our app we have to monitor streams and collect information. This logic has to be executed per minute what is not supported, as mentioned. That's why we use a simple Task with a CancellationTokenSource, and we start/stop the task in the app cycle-related events (Suspending, Resuming). This "solution" is not acceptable if the execution of the background logic is required when the app is suspended, too, but in our case this was not required.
Related
I'm writing an app with Xamarin.Android to retrieve data from some domotic sensors(Sonoff, Shelly) and to set some switches. I need it to make api calls even in background, say about every 5 or 10 minutes. I know it's a very short amount of time, I plan to do this with an Arduino later, but now I need this.
I researched a bit, read about Services and their limitations, but I can't figure out how to do this. Can someone help me? Thanks
You can either:
create a Foreground Service that keeps running, and you execute a timer there
use WorkManager from Android X, which depending on device capabilities and software versions will use the following in priority:
JobScheduler
Firebase JobDispatcher
AlarmManager
JobScheduler allows you (kind of like cron on Linux) to set up scheduled tasks to be run. However, it is limited in how frequent you can do this. This frequency depends on Android version and depends on the criteria on the job and whether the device is not running out of resources.
With the foreground service, you can do more or less what you want as long as the service is alive. You might need to disable battery optimizations in battery settings for your App, but otherwise it should just work.
Apart from these features, unless you are either using a rooted device or you are device admin on the device, you can't do much more. In case of root/device admin, you can mark your app as Persistent to disallow it being killed by Android.
My background task takes a long time to complete, and the OS is just killing it. I'm trying to sync my contacts online, here's what I'm doing:
Get all contacts from phonebook (takes ~1 second)
Upload them to a server (~2 seconds)
Retrieve all contacts from server (~2-3 seconds)
Delete all contacts from ContactStore(ContactStore.DeleteAsync sometimes takes 1 minute to complete)
Create a ContactStore and import all contacts )(~1-2 minutes for 1000 contacts)
I have ~100 contacts and it's working well, but I wanted to test with ~1000 contacts and it doesn't complete every time. I'm using a MaintenanceTrigger, but I think it's still too much for a background task, but I need a confirmation for this. MaintenanceTrigger tasks should be allowed to do more resource intensive tasks, so why is the OS killing my background task?
Take a look at this link: https://msdn.microsoft.com/en-us/library/windows/apps/hh202942(v=vs.105).aspx
Resource intensive tasks are constrained to a duration of 10 minutes.
The following constraints must be met before the task is started. If the device stop fulfilling these constraints the agent is terminated immediately.
External power required
Non-cellular connection required
Minimum battery power
Device screen lock required
No active phone call
Cannot change network to cellular
Besides this there are also a memory cap of respectively 11mb and 20mb for low/high end devices.
From your description above the most likely scenario IMO is the memory cap being hit. Maybe this post can help you look into the memory usage of your background task: How to get memory available or used in C#
Key changes to memory limits starting in Windows Phone 8.1 include (found here):
All Windows Phone 8 foreground apps are treated the same. We no longer have different memory caps for XNA, native or Silverlight apps.
Windows Phone 8.1 apps (including both Silverlight 8.1 and Windows Runtime) apps do have slightly higher caps than Windows Phone 8 apps.
Memory caps for all app types, including Continuous Background Execution (CBE), scale up with increased memory.
There is no longer a "default" and "higher" cap - there is only the default cap.
The ID_FUNCCAP_EXTEND_MEM manifest entry is ignored for all apps running on Windows Phone 8.1.
The ID_REQ_MEMORY_300 manifest entry is still valid, but you should really make your app run on all devices.
The new equivalent of ID_REQ_MEMORY_300 is below. This entry should be added to the AppX manifest (not to the WMAppManifest).
Finally, my task got canceled with the reason ExecutionTimeExceeded, so this is the problem. It seems that trying to import ~1000 contacts in the ContactStore takes ~12 minutes, which is too long for a background task. I'll have to make the user to open the app and do the import. Thank you for your help.
erm... may be silly but...
"Background tasks that use a maintenance trigger run only when the system is connected to AC power." Taken from MSDN
Could it be plugged into the mains when it works?, and not plugged in when it doesn't work?
EDIT: Are you considering how busy the phone is when you try to 'sync' contacts? Are you forcing the app to allways run in the background via Battery Saver?
You could do something like this to see how busy your phone is... or it could be the battery saver halting your app if download size etc limits are reached...
Taken from here...
var result = await BackgroundExecutionManager.RequestAccessAsync();
if (result == BackgroundAccessStatus.Denied)
{
// Handle this if it is important for your app.
}
"If the result is denied the phone thinks it has too much background task active. In that case you can prompt your users to go the Battery saver application and force allow your app to run in the background even if the phone donĀ“t want to..."
I want to develop an app which downloads small files continuously when my app is not in the foreground and sends a notification if certain conditions are met.
Problem is that periodic agents have a scheduled interval of 30 minutes and a duration of 10 seconds, while resource-intensive agents have a duration of 10 minutes and need an external power source.
How could I do to achieve my goal ?
If you don't mind upgrading your Application to WP8.1 then you can use a very simple class to download a file in the background.
BackgroundDownloader class. There is really good example at the bottom of the page as well.
Useful Links if you want to understand more:
Transferring data in the background Describes the events of the BackgroundDownloader.
Periodic Tasks should really only do something very simple IMHO (that is why they have those restriction, not download something continuously) for example, Grab the latest news from a feed and update the Secondary Title.
Windows Phone platform offers BackgroundTasks infrastructure. I can register my task like that:
builder.TaskEntryPoint = TaskName;
var trigger = new TimeTrigger(15, false);
builder.SetTrigger(trigger);
builder.Register();
The problem is, that TimeTrigger min interval is ~15 minutes, which is pretty large for my application. I need to have task which runs every 1-2 minutes in the background. Is it possible on Windows Phone?
It is not possible to have BackgroundTasks that run on a minute interval basis.
As you said already the minimum interval is 15 minute.
This is an OS limitation to prevent developers to build battery draining applications.
You always have some workarounds, like having a PushNotificationTrigger, and manage to send a push notification to your device every minute. (I guess some people manage to do so with the ScheduledToastNotification), but i wouldn't recomend it.
AFAIK with the official API - it's not possible to run TimeTrigger so often. Note that on WIndows Phone, the interval is even larger (MSDN):
Windows has a built-in timer that runs background tasks in 15-minute intervals. Note that on Windows Phone, the interval is 30 minutes.
I doubt it will be possible, due to battery consuption/restrictions. Maybe you can leave your app in the foreground and disable lockscreen (by using DisplayRequest).
Also you may try to run a timer along with obtaining deferal in your BackgroundTask. I've not tried that, for sure there will be many problems (CPU limit, memory and other restrictions), I'm not sure if that is not against certification requirements and of course it doesn't guarantee that your BackgroundTask wouldn't be terminated by OS.
I want to potentially update the tile of my WP8 app periodically - no more frequently than every hour or two. However, I don't want my app to have to be running for this background task to take place (will query a WAMS and, based on the returned results, update the WP8 app's tile).
Is this possible, or do background tasks (I found this tutorial on how to create one:
http://thesociablegeek.com/windows-8/livetiles/modifying-live-tiles-in-a-background-process/) require that the app that hosts them be running?
IOW, what I basically need is similar to a Windows Service, that his hosted by the OS, not a/my particular app.
Here's a guide how to use so called Background Agents in Windows Phone 7 or 8:
Background agents for Windows Phone
Basically you can schedule simple task to be executed every 30 minutes, even the main application is not running. There are system requirements on these tasks like memory cap constraint 6 MB for WP7 and 11 MB for WP8 tasks, run time of each task 25 seconds, and limited available APIs.
I would recommend that you code your tile update logic as a periodic task and then configure it to run in background. this way, you don't have to maintain your app running in background.
Hope this helps.