Xamarin: Block sleep mode while running a process - c#

Sometimes it is required to turn off sleep mode in the application while a lengthy process is running. When the process has done, sleep mode can be turned on again.
How to do that in Xamarin, for Android and iOS projects?

We'll make an interface and use DependencyService to run platform-specific implementation in the platform-agnostic project.
In the platform agnostic project create an interface:
namespace MyCompany.Services {
public interface ISleepModeHandler
{
public void BlockSleepMode(bool blockSleepMode);
}
}
In the Android project:
In the AndroidManifest.xml file, add this permission:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Add Xamarin.Essentials dependency to the platform-agnostic and to the android project. And don't forget to initialize Xamarin.Essentials in the android project.
Create the class:
using Android.Views;
using MyCompany.Android.Services;
using MyCompany.Services
using Xamarin.Essentials;
using Xamarin.Forms;
[assembly: Dependency(typeof(SleepModeHandlerForDroid))]
namespace MyCompany.Android.Services
{
public class SleepModeHandlerForDroid : ISleepModeHandler
{
public void BlockSleepMode(bool blockSleepMode)
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
{
MainActivity activity = (MainActivity)Platform.CurrentActivity;
if (blockSleepMode)
{
activity.Window.AddFlags(WindowManagerFlags.KeepScreenOn);
}
else
{
activity.Window.ClearFlags(WindowManagerFlags.KeepScreenOn);
}
});
}
}
}
In iOS project create the class:
using MyCompany.Services;
using MyCompany.iOS.Services;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(SleepModeHandlerForiOS))]
namespace MyCompany.iOS.Services
{
[Foundation.Preserve(AllMembers = true)]
public class SleepModeHandlerForiOS : ISleepModeHandler
{
public void BlockSleepMode(bool blockSleepMode)
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
{
UIApplication.SharedApplication.IdleTimerDisabled = blockSleepMode;
});
}
}
}
That's it. Now, in platform agnostic module, when you want to block sleep mode while processing, and turn it on afterwards use the following approach:
ISleepModeHandler sleepModeHandler = DependencyService.Get<ISleepModeHandler>();
sleepModeHandler.BlockSleepMode(true); // blocking the sleep mode
// your process goes here
sleepModeHandler.BlockSleepMode(false); // allowing the sleep mode again

Related

How to access GetSystemService(AudioService) in the UI layer

I am developing android App in Xamarin. I want to create an interface and its implementing class in the UI layer. As you see in the below code,
I am getting an error when ever, I use
this.GetSystemService(AudioService);
it is never recognized.
please have a look at the imports below. please let me know how to get it working.
code:
public class ImplClass :
InterfaceFile
{
public bool IsAllowed(Context ctx)
{
AudioManager audioMgr =
(AudioManager)this.GetSystemService(AudioService);
}
}
import:
using System;
using System.Runtime.Remoting.Contexts;
using Android.Media;
using MvvmCross.Platform;
using Android.Content.PM;
You can use the "Application Context".
Example:
public class ImplClass : InterfaceFile
{
public bool IsAllowed(Context ctx)
{
AudioManager audioMgr = (AudioManager)Application.Context.GetSystemService(AudioService);
}
}
I am using this and it works.
global::Android.App.Application.Context.GetSystemService

Main page with System.NotImplementedException error

I get a System.NotImplementedException error whenever I try to launch the page on the emulator that takes photographs. Whenever I attempt to take a photo with the emulator's camera, I get taken to the main page in the Xamarin Studio project that launches the user interface. I get the error:
System.NotImplementedException has been thrown
This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.
Here is the code:
using UIKit;
namespace Relate.iOS
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
/* if you want to use a different Application Delegate class
from "AppDelegate" you can specify it here. */
UIApplication.Main(args, null, "AppDelegate");
}
}
}
Can anyone help?
Here is the code for the camera. I added Media Plugin to my project.
using System;
using Relate.Model;
using Xamarin.Forms;
using Plugin.Media;
namespace Relate.Views
{
public partial class EditMemberPage : ContentPage
{
public EditMemberPage()
{
InitializeComponent();
saveButton.Clicked += async (sender, args) =>
{
if (CrossMedia.Current.IsCameraAvailable &&
CrossMedia.Current.IsTakePhotoSupported)
{
// Supply media options for saving our photo after
it's taken.
var mediaOptions = new
Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Receipts",
Name = $"{DateTime.UtcNow}.jpg"
};
// Take a photo of the business receipt.
var file = await
CrossMedia.Current.TakePhotoAsync(mediaOptions);
}
};
}
async void SaveButton_OnClicked(object sender, EventArgs e)
{
var famMemberItem = (FamMember)BindingContext;
await App.Database.SaveFamMemberAsync(famMemberItem);
await Navigation.PopAsync();
}
}
}
The answer here should explain why this is not working for you: https://forums.xamarin.com/discussion/93536/error-while-accessing-camera
You cannot access platform specific features using portable common libraries. If you want to access your emulators camera you'll have to use something like Media Plugin
https://github.com/jamesmontemagno/MediaPlugin

File permissions for Background Tasks in Win10

I have been trying to write a C# application on Win10 that only runs a background task that writes into a file.
Running the code below throws UnauthorizeAccessException exception after the trigger, 'Access to the path 'C:\temp' is denied'.
The file and directory both have full access for Everyone.
Also, what can background tasks access/run? I am trying to run a background task while in modern standby and for it to read some registers and/or run another tool. Is that even possible while still in modern standby?
Here is the code of my attempt in doing so:
Background task:
using Windows.ApplicationModel.Background;
using System.IO;
namespace RuntimeComponent2
{
public sealed class Class1 : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
File.WriteAllText(#"C:\temp\test.txt", "test");
}
}
}
Main page:
using System;
using Windows.ApplicationModel.Background;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace App3
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
var exampleTaskName = "MyTask1";
foreach (var t in BackgroundTaskRegistration.AllTasks)
{
t.Value.Unregister(true);
}
await BackgroundExecutionManager.RequestAccessAsync();
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "RuntimeComponent2.Class1";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
BackgroundTaskRegistration task = builder.Register();
}
}
}
You cannot do that, and the problem is not regarding the BackgroundTask. Inside a UWP application you cannot write on your hard-disk. The only places you can read & write is accessible using ApplicationData.Current (LocalCacheFolder, LocalFolder and so on), or any folder the user choose explicitly using SaveFilePicker.
Furthermore, you need to use this syntax (Intellisense suggests you to use the class File, but in UWP isn't really available)
FileIO.ReadTextAsync(StorageFile file);

Problem to open REPL using Xamarin Test Cloud

I'm beginner in Xamarin Test Cloud and I want to write tests for Xamarin Test Cloud.
I have Xamarin UITests in my solution and I tried to launch REPL, but UITest REPL window didn't open.
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
using Xamarin.UITest;
using Xamarin.UITest.Android;
using Xamarin.UITest.Queries;
namespace MurakamiKiev.UITests
{
[TestFixture]
public class Tests
{
AndroidApp app;
[SetUp]
public void BeforeEachTest ()
{
app = ConfigureApp.Android.StartApp ();
}
[Test]
public void TestLaunch ()
{
app.Repl();
}
}
}
Where is the error?
Also, what I need to write to launch specified activity?
If you don't have the application source code in the same solution then you'll need to specify the prebuilt app by pointing to it via a full path.
[SetUp]
public void BeforeEachTest ()
{
app = ConfigureApp.Android.ApkFile("<path-as-string>").StartApp ();
}

Cannot launch Repl() in Xamarin

I'm writing UITests on Xamarin
I try to launch the Repl window, but it doesn't launch.
My code:
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
using Xamarin.UITest;
using Xamarin.UITest.Android;
using Xamarin.UITest.Queries;
namespace MurakamiKiev.UITests
{
[TestFixture]
public class Tests
{
AndroidApp app;
[SetUp]
public void BeforeEachTest ()
{
app = ConfigureApp.Android.StartApp();
}
[Test]
public void ClickingButtonTwiceShouldChangeItsLabel ()
{
app.Repl();
}
}
}
This is, how I try to launch Repl:
That is, what I have in Console.
What wrong with my code??
I tried breakpoints, but nothin happens.
I tried to update references, but it didn't help.
Or if issue not in code, how I can launch Repl window?
Help me please I wrote Xamarin forums, but don't have answer.
UPDATE
I try to use Debug and x86
Have this error
Severity Code Description Project File Line Suppression State
Error java.lang.OutOfMemoryError. Consider increasing the value of $(JavaMaximumHeapSize). Java ran out of memory while executing 'java.exe -jar C:\android-sdk\build-tools\23.0.1\\lib\dx.jar --no-strict --dex --output=obj\x86\Debug\android\bin obj\x86\Debug\android\bin\classes "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v6.0\mono.android.jar" C:\Users\nemes\Documents\GitHub\Murakami_kiev\MurakamiKiev\obj\x86\Debug\__library_projects__\Square.OkHttp\library_project_imports\okhttp.jar C:\Users\nemes\Documents\GitHub\Murakami_kiev\MurakamiKiev\obj\x86\Debug\__library_projects__\Square.OkIO\library_project_imports\okio-1.6.0.jar C:\Users\nemes\Documents\GitHub\Murakami_kiev\MurakamiKiev\obj\x86\Debug\__library_projects__\Square.Picasso\library_project_imports\picasso-2.5.2.jar C:\Users\nemes\Documents\GitHub\Murakami_kiev\MurakamiKiev\obj\x86\Debug\__library_projects__\UrlImageViewHelper\library_project_imports\bin\classes.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.Animated.Vector.Drawable\23.3.0.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.v4\23.3.0.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.v4\23.3.0.0\embedded\libs\internal_impl-23.3.0.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.v7.AppCompat\23.3.0.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.v7.MediaRouter\23.3.0.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.v7.MediaRouter\23.3.0.0\embedded\libs\internal_impl-23.3.0.jar C:\Users\nemes\AppData\Local\Xamarin\Android.Support.Vector.Drawable\23.3.0.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\GooglePlayServices.Analytics\8.4.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\GooglePlayServices.Base\8.4.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\GooglePlayServices.Basement\8.4.0\embedded\classes.jar C:\Users\nemes\AppData\Local\Xamarin\GooglePlayServices.Maps\8.4.0\embedded\classes.jar' MurakamiKiev
My Heap size is set to 1G
Any answers how I can launch Repl?????
Look into adding platform specification for initializer
[TestFixture(Platform.Android)]
public class Tests
{
IApp app;
Platform platform;
public Tests(Platform platform)
{
this.platform = platform;
}
[SetUp]
public void BeforeEachTest()
{
app = AppInitializer.StartApp(platform);
}
[Test]
public void AppLaunches()
{
app.Repl();
}
}
Also I've noticed you have your project in Release mode - put it to Debug.

Categories