1import MusicQueue from '@/common/musicQueue'; 2import MusicSheet from '@/common/musicSheetManager'; 3import {check, PERMISSIONS, request} from 'react-native-permissions'; 4import TrackPlayer, {Capability} from 'react-native-track-player'; 5import {pluginManager} from '../common/pluginManager'; 6import 'react-native-get-random-values'; 7import {Platform, ToastAndroid} from 'react-native'; 8import {loadConfig} from '@/common/localConfigManager'; 9import RNBootSplash from 'react-native-bootsplash'; 10import RNFS, {exists, mkdir} from 'react-native-fs'; 11import DownloadManager from '@/common/downloadManager'; 12import pathConst from '@/constants/pathConst'; 13import {checkAndCreateDir} from '@/utils/fileUtils'; 14import {errorLog} from '@/common/logManager'; 15import MediaMetaManager from '@/common/mediaMetaManager'; 16 17/** app加载前执行 */ 18async function _bootstrap() { 19 // 检查权限 20 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 21 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 22 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 23 ]); 24 if ( 25 !( 26 readStoragePermission === 'granted' && 27 writeStoragePermission === 'granted' 28 ) 29 ) { 30 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 31 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 32 } 33 34 /** 初始化路径 */ 35 await setupFolder(); 36 // 加载配置 37 await loadConfig(); 38 // 加载插件 39 try { 40 await TrackPlayer.setupPlayer(); 41 } catch (e: any) { 42 if ( 43 e?.message !== 'The player has already been initialized via setupPlayer.' 44 ) { 45 throw e; 46 } 47 } 48 49 Promise.all([ 50 await pluginManager.setupPlugins(), 51 await MediaMetaManager.setupMediaMeta(), 52 ]); 53 await TrackPlayer.updateOptions({ 54 progressUpdateEventInterval: 0.4, 55 stopWithApp: false, 56 alwaysPauseOnInterruption: true, 57 capabilities: [ 58 Capability.Play, 59 Capability.Pause, 60 Capability.SkipToNext, 61 Capability.SkipToPrevious, 62 ], 63 compactCapabilities: [ 64 Capability.Play, 65 Capability.Pause, 66 Capability.SkipToNext, 67 Capability.SkipToPrevious, 68 ], 69 notificationCapabilities: [ 70 Capability.Play, 71 Capability.Pause, 72 Capability.SkipToNext, 73 Capability.SkipToPrevious, 74 ], 75 }); 76 await MusicQueue.setupMusicQueue(); 77 await MusicSheet.setupMusicSheet(); 78 await DownloadManager.setupDownload(); 79 80 ErrorUtils.setGlobalHandler(error => { 81 errorLog('未捕获的错误', error); 82 }); 83} 84 85/** 初始化 */ 86async function setupFolder() { 87 await Promise.all([ 88 checkAndCreateDir(pathConst.dataPath), 89 checkAndCreateDir(pathConst.logPath), 90 checkAndCreateDir(pathConst.cachePath), 91 checkAndCreateDir(pathConst.storagePath), 92 checkAndCreateDir(pathConst.pluginPath), 93 checkAndCreateDir(pathConst.lrcCachePath), 94 ]); 95} 96 97export default async function () { 98 try { 99 await _bootstrap(); 100 } catch (e) { 101 errorLog('初始化出错', e); 102 console.log(e); 103 } 104 // 隐藏开屏动画 105 console.log('HIDE'); 106 RNBootSplash.hide({fade: true}); 107} 108