Background agent task is never executed in Mango - windows-phone-7

I have a background agent that i would like to be executed in Mango for updating the live tile.
The problem is that it is never executed.
Here is the code that i used:
//start background agent
PeriodicTask periodicTask = new PeriodicTask("BruceWpAgent");
periodicTask.Description = "BruceWp periodic live task";
periodicTask.ExpirationTime = System.DateTime.Now.AddDays(10);
// If the agent is already registered with the system,
if (ScheduledActionService.Find(periodicTask.Name) != null)
{
ScheduledActionService.Remove("BruceWpAgent");
}
ScheduledActionService.Add(periodicTask);
I've found my app name between that Apps that use background jobs but the task is never invoked.
What am i doing wrong?

This code may help you..
string periodicTaskName = "PeriodicAgent";
public bool agentsAreEnabled = true;
private void StartBackgroundAgent()
{
// Variable for tracking enabled status of background agents for this app.
agentsAreEnabled = true;
// Obtain a reference to the period task, if one exists
periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
// If the task already exists and background agents are enabled for the
// application, you must remove the task and then add it again to update
// the schedule
if (periodicTask != null)
{
RemoveAgent(periodicTaskName);
}
periodicTask = new PeriodicTask(periodicTaskName);
// The description is required for periodic agents. This is the string that the user
// will see in the background services Settings page on the device.
periodicTask.Description = "Task to update the Economic times tile.";
// Place the call to Add in a try block in case the user has disabled agents
try
{
ScheduledActionService.Add(periodicTask);
// If debugging is enabled, use LaunchForTest to launch the agent in one minute.
ScheduledActionService.LaunchForTest(periodicTaskName, TimeSpan.FromMinutes(2));
}
catch (InvalidOperationException exception)
{
if (exception.Message.Contains("BNS Error: The action is disabled"))
{
MessageBox.Show("Background agents for this application have been disabled by the user.");
agentsAreEnabled = false;
}
}
}

Check out this hands on lab for Adding Multitasking to Your Application in Windows Phone 7.5, that should cover it.

Related

How to start the app that is associated to the IBackgroundTask I've created in UWP Windows 10

I implemented an IBackgroundTask on Universal Windows 10 and it works like a charm but the problem is that i want to start the app that is associated to that background task if some action occurs. The code is simple:
public sealed class AdvertisementWatcherTask : IBackgroundTask
{
private IBackgroundTaskInstance backgroundTaskInstance;
public void Run(IBackgroundTaskInstance taskInstance)
{
backgroundTaskInstance = taskInstance;
var details = taskInstance.TriggerDetails as BluetoothLEAdvertisementWatcherTriggerDetails;
if (details != null)
{
//Do things
}
}
}
I've seen that you can create a ToastNotification like that:
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
Windows.Data.Xml.Dom.XmlNodeList elements = toastXml.GetElementsByTagName("text");
foreach (IXmlNode node in elements)
{
node.InnerText = taskInstance.Task.Name+ " remember to uninstall task if not debugging";
}
ToastNotification notification = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(notification);
The notification toast works good. It creates and prompts a notification and if you click it, the app that created this background task starts. This is the behaviour that I want but I want to start the app without having to click any notification. Is there any way to achieve this? Thank you.
TL;DR: I want to start the app that created the background task at some point of the code.
You can not programmatically launch URI or open app from background task. You can however display a reminder or toast notification to let user open your app.

Geofence is not being triggered in the background in windows phone 8.1

I'm trying to implement geofencing in Windows phone 8.1. First I wanted to create a sample Project to understand how it Works, but i couldnt make it works. What I'm trying to achieve is basically, I'll set the coordinates and close the app by pressing back button and it will trigger a toast notification when the phone is in the area of interest.
I've created a blank Windows phone(silverlight) 8.1 Project(geofence_test_01) and added a Windows RT Component Project(BackgroundTask) into the same solution. Added a reference for BackgroundTask in the geofence_test_01 Project.
ID_CAP_LOCATION is enabled in the app manifest.
MainPage.xaml has only one button to start geofencing.
<Button Name="btnStart" Content="Start" Click="btnStart_Click"/>
In btnSave_Click, I call a method which creates the geofence and registers the background task.
private void btnStart_Click(object sender, RoutedEventArgs e)
{
Init_BackgroundGeofence();
registerBackgroundTask();
}
private async Task Init_BackgroundGeofence()
{
//----------------- Crating Geofence ---------------
var geofenceMonitor = GeofenceMonitor.Current;
var geoId = "building9";
var positionBuilding9 = new BasicGeoposition()
{
Latitude = 47.6397,
Longitude = -122.1289
};
var geofence = new Geofence(geoId, new Geocircle(positionBuilding9, 100),
MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited,
false, TimeSpan.FromSeconds(10));
geofenceMonitor.Geofences.Add(geofence);
}
private async Task registerBackgroundTask()
{
//----------------- Register Background Task ---------------
var backgroundAccessStatus =
await BackgroundExecutionManager.RequestAccessAsync();
var geofenceTaskBuilder = new BackgroundTaskBuilder
{
Name = "GeofenceBackgroundTask",
TaskEntryPoint = "BackgroundTask.GeofenceBackgroundTask"
};
var trigger = new LocationTrigger(LocationTriggerType.Geofence);
geofenceTaskBuilder.SetTrigger(trigger);
var geofenceTask = geofenceTaskBuilder.Register();
}
And finally, in BackgroundTask, I've the following code:
namespace BackgroundTask
{
public sealed class GeofenceBackGroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var geofenceMonitor = GeofenceMonitor.Current;
var geoReports = geofenceMonitor.ReadReports();
var geoId = "building9";
foreach (var geofenceStateChangeReport in geoReports)
{
var id = geofenceStateChangeReport.Geofence.Id;
var newState = geofenceStateChangeReport.NewState;
if (id == geoId && newState == GeofenceState.Entered)
{
//------ Call NotifyUser method when Entered -------
notifyUser();
}
}
}
private void notifyUser()
{
var toastTemplate = ToastTemplateType.ToastText02;
var toastXML = ToastNotificationManager.GetTemplateContent(toastTemplate);
var textElements = toastXML.GetElementsByTagName("text");
textElements[0].AppendChild(toastXML.CreateTextNode("You are in!"));
var toast = new ToastNotification(toastXML);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
}
I get no error when building and deploying this in the emulator. I set a breakpoint in the backgroundTask but I've not seen that part of code is called yet. It never hits the breakpoint. I test it by using Additional Tools of the emulator, in Location tab, by clicking somewhere in my geofence area on the map, waiting for a while, but it never hits the breakpoint. Hope somebody can tell me what i am missing here...
I've checked these following links to build this application:
http://www.jayway.com/2014/04/22/windows-phone-8-1-for-developers-geolocation-and-geofencing/
Geofence in the Background Windows Phone 8.1 (WinRT)
Toast notification & Geofence Windows Phone 8.1
http://java.dzone.com/articles/geofencing-windows-phone-81
Thanks
You can download the project here:
https://drive.google.com/file/d/0B8Q_biJCWl4-QndYczR0cjNhNlE/view?usp=sharing
---- Some clues
Thanks to Romasz, I've checked the Lifecycle events and i see "no background tasks" even after registerBackgroundTask() is executed.... Apparently there is something wrong/missing in registerBackgroundTask() method.
I've tried to build my sample (it was easier for me to build a new one) basing on your code and it seems to be working. You can take a look at it at my GitHub.
There are couple of things that may have gone wrong in your case:
remember to add capabilities in WMAppManifest file (IS_CAP_LOCATION) and Package.appxmanifest (Location)
check the names (of namespaces, classes and so on) in BackgroundTask
check if your BackgroundTask project is Windows Runtime Componenet and is added to your main project as a reference
I know you have done some of this things already, but take a look at my sample, try to run it and maybe try to build your own from the very beginning.
Did you add your background task in the Package.appxmanifest under Declarations with the correct supported task types (Namely Location)?

Background agent error WP7

When I try to add a periodic task in windows phone 7.5 it gives me a "BNS Error: The maximum number of ScheduledActions of this type have already been added." error while i haven't added any periodic task. The code works fine on Windows phone 8 but raises this error on WP7.5. Also the app schedules reminders and alarms.
string periodicTaskName = "myperiodictask";
PeriodicTask periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
if (periodicTask != null)
{
try
{
ScheduledActionService.Remove(periodicTaskName);
}
catch (Exception)
{ }
}
periodicTask = new PeriodicTask(periodicTaskName);
periodicTask.Description = "Updates LiveTile, Sessions and Assignments";
periodicTask.ExpirationTime = DateTime.Now.AddDays(10);
try
{
ScheduledActionService.Add(periodicTask);
}
catch (InvalidOperationException exception)
{
if (exception.Message.Contains("BNS Error: The action is disabled"))
MessageBox.Show("Background agents have been disabled by the user.");
if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type have already been added."))
MessageBox.Show("maximum number of ScheduledActions of this type have already been added!");
}
catch (SchedulerServiceException)
{ }
How are you testing the background agent? Emulator or Device. Either way, you need to make sure you're not testing on a low memory 'device'.
On low memory devices (256mb), background agents are disabled. Unfortunately, the error thrown is the same as when the maximum number of agents are scheduled, i.e. "BNS Error: The maximum number of ScheduledActions of this type have already been added."
Please refer these posts.
http://codeblog.vurdalakov.net/2012/02/solution-bns-error-maximum-number-of.html
http://imjo.hn/2013/01/23/bns-error-the-maximum-number-of-scheduledactions-of-this-type-have-already-been-added/
In debugging you added some task and its registered your app but you are not removing earlier
tasks thats why this happening.

Launching a background agent from within the app

As far as I have understood, if you register a periodic task to deal with your WP7 live tiles, it will not update more than once every half hour. However, I would like to update the data the background agent works on every time the user exits the app.
My scenario is that I have a live tile displaying the first entry in a planner - and depending on what the user does within the app, that planner might get its entries deleted or have a new one up front. To have the live tile present outdated info is not very appealing.
Is this possible - and if so, how to?
I dont know if this is what you are looking for.
My app updates livetiles when the user exits the app. But then I have had problems such as, if the user does not open the app for few days then it does not get updated.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
ShellTile PrimaryTile = ShellTile.ActiveTiles.First();
StandardTileData tile = new StandardTileData();
if (PrimaryTile != null)
{
tile.BackTitle = resMan.GetString("liveTileTitle");
tile.BackBackgroundImage = new Uri("/Background.png", UriKind.Relative);
if (pCycMan.GetStartDate() == pCycMan.GetDefaultDate())
{
tile.Title = resMan.GetString("liveTileNotTrackingStatus");
}
else
{
tile.Title = App.m_liveTileText;
}
PrimaryTile.Update(tile);
}
}

Is it possible to check whether the location services are active?

is it possible to check whether the location services are active?
I mean Settings > Location > Location services
There is probably no direct API for calling, but could it work with the GeoCoordinateWatcher?
GeoCoordinateWatcher g = new GeoCoordinateWatcher();
g.Start();
if (g.Permission.Equals(GeoPositionPermission.Granted))
{
//Your location services is enabled. Go ahead.
//Your codes goes here.
}
else if (g.Permission.Equals(GeoPositionPermission.Denied) || g.Permission.Equals(GeoPositionPermission.Unknown))
{
MessageBox.Show("Location services are disabled. To enable them, Goto Settings - Location - Enable Location Services.", "Location services", MessageBoxButton.OK);
}
You can use the following code to determine the status of the Location service:
var watcher = new GeoCoordinateWatcher();
if (GeoPositionStatus.Disabled == watcher.Status)
{
// Watcher is disabled.
}
More realistically, you'll want to pay more attention to change to the status (just because the service isn't disabled doesn't mean you've got location data), so you shoudl take a look at the MSDN Documentation for working with the Location service.
There's also a good post on filtering and emulating location data using the Reactive extensions, which is perfect for that pre-device testing, though to save you time on that front the Widnows Phone Team have released the Windows Phone GPS Emulator.
Even with the started GeoCoordinateWatcher you will get NoData if the sensor is disabled. What you should try using instead is TryStart:
GeoCoordinateWatcher g = new GeoCoordinateWatcher();
MessageBox.Show(g.TryStart(false,TimeSpan.FromSeconds(30)).ToString());
If it returns False, it means that the sensor is disabled. If it returns True, it is enabled. Set an appropriate timeout period (in the snippet above I am using 30 seconds) and delegate this process to a secondary thread, so it won't hang the UI.
You can add a StatusChanged event to your GeoCoordinateWatcher and test for GeoPositionPermission.Denied in the permissions when it fires.
watcher = new GeoCoordinateWatcher();
watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.Start();
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
if (watcher.Permission == GeoPositionPermission.Denied)
{
// Location services were disabled
}
}
Hope that helps.
Made this one based on TeJ's answer.
public override void OnNavigatedTo()
{
using (var watcher = new GeoCoordinateWatcher())
{
try
{
watcher.Start();
}
finally
{
IsAllowedInSystem = watcher.Permission.Equals(GeoPositionPermission.Granted);
watcher.Stop();
}
}
}
And my apps' ToggleSwitch.IsEnabled is binded to IsAllowedInSystem.
When i'm switching to Location Service, disable it and return back to app, my ToggleSwitch is disabled (also a string "Please, enable Location Service in System settings" in visible). When i'm switching to Location Service, enable it and return back to my app, my ToggleSwitch is enabled and user can set it up.

Resources