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