Xamarin.Forms에서 절전 모드로 전환하지 않기 위해

Xamarin.Forms 재미 있습니다. 여기 최근 매일 만지고 있습니다.

요 전날부터 타이머 앱을 만들고 있었고, 거기서 어떤 현상에 부딪혔습니다.
  • 타이머가 시작되는 동안 화면이 절전 모드로 전환됩니다.

    슬립 상태가 되면 당연히 타이머는 멈춥니다.
    그런 앱은 타이머 앱이 아닙니다. 곤란했습니다.

    타이머 기동중에 방치해도 슬립 상태로 시키지 않기 위해서 설정을 해 갑니다.

    PCL



    이번에는 슬립하지 않는 모드와 슬립하는 모드를 메소드 호출하여 전환할 수 있도록 만들고 싶습니다.
    잠자기 설정은 iOS나 Android측에 쓰게 되므로, 그들을 호출하는 interface를 만들어 줍니다.

    Timer/Interfaces/ISleepScreen.cs
    public interface ISleepScreen
    {
        void SleepDisabled();
    
        void SleepEnabled();
    }
    

    iOS



    iOS의 경우 UIApplication.SharedApplication.IdleTimerDisabled를 변경하여 실현 가능하다고 합니다.true 에서 잠자기 상태가 되고 false 로 잠자기 상태입니다.

    Timer.iOS/SleepScreen.cs
    using UIKit;
    
    [assembly: Dependency(typeof(SleepScreen))]
    namespace Timer.iOS
    {
        public class SleepScreen : ISleepScreen
        {
            public void SleepDisabled()
            {
                UIApplication.SharedApplication.IdleTimerDisabled = true;
            }
    
            public void SleepEnabled()
            {
                UIApplication.SharedApplication.IdleTimerDisabled = false;
            }
        }
    }
    

    안드로이드


    OnCreate 에서 Window.AddFlags(WindowManagerFlags.KeepScreenOn); 하면 슬립을 억제할 수 있는 것 같습니다.

    Timer.Android/MainActivity.cs
    namespace Timer.Droid
    {
        [Activity(Label = "Timer", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
        public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            protected override void OnCreate(Bundle bundle)
            {
                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;
    
                base.OnCreate(bundle);
    
                global::Xamarin.Forms.Forms.Init(this, bundle);
                LoadApplication(new App());
    
                Window.AddFlags(WindowManagerFlags.KeepScreenOn); 
            }
        }
    }
    

    수면 억제를 메소드 호출로 관리 할 수 ​​없습니까?



    할 수 없다.
    하지만 조사했는데 아무래도 비추천인 것 같다.
    http://monobook.org/wiki/Xamarin.Android/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4 %E3%82%92%E3%82%B9%E3%83%AA%E3%83%BC%E3%83%97%E3%81%95%E3%81%9B%E3%81%AA%E3 %81%84

    해결책: wakelock
    이 방법은 권한이 필요하며, 일단 디스플레이의 수면을 억제하면 활동이 전환되지만 무엇을 하든 명시 적으로 해제하지 않는 한 연장 억제됩니다. 별로 추천할 수 없다. 따라서 생략한다.

    하지만 제어하고 싶다.


    wakelock 를 조금 조사해 보았다.
    htps : //에서 ゔぇぺぺr. 마린. 코 m/아피/tyぺ/안 d로이 d. 오 S. 포우 r 마나게 r /
    htps : //에서 ゔぇぺぺr. 마린. 코 m/아피/tyぺ/안 d로이 d. 오 S. 포우 r 마나게 r + わぉ CK /
    htps : //에서 ゔぇぺぺr. 마린. 코 m/아피/메 m베r/안 d로이 d. 오 S. Pou r 마나게 r. 네 ぉ ck/p/안 d로이 d. 오 S.ぉ ckFぁgs/Sys m. St 링 g/
    wekelocknewWakeLock 로 만들면, acqure()release() 를 할 필요가 있는 것 같다.GetSystemService 가 어디에 있는지 처음 모르게 고생했습니다.

    Timer.Android/SleepScreen.cs
    using Android.OS;
    using Android.Content;
    using Xamarin.Forms;
    
    [assembly: Dependency(typeof(SleepScreen))]
    namespace Timer.Droid
    {
        public class SleepScreen : ISleepScreen
        {
            PowerManager.WakeLock wl;
            public void SleepDisabled()
            {
                if (wl != null) return;
                PowerManager pm = (PowerManager)(Forms.Context.GetSystemService(Context.PowerService));
                wl = pm.NewWakeLock(WakeLockFlags.ScreenBright | WakeLockFlags.OnAfterRelease, "My Tag");
    
                wl.Acquire();
            }
    
            public void SleepEnabled()
            {
                if (wl != null) 
                {
                    wl.Release();
                    wl = null;
                }
            }
        }
    }
    
    Acqure()Release() 를 다른 메소드로 호출하는 이상 동일한 인스턴스를 계속 사용해야 합니다.DependencyService.Get<T>() 로 호출할 때는 다음과 같이 옵션을 붙이자.
    DependencyService.Get<ISleepScreen>(DependencyFetchTarget.GlobalInstance).SleepDisabled();
    
    DependencyService.Get<ISleepScreen>(DependencyFetchTarget.GlobalInstance).SleepEnabled();
    
    DependencyFetchTarget.GlobalInstance 를 지정하여 동일한 인스턴스에서 검색할 수 있습니다.
    htps : //에서 ゔぇぺぺr. 마린. 코m/아피/tyぺ/ぁ마린. 후 rms. 데 펜덴 cy 훗 tch r t /

    또한 wakelock을 사용하려면 권한이 필요합니다.Timer.Android/Properties/AndroidManifest.xml 로 권한을 부여할 수 있습니다.必要なアクセス許可 에서 WakeLock 를 지정합시다.


    이제 SleepDisabled()SleepEnabled() 에서 슬립 상태를 제어할 수 있습니다.

    결론



    iOS는 괜찮습니다. 안드로이드가 어쩐지 까다 롭습니다.Acquire() 를 호출하면 Release() 도 호출할 필요가 있으므로, 물론 생각하면 솔직하게 wakelock 가 아니라 KeepScreenOn 를 사용하는 것이 좋은 것 같은 느낌도 합니다. 어떻게 하는 것이 정답인지는 잘 모릅니다.
    이번과 같은 형태로 대응할 수 있는 것을 알았으므로, 필요할 때는 이렇게 구현하기로 합니다.

    내일은 kmy72입니다. 잘 부탁드립니다.
  • 좋은 웹페이지 즐겨찾기