更新外部存储路径获取方式

This commit is contained in:
lyswhut 2023-12-17 22:18:32 +08:00
parent 89a282ff56
commit 2fb4db83e6
8 changed files with 70 additions and 18 deletions

View File

@ -1,6 +1,11 @@
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.File;
import java.io.FileInputStream;
@ -8,6 +13,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class Utils {
@ -26,6 +33,31 @@ public class Utils {
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 {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();

View File

@ -395,5 +395,10 @@ public class UtilsModule extends ReactContextBaseJavaModule {
public void requestIgnoreBatteryOptimization(Promise promise) {
promise.resolve(BatteryOptimizationUtil.requestIgnoreBatteryOptimization(reactContext.getApplicationContext(), reactContext.getPackageName()));
}
@ReactMethod
public void getExternalStoragePath(Promise promise) {
promise.resolve(Utils.getExternalStoragePath(reactContext, true));
}
}

View File

@ -14,7 +14,7 @@
- 优化播放详情页歌曲封面、控制按钮对各尺寸屏幕的适配,修改横屏下的控制栏按钮布局
- 优化横竖屏界面的暂时判断,现在趋于方屏的屏幕按竖屏的方式显示,横屏下的播放栏添加上一曲切歌按钮
- 添加对wy源某些歌曲有问题的歌词进行修复#370
- 文件选择器允许(在旧系统)选择外置存储设备上的路径`/storage`
- 文件选择器允许(在旧系统)选择外置存储设备上的路径
- 图片显示改用第三方的图片组件支持gif类型的图片显示尝试解决某些设备上图片过多导致的应用崩溃问题
- 歌曲评论内容过长时自动折叠,需手动展开
- 改进本地音乐在线信息的匹配机制

View File

@ -44,7 +44,7 @@ export default forwardRef<MetadataEditType, MetadataEditProps>((props, ref) => {
readLyric(filePath),
]).then(([_metadata, pic, lyric]) => {
if (!_metadata) return
if (isUnmounted) return
if (isUnmounted.current) return
metadata.current = {
name: _metadata.name,
singer: _metadata.singer,

View File

@ -126,6 +126,7 @@ export default forwardRef<ListType, ListProps>(({
// console.log('prevPath', prevPath)
// if (isReadingDir.current) return
// setPath(prevPath)
throw err
}).finally(() => {
isReadingDir.current = false
})
@ -134,7 +135,7 @@ export default forwardRef<ListType, ListProps>(({
const onSetPath = (pathInfo: PathItem) => {
// console.log('onSetPath')
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 {
onConfirm(pathInfo.path)
// setPath(pathInfo.path)
@ -143,7 +144,9 @@ export default forwardRef<ListType, ListProps>(({
const toParentDir = () => {
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 = () => {

View File

@ -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 Input, { type InputType } from '@/components/common/Input'
import Text from '@/components/common/Text'
@ -9,6 +9,8 @@ import { createStyle, toast } from '@/utils/tools'
import { mkdir, readDir } from '@/utils/fs'
import { useTheme } from '@/store/theme/hook'
import { scaleSizeH } from '@/utils/pixelRatio'
import { getExternalStoragePath } from '@/utils/nativeModules/utils'
import { useUnmounted } from '@/utils/hooks'
const filterFileName = /[\\/:*?#"<>|]/
@ -45,8 +47,6 @@ const NameInput = forwardRef<NameInputType, {}>((props, ref) => {
)
})
const storagePath = '/storage'
export default memo(({
title,
path,
@ -59,26 +59,34 @@ export default memo(({
const theme = useTheme()
const confirmAlertRef = useRef<ConfirmAlertType>(null)
const nameInputRef = useRef<NameInputType>(null)
const storagePathRef = useRef('')
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(() => {
let isUnmounted = false
void readDir(storagePath).then(() => {
if (isUnmounted) return
setIsShowStorage(true)
}).catch(_ => _)
return () => {
isUnmounted = true
}
checkExternalStoragePath()
}, [])
const refresh = () => {
void onRefreshDir(path)
checkExternalStoragePath()
}
const toggleStorageDir = () => {
void onRefreshDir(storagePath)
void onRefreshDir(storagePathRef.current)
}
const handleShow = () => {

View File

@ -9,5 +9,5 @@ export function useUnmounted() {
}
}, [])
return isUnmountedRef.current
return isUnmountedRef
}

View File

@ -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 }> => {
return UtilsModule.getWindowSize()
}