You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何检测手机屏幕的开启/关闭状态?

准确判断移动设备屏幕状态的解决方案

针对你开发专注应用时遇到的「AppState无法区分应用切换和屏幕关闭」的问题,以下是分平台的原生实现方案(React Native无直接内置API,需通过原生模块扩展):

iOS 端实现

iOS可通过监听系统通知结合保护数据状态来区分屏幕锁定与应用切换:

  • 注册监听UIApplicationDidEnterBackgroundNotification和UIApplicationWillEnterForegroundNotification
  • 当应用进入后台时,检查UIApplication.shared.isProtectedDataAvailable:
    • 返回false:说明设备屏幕已锁定(关闭)
    • 返回true:说明用户切换到了其他应用
  • 将状态通过原生模块桥接给React Native JS层,可导出查询方法或发送事件通知。

示例原生代码片段(Objective-C):

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface ScreenStateManager : RCTEventEmitter <RCTBridgeModule>
@end

@implementation ScreenStateManager

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents {
  return @[@"screenLocked", @"screenUnlocked"];
}

- (void)startObserving {
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(onAppEnterBackground:)
                                               name:UIApplicationDidEnterBackgroundNotification
                                             object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(onAppEnterForeground:)
                                               name:UIApplicationWillEnterForegroundNotification
                                             object:nil];
}

- (void)stopObserving {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)onAppEnterBackground:(NSNotification *)notification {
  BOOL isLocked = ![[UIApplication sharedApplication] isProtectedDataAvailable];
  if (isLocked) {
    [self sendEventWithName:@"screenLocked" body:nil];
  }
}

- (void)onAppEnterForeground:(NSNotification *)notification {
  [self sendEventWithName:@"screenUnlocked" body:nil];
}

RCT_EXPORT_METHOD(getCurrentScreenLockedStatus:(RCTResponseSenderBlock)callback) {
  BOOL isLocked = ![[UIApplication sharedApplication] isProtectedDataAvailable];
  callback(@[@(isLocked)]);
}

@end

Android 端实现

Android通过广播接收器监听屏幕开关状态,结合AppState判断场景:

  • 创建广播接收器,监听Intent.ACTION_SCREEN_ON和Intent.ACTION_SCREEN_OFF系统广播
  • 收到广播时,向React Native JS层发送对应状态事件(screenOn/screenOff)
  • 在JS层结合AppState的background事件:当AppState变为background时,若此前收到过screenOff事件则为屏幕关闭,否则为应用切换。

示例原生代码片段(Kotlin):

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.modules.core.DeviceEventManagerModule

class ScreenStateModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    private val screenReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                Intent.ACTION_SCREEN_ON -> sendEvent("screenOn")
                Intent.ACTION_SCREEN_OFF -> sendEvent("screenOff")
            }
        }
    }

    override fun getName(): String = "ScreenStateModule"

    override fun initialize() {
        super.initialize()
        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_SCREEN_ON)
            addAction(Intent.ACTION_SCREEN_OFF)
        }
        reactApplicationContext.registerReceiver(screenReceiver, filter)
    }

    override fun onCatalystInstanceDestroy() {
        super.onCatalystInstanceDestroy()
        reactApplicationContext.unregisterReceiver(screenReceiver)
    }

    private fun sendEvent(eventName: String) {
        reactApplicationContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit(eventName, null)
    }

    @ReactMethod
    fun getCurrentScreenState(callback: (Boolean) -> Unit) {
        val powerManager = reactApplicationContext.getSystemService(Context.POWER_SERVICE) as android.os.PowerManager
        callback(powerManager.isInteractive)
    }
}

React Native JS 层整合

在JS层同时监听AppState和屏幕状态事件,实现逻辑判断:

import { AppState, NativeEventEmitter, NativeModules } from 'react-native';

const { ScreenStateModule } = NativeModules;
const screenStateEmitter = new NativeEventEmitter(ScreenStateModule);

let isScreenOff = false;

// 监听屏幕状态
screenStateEmitter.addListener('screenLocked', () => {
  isScreenOff = true;
});
screenStateEmitter.addListener('screenUnlocked', () => {
  isScreenOff = false;
});
screenStateEmitter.addListener('screenOn', () => {
  isScreenOff = false;
});
screenStateEmitter.addListener('screenOff', () => {
  isScreenOff = true;
});

// 监听AppState变化
AppState.addEventListener('change', (nextAppState) => {
  if (nextAppState === 'background') {
    if (isScreenOff) {
      // 处理屏幕关闭的情况,不判定为违规
      console.log('屏幕已关闭,允许');
    } else {
      // 处理切换到其他应用的情况,判定为违规
      console.log('切换到其他应用,触发专注提醒');
    }
  }
});

内容的提问来源于stack exchange,提问作者Hitul Nayakpara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:55:42