9

I am using a portable project so do not have direct access to native code.

I have an interface in my project that allows me to access native objects in the Android/iOS projects. We use this primarily for playing audio.

Android, for example, has things like

Window w = new Window();
w.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.KeepScreenOn);

However the main issue would be accessing a Window object. I could pass a Xamarin.Forms.Page object to the native code, but there would be no way (I don't think) to cast it to a native Android Window object to access the flags.

Is there a way to do this with a portable project?

sosil
  • 369
  • 4
  • 12

3 Answers3

18

You can't do this without platform specific services or renderers. A portable project will have to call platform specific code in order to achieve this.

From that platform specific code, either as a DependencyService or Renderer, you can access the Window object through the Forms.Context. The Forms.Context is your Android Activity, through which you can reach the Window object.

On Android it works like this:

Android.Views.Window window = (Forms.Context as Activity).Window;
window.SetFlags(WindowManagerFlags.KeepScreenOn);

On iOS you can try this (Apple docs):

UIApplication.SharedApplication.IdleTimerDisabled = true;
Tim Klingeleers
  • 2,834
  • 14
  • 20
  • Great, that seems to work perfectly! I suppose I should have asked about both... Any idea how this is done on iOS? Just a note, `window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.KeepScreenOn);` didn't seem to work, but `window.AddFlags(WindowManagerFlags.KeepScreenOn);` does work well – sosil May 01 '17 at 13:44
  • Oh, you are right, didn't notice that. I've updated the answer for iOS and fixed the Android version. – Tim Klingeleers May 01 '17 at 13:49
  • Ah ok, I was just giving that a shot right now, I'll let you know if it works – sosil May 01 '17 at 14:08
  • 1
    In Android now I get 'Forms.Context' is obsolete: 'Context is obsolete as of version 2.5. Please use a local context instead.' How do I have to do this without Forms.Context – Kees Dapperens May 10 '18 at 22:32
  • @KeesDapperens: You could use [this solution](https://stackoverflow.com/a/56523482/426227) for `DependencyService`. In a `Renderer` there is a `Context` parameter in the constructor. I used the `DependencyService` because with the `Renderer` changing back to the defaults (screen lock is on again) never happened. – testing Dec 14 '21 at 17:41
5

Now there is a plugin doing exactly what Tim wrote

https://learn.microsoft.com/en-us/xamarin/essentials/screen-lock

simple source code is here

https://github.com/xamarin/Essentials/blob/main/Samples/Samples/ViewModel/KeepScreenOnViewModel.cs

using System.Windows.Input; using Xamarin.Essentials; using Xamarin.Forms;

namespace Samples.ViewModel
{
    public class KeepScreenOnViewModel : BaseViewModel
    {
        public KeepScreenOnViewModel()
        {
            RequestActiveCommand = new Command(OnRequestActive);
            RequestReleaseCommand = new Command(OnRequestRelease);
        }

        public bool IsActive => DeviceDisplay.KeepScreenOn;

        public ICommand RequestActiveCommand { get; }

        public ICommand RequestReleaseCommand { get; }

        void OnRequestActive()
        {
            DeviceDisplay.KeepScreenOn = true;

            OnPropertyChanged(nameof(IsActive));
        }

        void OnRequestRelease()
        {
            DeviceDisplay.KeepScreenOn = false;

            OnPropertyChanged(nameof(IsActive));
        }
    }
}
Emil
  • 6,411
  • 7
  • 62
  • 112
0

For Xamarin Forms Android. Renders file I included below code

Window window = (Forms.Context as Activity).Window;
window.AddFlags(WindowManagerFlags.KeepScreenOn);
Kairat Koibagarov
  • 1,385
  • 15
  • 9