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

React Native Track Player在Android上无法显示迷你播放控件(通知/锁屏播放器)

React Native Track Player在Android上无法显示迷你播放控件(通知/锁屏播放器)

看起来你已经把基础播放功能跑通了,但Android的锁屏/通知栏迷你播放器没出来,我结合你的代码帮你排查几个常见的坑:

1. 缺失Android 13+ 通知权限(必加)

你用的Android 15属于Android 13+,系统要求必须明确申请POST_NOTIFICATIONS权限才能显示播放类通知,你的代码里完全没处理这个:

  • 第一步在app.json里添加权限配置:
{
  "expo": {
    "android": {
      "permissions": ["POST_NOTIFICATIONS"]
    }
  }
}
  • 然后在AudioPage的初始化逻辑里主动申请权限:
// 先导入需要的模块
import { Platform, PermissionsAndroid } from 'react-native';

async function initTrackPlayer() {
  console.log("setup player");
  // Android 13+ 申请通知权限
  if (Platform.OS === 'android' && Platform.Version >= 33) {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
    );
    if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
      console.log("通知权限被拒绝,无法显示播放通知");
      return;
    }
  }
  // 后续的setupPlayer和updateOptions逻辑...
}

2. 未导入AppKilledPlaybackBehavior枚举

你的updateOptions里用了AppKilledPlaybackBehavior.PausePlayback,但代码里完全没从react-native-track-player导入这个枚举!这会导致代码静默报错,进而让updateOptions执行失败,通知控件自然出不来:

// 修改AudioPage的导入语句
import TrackPlayer, { AppKilledPlaybackBehavior } from "react-native-track-player";

3. 补充通知控件的关键配置

你的updateOptions里的权限配置不全,补充几个让通知正常显示的参数:

TrackPlayer.updateOptions({
  android: {
    appKilledPlaybackBehavior: AppKilledPlaybackBehavior.PausePlayback,
    notificationColor: "#000000", // 匹配你的App深色主题
    alwaysOnNotification: true, // 确保播放时通知常驻
  },
  capabilities: [
    TrackPlayer.CAPABILITY_PLAY,
    TrackPlayer.CAPABILITY_PAUSE,
    TrackPlayer.CAPABILITY_STOP,
  ],
  compactCapabilities: [
    TrackPlayer.CAPABILITY_PLAY,
    TrackPlayer.CAPABILITY_PAUSE,
    TrackPlayer.CAPABILITY_STOP,
  ],
  notificationCapabilities: [
    TrackPlayer.CAPABILITY_PLAY,
    TrackPlayer.CAPABILITY_PAUSE,
    TrackPlayer.CAPABILITY_STOP,
  ],
});

4. 修复轨道添加和初始化的细节问题

  • 本地资源的url建议显式取uri属性,避免部分版本的track-player解析失败
  • 播放前先重置播放器,避免重复添加轨道
  • 所有异步操作加错误捕获,方便排查问题:
async function play() {
  try {
    const track = {
      url: require("../../assets/test.mp3").uri,
      title: "Test",
      artwork: require("../../assets/icon.png").uri,
      duration: 29,
    };
    await TrackPlayer.reset(); // 先清空之前的轨道
    await TrackPlayer.add([track]);
    await TrackPlayer.play(); // 这里必须加await
  } catch (e) {
    console.error("播放失败:", e);
  }
}

5. 确认PlaybackService正常启动

在你的PlaybackService.js里加个启动日志,确认服务正常注册:

export default async () => {
  console.log("Playback Service 已启动"); // 加这个日志验证
  TrackPlayer.addEventListener(Event.RemotePlay, () => TrackPlayer.play());
  TrackPlayer.addEventListener(Event.RemotePause, () => TrackPlayer.pause());
  TrackPlayer.addEventListener(Event.RemoteStop, () => TrackPlayer.stop());
};

额外的代码优化建议(满足你的code review需求)

  • 用useRef标记播放器是否已初始化,避免组件重渲染时重复执行初始化:
import { useRef } from 'react';

const AudioPage = () => {
  const isPlayerInitialized = useRef(false);
  useEffect(() => {
    if (!isPlayerInitialized.current) {
      initTrackPlayer();
      isPlayerInitialized.current = true;
    }
  }, []);
  // ...其他逻辑
}
  • 所有TrackPlayer的异步操作都要加await和try/catch,不然出问题很难定位
  • 可以给TouchableOpacity加个禁用状态,避免用户重复点击播放按钮

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:52:59