.NET for Androidでディスプレイをスリープさせない
概要 編集
無操作でもディスプレイをスリープさせたくない場面も多い。 たとえばMonoGameで作るAndroid向けのゲームなどである。
環境 編集
- Xamarin.Android
- .NET for Android
Xamarin.Androidの頃から変わっていない。
解決策:KeepScreenOn 編集
アクティビティに「WindowManagerFlags.KeepScreenOn」というフラグを設定すると一時的にディスプレイのスリープを抑制できます。この方法は
- 権限が不要であり
- アクティビティが遷移する際に自動的に解除されます
public class MainActivity : Activity
{
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
// 画面をオフにしない。
this.Window!.AddFlags(Android.Views.WindowManagerFlags.KeepScreenOn);
}
}
MonoGameでもこの方法は有効です。
public class Activity1 : AndroidGameActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// ディスプレイをスリープさせない
this.Window.AddFlags(WindowManagerFlags.KeepScreenOn);
}
}
解決策:wakelock 編集
WakeLockを使う方法は、権限が必要であり、ひとたびディスプレイのスリープを抑制するとアクティビティが遷移しようが何をしようが明示的に解除しない限り延々とスリープが抑制されます。
当然のように素人にはオススメできない代物です。
- 必要な権限
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- 大雑把なソース
どうしても使いたい場合はWakeLock利用中のあらゆる暴走をtry/catchして確実にReleaseしてください。 メモリ不足などの「アプリ外の影響」「OSの暴走」も想定しましょう。
PowerManager? _powerManager;
PowerManager.WakeLock? _wakelock;
void Initialize()
{
_powerManager = GetSystemService(Context.PowerService) as PowerManager;
_wakelock = _powerManager?.NewWakeLock(WakeLockFlags.Full, "tag")!;
}
void Start()
{
if (_wakelock != null)
{
_wakelock.Acquire();
}
}
void Stop()
{
if (_wakelock != null && _wakelock.IsHeld)
{
_wakelock.Release();
}
}
void Release()
{
if (_wakelock != null)
{
if (_wakelock.IsHeld)
{
_wakelock.Release();
}
_wakelock.Dispose();
_wakelock = null;
}
}