保持设备唤醒

为了避免耗尽电池电量,处于空闲状态的 Android 设备会很快进入睡眠状态。但是,有时应用程序需要唤醒屏幕或 CPU 并保持唤醒状态以完成一些工作。

您采用的方法取决于应用程序的需求。但是,一般经验法则是,您应该对应用程序使用最轻量级的方法,以最大程度地减少应用程序对系统资源的影响。以下部分介绍了如何处理设备的默认睡眠行为与应用程序要求不兼容的情况。

使用唤醒锁的替代方案

在向应用程序添加唤醒锁支持之前,请考虑应用程序的用例是否支持以下替代解决方案之一

  • 如果应用程序正在执行长时间运行的 HTTP 下载,请考虑使用 DownloadManager.

  • 如果应用程序正在从外部服务器同步数据,请考虑创建一个 同步适配器.

  • 如果应用程序依赖于后台服务,请考虑使用 JobSchedulerFirebase 云消息传递 以特定间隔触发这些服务。

  • 如果您需要在伴侣设备在范围内时保持伴侣应用程序运行,请使用 伴侣设备管理器.

保持屏幕开启

某些应用程序需要保持屏幕开启,例如游戏或电影应用程序。最好的方法是在活动中使用 FLAG_KEEP_SCREEN_ON(并且只在活动中使用,不要在服务或其他应用程序组件中使用)。例如

Kotlin

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    }
}

Java

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  }
}

这种方法的优点是,与唤醒锁(在 保持 CPU 开启 中讨论)不同,它不需要特殊权限,并且平台会正确管理用户在应用程序之间的移动,而无需应用程序担心释放未使用的资源。

另一种实现方法是在应用程序的布局 XML 文件中使用 android:keepScreenOn 属性

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">
    ...
</RelativeLayout>

使用 android:keepScreenOn="true" 等同于使用 FLAG_KEEP_SCREEN_ON。您可以根据应用程序选择最适合的方法。在活动中以编程方式设置标志的优点是,它使您能够稍后以编程方式清除标志,从而允许屏幕关闭。

适用于 TV 的环境模式

在 TV 上,应使用 FLAG_KEEP_SCREEN_ON 来防止设备在活动视频播放期间进入 环境模式。如果前台活动未设置 FLAG_KEEP_SCREEN_ON,则设备将在一段时间不活动后自动进入环境模式。

保持 CPU 开启

如果您需要保持 CPU 运行以在设备进入睡眠状态之前完成一些工作,您可以使用 PowerManager 系统服务功能,称为唤醒锁。唤醒锁允许应用程序控制主机设备的电源状态。

创建和持有唤醒锁会对主机设备的电池寿命产生重大影响。因此,您应该仅在绝对必要时使用唤醒锁,并尽可能缩短持有时间。例如,您绝不应该在 Activity 中使用唤醒锁。如上所述,如果您想在 Activity 中保持屏幕开启,请使用 FLAG_KEEP_SCREEN_ON

使用唤醒锁的一个合法案例可能是后台服务需要获取唤醒锁来保持 CPU 运行以在屏幕关闭时执行工作。但是,由于对电池寿命的影响,这种做法应该尽量减少。

要使用唤醒锁,第一步是在应用程序的清单文件中添加 WAKE_LOCK 权限

<uses-permission android:name="android.permission.WAKE_LOCK" />

如果您的应用程序包含使用服务来执行某些工作的广播接收器,以下是您直接设置唤醒锁的方法

Kotlin

val wakeLock: PowerManager.WakeLock =
        (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
            newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag").apply {
                acquire()
            }
        }

Java

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
        "MyApp::MyWakelockTag");
wakeLock.acquire();

要释放唤醒锁,请调用 wakelock.release()。这将释放您对 CPU 的权利。在您的应用程序完成使用唤醒锁后尽快释放它非常重要,以避免耗尽电池。