Extend background time on xamarin ios - c#

I am trying to do a task that runs indefinitely in a background mode in xamarin ios, but the task takes only 30 seconds to kill the app when it is send to a second plane, so I really do not know how to extend this time in order to receive that information.
This is the method that launches the background task:
public async void ActivateHeartbeat()
{
await Task.Factory.StartNew(() =>
{
taskID = UIApplication.SharedApplication.BeginBackgroundTask(() =>
{
Console.WriteLine("APPLICATION GOT KILLED");
UIApplication.SharedApplication.EndBackgroundTask(taskID);
});
while (true)
{
Console.WriteLine("Background time remaining: " + UIApplication.SharedApplication.BackgroundTimeRemaining);
int sent = SendTCP(data);
if (sent > 0) Console.WriteLine("Sent Heartbeat.");
Thread.Sleep(10000);
}
});
}
I have already read all the documentation that Microsoft is offering, but it did not help for me. How can I increase that background time?
Result of console when the app is pushed to second plane (minimizing the app on an iPhone):
Background time remaining: 25.9390514166444
Sent Heartbeat.
Background time remaining: 15.8512012083665
Sent Heartbeat.
Background time remaining: 5.76157358335331
Sent Heartbeat.
APPLICATION GOT KILLED
APPLICATION GOT KILLED
Any help is welcome. Thanks in advance,
Raúl.

It is well-known that Apple is so strict about hardware resources occupied by App, not to mention App in the background state. When App enter the background state, it will soon be suspended by the OS, unless you apply for permisson from OS.
The following image is from XCode Capabilities. These modes can run in the Background Modes.
Seems that you couldn't directly run your app in the background mode.
However, some articles extend the background time by playing blank videos as audio can be played in Background modes. That means we have to play blank audio in the background task. You could refer to Unlimited Backgrounding on iOS. But i have no idea if Apple will approve this app on Apple Store.
Hope my answer makes sense.

Related

Get a notification when Windows Service state change?

im trying to figure out how i can get a notification when the state of a Windows Service changes. First i tryied a timer that check the state every view seconds with the ServiceControl.State. I found this "NotifyServiceStatusChange" but no examples or something like that and dont know how to use that.
Or is there a other way?
Background information:
I have an application. The application has 2 buttons. Everytime the state of the service changes one of the buttons should be disabled. Like Service-State running then disable the "Start Service" button.
Have you had a look at the ServiceController Class? Something like this should get you started.
ServiceController sc = new ServiceController("ServiceName");
switch (sc.Status)
{
case ServiceControllerStatus.Running:
break;
case ServiceControllerStatus.Stopped:
break;
case ServiceControllerStatus.Paused:
break;
}
If you would like to avoid constantly polling on a timer, you could have a look at WaitForStatus. Have your background workers always waiting for a specified status to enable buttons, disable buttons or whatever.
This is a very basic example, but to answer your question about infinite loop - no. see my comments and debug step this, you will understand why.
ServiceController sc = new ServiceController("ServiceName");
for (;;)
{
// for pauses execution, waiting for stopped status.
sc.WaitForStatus(ServiceControllerStatus.Stopped);
// continues when stopped status signaled, disable button
// for waiting for running status.
sc.WaitForStatus(ServiceControllerStatus.Running);
//continues when running status signaled, enable button
// for will continue but wait for stopped status signal
}
This is why I recommended doing this check in a background worker or just something off of the main thread so that your entire application does not get jammed up while waiting for status changes.
If I understood it correctly, you have a windows service running in the background and another app that wants to be notified.
If that is the case, you will need to implement some form of communication between them.
Depending on your requirements, and where you are going to run the solution, you can use Message Queue (MSMQ for example) where you can subscribe/broadcast your messages. Another alternative it would be to user some Real Time Communication (like TCP/Socket, signalR or even using firebase to notify your app).

UnknownError Running ApplicationTrigger only if called while in background

With the new anniversary update sdk i have decided to change my background audio to use the new api. Everything works except that i need to make network calls when a track ends to get the next track or next playlist (8tracks.com app).
The new api allows network connectivity for buffering and downloading the song but after that the network connectivity is gone. At the bottom of this explanation it says that i will need an ApplicationTrigger to make those calls.
So I set one up and it's used in the foreground and background. When the song ends MediaPlayer.MediaEnded is triggered and then ApplicationTrigger.RequestAsync(); is called. The backgroundtask works fine if the app is in the foreground but if its in the background the await ApplicationTrigger.RequestAsync(); returns UnknownError. I have noticed that it will work fine if i'm debugging but if i'm not then the error occurs. Is it not possible to trigger an ApplicationTrigger from the new background audio api?

WebAuthenticationBrowser.AuthenticateAsync() kills the UWP app

I have a universal Windows 10 app where I use
var token = await WebAuthenticationBrowser.AuthenticateAsync(...)
to authenticate user against facebook. It all works fine in a common scenario when it's just the foreground app. However when I add a BackgroundMediaPlayer, start music playback and communication between foreground and background, calling
var token = await WebAuthenticationBrowser.AuthenticateAsync(...)
actually kills my foreground app. When user finishes the authentication in the broker, he is taken back to the app - but it was killed and is re-instantiated. This of course means that awaiting AuthenticateAsync() doesn't produce any results, because it's a new instance of the app.
I would understand this behavior when calling WebAuthenticationBrowser.AuthenticateAndContinue() which was introduced in WP8.1, but this API has been deprecated in UWP.
So my questions are - is this expected behavior (app being killed and relaunched)? If so, how do I get the token from WebAuthenticationBroker during app relaunch?
Here is a sample project to reproduce (with exact steps in a txt file): https://t.co/XtmESd9o5r
Here is a video running the sample (first launch the broker without BackgroundMediaPlayer running, then with it running): http://youtu.be/VcZXBOTiD1Y
I started a conversation about this in twitter: https://twitter.com/lancewmccarthy/status/685152844849262593 but so far the only help I got was to "check the activation kind" with this link: https://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.activation.activationkind.aspx.
The link describes activationKind has "WebAuthenticationBrokerContinuation", but
1) that's only for Windows Phone, not Windows 10
2) when you run the sample, you will never receive it. Only "Launched", with previousExecutionState "Terminated"

WPF, Modal Loader, Thread stop responding on touch events

I'm using a Modal Loader in a WPF Application to indicates to the user some background processing.
All works fine with keyboard and mouse, but when it runs in a Windows tablet the application freezes executing this procedure:
public void Complete(bool focusOnWhoCall = true)
{
try
{
Dispatcher.InvokeShutdown();
}
catch { }
}
Running with the remote debugger, when froze, I pause the running. The visual studio execution pointer is on InvokeShutdown. Then I continue and it executes... It keeps freezed... I pause again and it stopped in the same point.
I uploaded this video on youtube to show the problem: https://youtu.be/IryEJ-YF168
I start using the mouse. All fine. When I use the touch at the first time its freezes... I don't know what to do anymore...
I make a project sample, every can download here: https://onedrive.live.com/redir?resid=F4B7C28FAD05ECCD!3743&authkey=!AHs6dcCjRGJmB4c&ithint=file%2czip
Thank's in advance!

BackgroundAudioTask not working after cancelled by another app

When the BackgroundAudioTask for my app is cancelled by other app on Windows Phone 8.1 which also uses BackgroundAudioTask, when I go back into my app, it will no longer play audio in the background. It will play fine when the app is running but if it is suspended - the background audio also stops.
The steps to reproduce this issue are:
I launch the Windows Phone 8.1 app which has a BackgroundAudioTask & everything works fine. I that start another app, for example the Music player, that uses a BackgroundAudioTask it will cancel the BackgroundAudioTask of my app.
When I launch my app for the second time, I want to re-register my BackgroundAudioTask so that it will behave as it did originally.
In Package.appxmanifest I have the following:
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="WindowsPhoneBackgroundAudioTask.BackgroundAudioTask">
<BackgroundTasks>
<Task Type="audio" />
</BackgroundTasks>
</Extension>
</Extensions>
When I first run the application the Run method will be called and I add a Deferral to the task to make sure it is kept alive even when I close my application:
public void Run(IBackgroundTaskInstance taskInstance)
{
setupDeferral = taskInstance.GetDeferral();
}
When I start the music player from another application my BackgroundAudioTask Cancelled event is called (If I don't do setupDeferral.Complete() here my application will crash):
private void Task_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
setupDeferral.Complete();
}
When I open my app how do I recreate my BackgroundAudioTask? The problem is the Run method is never called again so I can't setup the Deferral again. Music will now play fine in the app, but as soon as I navigate away from the app the music will stop.
I tried manually re-registering the task in App.xaml.cs in the App_Resuming event with this code:
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = "BackgroundAudioTask";
taskBuilder.TaskEntryPoint = typeof(WindowsPhoneBackgroundAudioTask.BackgroundAudioTask).FullName;
BackgroundTaskRegistration task = taskBuilder.Register();
The above code will throw and InvalidArgumentException because it does not have a Trigger setup. I don't want it to have a trigger. I just want to start the background task immediately.
Is there a way to manually instruct the OS to run the background audio again or a way to handle cancelled background audio better?
I know this is really old - but maybe someone will come across it. You actually don't need to register the task at all.
In the case of background audio, all you need to do is call
BackgroundMediaPlayer.Current
And it will fire up the task, and then your code will get the deferral.
I too had this same issue. The Background Audio Task wasn't starting playback once it was cancelled - either due to 5 minutes of inactivity, or due to another app. I was referring the sample code given by Microsoft here.
After hours of searching on the internet, I didn't find a solution. Then, digging in my code further, I found out that when the task is cancelled, the BackgroundMediaPlayer.Current.CurrentState becomes MediaPlayerState.Closed.
Hence, in order to restart the task/background audio playback, just set a source to the BackgroundMediaPlayer.Current again. In the sample code, this media player object is referenced using a variable named mediaPlayer inside the PlaylistManager project component.
Although the sample has a piece of code to restart playback once the task is cancelled, it does not work.

Categories

Resources