Search code examples
c#xamarinxamarin.androidxamarin.ios

Xamarin: Block sleep mode while running a process


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?


Solution

  • 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:

    1. In the AndroidManifest.xml file, add this permission:
        <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    1. 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.

    2. 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);
                    }
                });
            }
        }
    }
    
    1. 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