Skip to page content

App Wake Lock
v2.34+

菜谱页、登机牌、演示文稿、导航界面:有些画面即便用户没有触碰设备,也必须保持常亮。AppWakeLock 插件封装了 Screen Wake Lock API,只需一次 request() 就能让屏幕在你希望的时长内保持唤醒,而 release() 则会让设备恢复到正常的熄屏超时行为。

用法

Outside of a Vue file

import { AppWakeLock } from 'quasar'

// Keep the screen awake:
AppWakeLock.request()
  .then(() => {
    // success!
  })
  .catch(err => {
    // page hidden, battery saver, or not capable
  })

// Let the screen turn off again:
AppWakeLock.release()
Inside of a Vue file

import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()

  $q.wakeLock.request()
    .then(() => {
      // success!
    })
    .catch(err => {
      // page hidden, battery saver, or not capable
    })

  // ...later
  $q.wakeLock.release()
}

下面这个示例演示了如何通过一个开关来请求和释放屏幕唤醒锁,并实时展示锁的当前状态:

<template>
  <div class="q-pa-md">
    <div v-if="$q.wakeLock.isCapable">
      <q-toggle
        v-model="keepAwake"
        label="Keep the screen awake"
        @update:model-value="onToggle"
      />

      <div class="q-mt-sm"> Lock held: {{ $q.wakeLock.isActive }} </div>

      <div class="q-mt-sm text-caption">
        Switch to another tab or app and come back: the browser drops the lock
        while the page is hidden and the plugin re-acquires it.
      </div>
    </div>

    <div v-else> This browser does not support the Screen Wake Lock API. </div>
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'
import { ref, watch } from 'vue'

const $q = useQuasar()
const keepAwake = ref(false)

function onToggle(val) {
  const promise = val ? $q.wakeLock.request() : $q.wakeLock.release()

  promise.catch(err => {
    keepAwake.value = false
    $q.notify({
      type: 'negative',
      message: `Wake lock ${val ? 'request' : 'release'} failed: ${err.message}`
    })
  })
}

// the plugin keeps re-acquiring the lock until release() is called,
// so this is only a mirror of what the toggle asked for
watch(
  () => $q.wakeLock.isActive,
  val => {
    if (val) keepAwake.value = true
  }
)
</script>

浏览器会自行释放锁

屏幕唤醒锁只在页面处于可见状态时存活。一旦用户切换标签页、最小化浏览器或锁屏,浏览器就会释放该锁,isActive 随之变为 false。插件会记住你曾请求过这把锁,并在页面重新变为可见的那一刻自动再次申请,直到你调用 release() 为止。你这边无需做任何额外接线:一个组件所需的全部,就是挂载时调用一次 request()、卸载时调用一次 release()。

<template>...</template>

<script setup>
  import { useQuasar } from 'quasar'
  import { onBeforeUnmount } from 'vue'

  const $q = useQuasar()

  $q.wakeLock.request().catch(() => {
    // not available; the page still works, the screen just times out
  })

  onBeforeUnmount(() => {
    $q.wakeLock.release()
  })
</script>

isActive 始终反映真实状态:只有在锁确实被持有时它才为 true。如果你的界面要展示当前状态,就监听它。

当请求被拒绝时

当页面处于隐藏状态、设备开启了省电模式,或者某个 screen-wake-lock 的 权限策略(Permissions Policy) 禁止它时(这在你的应用运行于 iframe 内时尤为相关),浏览器会以 NotAllowedError 拒绝 request()。请把这类拒绝当作一次「软失败」来处理:屏幕的行为与它一贯的表现无异。

浏览器支持

Screen Wake Lock API 需要安全上下文(HTTPS 或 localhost),可在基于 Chromium 的浏览器、Safari 16.4+ 以及 Firefox 126+ 中使用。在展示「保持屏幕常亮」这类控件之前,请先检查 $q.wakeLock.isCapable;在它为 false 的地方,相关方法会以 Not capable 错误拒绝。

混合应用(Hybrid apps)

在当前平台上,该 API 可在 Capacitor 和 Cordova 使用的 WebView 内正常工作,因此本插件依然是 Web、PWA 与混合构建三者共用的统一方案。如果你需要不受 WebView 支持情况限制、无论如何都让屏幕常亮,那么这些平台各自的原生 keep-awake 插件就是兜底选择。

SSR 与 SSG

服务端没有屏幕,因此在那里 isCapable 和 isActive 都为 false,相关方法会直接 resolve 而不做任何事。在客户端,isCapable 只有在 hydration 完成之后才会取得它真实的值,这可以避免依赖它的标记(例如包裹你的开关的 v-if)与服务端渲染结果产生不一致。