移动端息屏控制

息屏控制

UE 中封装了通用的接口来控制,可以使用以下函数:

1
UKismetSystemLibrary::ControlScreensaver(false);

它会调用到对应平台的 F*ApplicationMisc 中的同名函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// for Android
bool FAndroidApplicationMisc::ControlScreensaver(EScreenSaverAction Action)
{
#if USE_ANDROID_JNI
extern void AndroidThunkCpp_KeepScreenOn(bool Enable);
switch (Action)
{
case EScreenSaverAction::Disable:
// Prevent display sleep.
AndroidThunkCpp_KeepScreenOn(true);
break;

case EScreenSaverAction::Enable:
// Stop preventing display sleep now that we are done.
AndroidThunkCpp_KeepScreenOn(false);
break;
}
return true;
#else
return false;
#endif
}

// for IOS
bool FIOSPlatformApplicationMisc::ControlScreensaver(EScreenSaverAction Action)
{
IOSAppDelegate* AppDelegate = [IOSAppDelegate GetDelegate];
[AppDelegate EnableIdleTimer : (Action == FGenericPlatformApplicationMisc::Enable)];
return true;
}

Android

在 UE 的 GameActivity.java.template 文件中有以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public void AndroidThunkJava_KeepScreenOn(boolean Enable)
{
bKeepScreenOn = Enable;
if (Enable)
{
_activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
Log.debug("==============> [JAVA] AndroidThunkJava_KeepScreenOn(true) - Disabled screen saver");
_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
else
{
_activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
Log.debug("==============> [JAVA] AndroidThunkJava_KeepScreenOn(false) - Enabled screen saver");
_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
}

在 GameActivity 的 OnResume 函数中会调用,是否开启的值为bKeepScreenOn

可以通过 UPL、或者运行时的 JNI 调用来控制 Android 是否息屏。

1
2
3
4
5
<gameActivityOnCreateFinalAdditions>
<insert>
AndroidThunkJava_KeepScreenOn(true);
</insert>
</gameActivityOnCreateFinalAdditions>

IOS

在引擎中有由下代码控制:

Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp
1
2
3
4
5
6
7
8
9
10
-(void)InitIdleTimerSettings
{
float TimerDuration = 0.0F;
GConfig->GetFloat(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("IdleTimerEnablePeriod"), TimerDuration, GEngineIni);
IdleTimerEnablePeriod = TimerDuration;
self.IdleTimerEnableTimer = nil;
bool bEnableTimer = YES;
GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bEnableIdleTimer"), bEnableTimer, GEngineIni);
[self EnableIdleTimer : bEnableTimer];
}

可以从 GEngineIni 中读取两个配置:

1
2
3
[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
IdleTimerEnablePeriod=0.0
bEnableIdleTimer=true

bEnableIdleTimer=false,在游戏运行时就不会息屏。

运行时设置需要调用 OC 的代码:

Runtime\ApplicationCore\Private\IOS\IOSAppDelegate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-(void)EnableIdleTimer:(bool)bEnabled
{
dispatch_async(dispatch_get_main_queue(),^
{
if (bEnabled)
{
// Nothing needs to be done, if the enable timer is already running.
if (self.IdleTimerEnableTimer == nil)
{
self.IdleTimerEnableTimer = [NSTimer scheduledTimerWithTimeInterval:IdleTimerEnablePeriod target:self selector:@selector(DeferredEnableIdleTimer) userInfo:nil repeats:NO];
}
}
else
{
// Ensure pending attempts to enable the idle timer are cancelled.
if (self.IdleTimerEnableTimer != nil)
{
[self.IdleTimerEnableTimer invalidate];
self.IdleTimerEnableTimer = nil;
}

[UIApplication sharedApplication].idleTimerDisabled = NO;
[UIApplication sharedApplication].idleTimerDisabled = YES;
}
});
}

调用 EnableIdleTimer 传入 false 会关闭游戏运行时息屏。