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

如何使用React Native Expo自动检测耳机连接状态

React Native Expo 实现仅耳机连接时播放MP3方案

针对公司资产MP3文件的播放安全需求,以下是具体实现方案:

1. 耳机连接状态监听

使用Expo官方的expo-av模块实现耳机状态检测,该模块提供了监听音频路由变化的API,能准确捕捉耳机连接/断开事件。

核心代码示例:

import { Audio } from 'expo-av';
import { useEffect } from 'react';

// 初始化耳机状态监听
let audioRouteSubscription;

const setupHeadphoneDetection = async () => {
  // 获取当前音频路由状态
  const currentRoute = await Audio.getAudioRouteAsync();
  const isHeadphonesConnected = currentRoute.includes('headphones');
  
  // 监听路由变化,断开时暂停播放
  audioRouteSubscription = Audio.addAudioRouteChangeListener((route) => {
    if (!route.includes('headphones')) {
      pauseAudio();
    }
  });
  
  return isHeadphonesConnected;
};

// 组件挂载时初始化监听,卸载时清理
useEffect(() => {
  setupHeadphoneDetection();
  return () => {
    audioRouteSubscription && Audio.removeAudioRouteChangeListener(audioRouteSubscription);
  };
}, []);

2. 播放权限控制

在播放MP3前强制检查耳机连接状态,未连接时禁止播放并提示用户:

const playAudio = async (audioUri) => {
  const isHeadphonesConnected = await Audio.getAudioRouteAsync().then(route => route.includes('headphones'));
  
  if (!isHeadphonesConnected) {
    alert('请连接耳机后播放音频');
    return;
  }
  
  // 初始化播放器并启动播放
  const { sound } = await Audio.Sound.createAsync({ uri: audioUri });
  await sound.playAsync();
};

3. 额外安全加固措施

  • 禁用录音权限:在app.json中移除录音权限配置,降低外部应用录制风险:
    "ios": {
      "infoPlist": {
        "NSMicrophoneUsageDescription": ""
      }
    },
    "android": {
      "permissions": []
    }
    
  • 加密MP3文件:对公司资产MP3进行AES加密,播放时在内存中解密后再播放,防止文件被直接提取。
  • 强制耳机输出:部分设备支持强制音频仅通过耳机播放,可添加如下配置:
    await Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      playsInSilentModeIOS: true,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
      playThroughEarpieceAndroid: true
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:45:02