mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
更新外部存储路径获取方式
This commit is contained in:
parent
89a282ff56
commit
2fb4db83e6
@ -1,6 +1,11 @@
|
|||||||
package cn.toside.music.mobile.utils;
|
package cn.toside.music.mobile.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -8,6 +13,8 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
@ -26,6 +33,31 @@ public class Utils {
|
|||||||
return dir.delete();
|
return dir.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/PauloLuan/4bcecc086095bce28e22?permalink_comment_id=2591001#gistcomment-2591001
|
||||||
|
public static String getExternalStoragePath(ReactApplicationContext mContext, boolean is_removable) {
|
||||||
|
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
|
||||||
|
Class<?> storageVolumeClazz;
|
||||||
|
try {
|
||||||
|
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
|
||||||
|
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
|
||||||
|
Method getPath = storageVolumeClazz.getMethod("getPath");
|
||||||
|
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
|
||||||
|
Object result = getVolumeList.invoke(mStorageManager);
|
||||||
|
final int length = Array.getLength(result);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
Object storageVolumeElement = Array.get(result, i);
|
||||||
|
String path = (String) getPath.invoke(storageVolumeElement);
|
||||||
|
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
|
||||||
|
if (is_removable == removable) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static String convertStreamToString(InputStream is) throws Exception {
|
public static String convertStreamToString(InputStream is) throws Exception {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -395,5 +395,10 @@ public class UtilsModule extends ReactContextBaseJavaModule {
|
|||||||
public void requestIgnoreBatteryOptimization(Promise promise) {
|
public void requestIgnoreBatteryOptimization(Promise promise) {
|
||||||
promise.resolve(BatteryOptimizationUtil.requestIgnoreBatteryOptimization(reactContext.getApplicationContext(), reactContext.getPackageName()));
|
promise.resolve(BatteryOptimizationUtil.requestIgnoreBatteryOptimization(reactContext.getApplicationContext(), reactContext.getPackageName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void getExternalStoragePath(Promise promise) {
|
||||||
|
promise.resolve(Utils.getExternalStoragePath(reactContext, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
- 优化播放详情页歌曲封面、控制按钮对各尺寸屏幕的适配,修改横屏下的控制栏按钮布局
|
- 优化播放详情页歌曲封面、控制按钮对各尺寸屏幕的适配,修改横屏下的控制栏按钮布局
|
||||||
- 优化横竖屏界面的暂时判断,现在趋于方屏的屏幕按竖屏的方式显示,横屏下的播放栏添加上一曲切歌按钮
|
- 优化横竖屏界面的暂时判断,现在趋于方屏的屏幕按竖屏的方式显示,横屏下的播放栏添加上一曲切歌按钮
|
||||||
- 添加对wy源某些歌曲有问题的歌词进行修复(#370)
|
- 添加对wy源某些歌曲有问题的歌词进行修复(#370)
|
||||||
- 文件选择器允许(在旧系统)选择外置存储设备上的路径(`/storage`)
|
- 文件选择器允许(在旧系统)选择外置存储设备上的路径
|
||||||
- 图片显示改用第三方的图片组件,支持gif类型的图片显示,尝试解决某些设备上图片过多导致的应用崩溃问题
|
- 图片显示改用第三方的图片组件,支持gif类型的图片显示,尝试解决某些设备上图片过多导致的应用崩溃问题
|
||||||
- 歌曲评论内容过长时自动折叠,需手动展开
|
- 歌曲评论内容过长时自动折叠,需手动展开
|
||||||
- 改进本地音乐在线信息的匹配机制
|
- 改进本地音乐在线信息的匹配机制
|
||||||
|
@ -44,7 +44,7 @@ export default forwardRef<MetadataEditType, MetadataEditProps>((props, ref) => {
|
|||||||
readLyric(filePath),
|
readLyric(filePath),
|
||||||
]).then(([_metadata, pic, lyric]) => {
|
]).then(([_metadata, pic, lyric]) => {
|
||||||
if (!_metadata) return
|
if (!_metadata) return
|
||||||
if (isUnmounted) return
|
if (isUnmounted.current) return
|
||||||
metadata.current = {
|
metadata.current = {
|
||||||
name: _metadata.name,
|
name: _metadata.name,
|
||||||
singer: _metadata.singer,
|
singer: _metadata.singer,
|
||||||
|
@ -126,6 +126,7 @@ export default forwardRef<ListType, ListProps>(({
|
|||||||
// console.log('prevPath', prevPath)
|
// console.log('prevPath', prevPath)
|
||||||
// if (isReadingDir.current) return
|
// if (isReadingDir.current) return
|
||||||
// setPath(prevPath)
|
// setPath(prevPath)
|
||||||
|
throw err
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
isReadingDir.current = false
|
isReadingDir.current = false
|
||||||
})
|
})
|
||||||
@ -134,7 +135,7 @@ export default forwardRef<ListType, ListProps>(({
|
|||||||
const onSetPath = (pathInfo: PathItem) => {
|
const onSetPath = (pathInfo: PathItem) => {
|
||||||
// console.log('onSetPath')
|
// console.log('onSetPath')
|
||||||
if (pathInfo.isDir) {
|
if (pathInfo.isDir) {
|
||||||
void readDir(pathInfo.path, readOptions.current.dirOnly, readOptions.current.filter)
|
void readDir(pathInfo.path, readOptions.current.dirOnly, readOptions.current.filter).catch(_ => _)
|
||||||
} else {
|
} else {
|
||||||
onConfirm(pathInfo.path)
|
onConfirm(pathInfo.path)
|
||||||
// setPath(pathInfo.path)
|
// setPath(pathInfo.path)
|
||||||
@ -143,7 +144,9 @@ export default forwardRef<ListType, ListProps>(({
|
|||||||
|
|
||||||
const toParentDir = () => {
|
const toParentDir = () => {
|
||||||
const parentPath = path.substring(0, path.lastIndexOf('/'))
|
const parentPath = path.substring(0, path.lastIndexOf('/'))
|
||||||
void readDir(parentPath.length ? parentPath : externalStorageDirectoryPath, readOptions.current.dirOnly, readOptions.current.filter)
|
void readDir(parentPath.length ? parentPath : externalStorageDirectoryPath, readOptions.current.dirOnly, readOptions.current.filter).catch(() => {
|
||||||
|
void readDir(externalStorageDirectoryPath, readOptions.current.dirOnly, readOptions.current.filter).catch(_ => _)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleHide = () => {
|
const handleHide = () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
||||||
import { View, TouchableOpacity } from 'react-native'
|
import { View, TouchableOpacity } from 'react-native'
|
||||||
import Input, { type InputType } from '@/components/common/Input'
|
import Input, { type InputType } from '@/components/common/Input'
|
||||||
import Text from '@/components/common/Text'
|
import Text from '@/components/common/Text'
|
||||||
@ -9,6 +9,8 @@ import { createStyle, toast } from '@/utils/tools'
|
|||||||
import { mkdir, readDir } from '@/utils/fs'
|
import { mkdir, readDir } from '@/utils/fs'
|
||||||
import { useTheme } from '@/store/theme/hook'
|
import { useTheme } from '@/store/theme/hook'
|
||||||
import { scaleSizeH } from '@/utils/pixelRatio'
|
import { scaleSizeH } from '@/utils/pixelRatio'
|
||||||
|
import { getExternalStoragePath } from '@/utils/nativeModules/utils'
|
||||||
|
import { useUnmounted } from '@/utils/hooks'
|
||||||
const filterFileName = /[\\/:*?#"<>|]/
|
const filterFileName = /[\\/:*?#"<>|]/
|
||||||
|
|
||||||
|
|
||||||
@ -45,8 +47,6 @@ const NameInput = forwardRef<NameInputType, {}>((props, ref) => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const storagePath = '/storage'
|
|
||||||
|
|
||||||
export default memo(({
|
export default memo(({
|
||||||
title,
|
title,
|
||||||
path,
|
path,
|
||||||
@ -59,26 +59,34 @@ export default memo(({
|
|||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const confirmAlertRef = useRef<ConfirmAlertType>(null)
|
const confirmAlertRef = useRef<ConfirmAlertType>(null)
|
||||||
const nameInputRef = useRef<NameInputType>(null)
|
const nameInputRef = useRef<NameInputType>(null)
|
||||||
|
const storagePathRef = useRef('')
|
||||||
const [isShowStorage, setIsShowStorage] = useState(false)
|
const [isShowStorage, setIsShowStorage] = useState(false)
|
||||||
|
const isUnmounted = useUnmounted()
|
||||||
|
|
||||||
|
const checkExternalStoragePath = useCallback(() => {
|
||||||
|
void getExternalStoragePath().then((storagePath) => {
|
||||||
|
if (storagePath) {
|
||||||
|
void readDir(storagePath).then(() => {
|
||||||
|
if (isUnmounted.current) return
|
||||||
|
storagePathRef.current = storagePath
|
||||||
|
setIsShowStorage(true)
|
||||||
|
}).catch(() => {
|
||||||
|
setIsShowStorage(false)
|
||||||
|
})
|
||||||
|
} else setIsShowStorage(false)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isUnmounted = false
|
checkExternalStoragePath()
|
||||||
void readDir(storagePath).then(() => {
|
|
||||||
if (isUnmounted) return
|
|
||||||
setIsShowStorage(true)
|
|
||||||
}).catch(_ => _)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
isUnmounted = true
|
|
||||||
}
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
void onRefreshDir(path)
|
void onRefreshDir(path)
|
||||||
|
checkExternalStoragePath()
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleStorageDir = () => {
|
const toggleStorageDir = () => {
|
||||||
void onRefreshDir(storagePath)
|
void onRefreshDir(storagePathRef.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleShow = () => {
|
const handleShow = () => {
|
||||||
|
@ -9,5 +9,5 @@ export function useUnmounted() {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return isUnmountedRef.current
|
return isUnmountedRef
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,10 @@ export const onScreenStateChange = (handler: (state: 'ON' | 'OFF') => void): ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getExternalStoragePath = async(): Promise<string | null> => {
|
||||||
|
return UtilsModule.getExternalStoragePath()
|
||||||
|
}
|
||||||
|
|
||||||
export const getWindowSize = async(): Promise<{ width: number, height: number }> => {
|
export const getWindowSize = async(): Promise<{ width: number, height: number }> => {
|
||||||
return UtilsModule.getWindowSize()
|
return UtilsModule.getWindowSize()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user