Как я могу создать и сохранить файл используя expo?
Как в expo можно создать и сохранить файл в нужной мне директории?
UPD: я пытался использовать такой код:
const Save = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status === "granted") {
let fileUri = FileSystem.documentDirectory + "text.txt";
await FileSystem.writeAsStringAsync(fileUri, "Hello World", { encoding: FileSystem.EncodingType.UTF8 });
const asset = await MediaLibrary.createAssetAsync(fileUri)
await MediaLibrary.createAlbumAsync("Download", asset, false)
}
}
expo-permissions is now deprecated — the functionality has been moved to other expo packages that directly use these permissions (e.g. expo-location, expo-camera). The package will be removed in the upcoming releases.
следующее, что я попытался предпринять - использовать StorageAccessFramework
import { StorageAccessFramework } from 'expo-file-system';
const Save = async () => {
try {
const status = await StorageAccessFramework.requestDirectoryPermissionsAsync();
if (status.granted) {
console.log('granted');
await StorageAccessFramework.createFileAsync(status, "test", ".txt");
}
} catch (err) {
console.warn(err);
}
}
Но получал ошибку
Argument of an incompatible class: class java.util.HashMap cannot be passed as an argument to parameter expecting class java.lang.String.
Ответы (2 шт):
Есть очень простой способ, НО (ВНИМАНИЕ) КОЛХОЗНЫЙ и КОСТЫЛЬНЫЙ. До безобразия. И работает он только с прямыми ссылками, типа "https://www.abc.ru/123.jpg"
Суть такова: взять урл, и вставить его в сорс WebView: Сам компонент:
export default function Downloader(props: { url: string}) {
const html = `<!DOCTYPE html><html><script>window.location.href = '${props.url}'</script></html>`;
return (
<WebView source={{html}} />
);
}
затем этот компонент вставить в ... куда надо:
export default function App() {
const [startDownload, setStartDownload] = useState<boolean>(false);
const download = () => {
setStartDownload(true);
setTimeout(()=> setStartDownload(false), 2000);
}
return (
<View>
<TouchableHighlight
onPress={() => download()}
>
<MaterialCommunityIcons
name={'download'}
/>
</TouchableHighlight>
{startDownload && <Downloader url={URL}/>}
</View>
);
}
Фишка в том, что скачается любой файл, в директорию Downloads, выйдет уведомление в верхней строке с ссылкой на скаченный файл, и выйдет тоаст с уведомлением о начале загрузки. В других реализациях, ВСЁ ЭТО придётся самим реализовывать руками (!!!) и там трабл, что картинки скачиваются в папку с картинками, а видео с видео, а остальные форматы не идут никуда и не качаются. но это колхоз-колхоз.
Вот у меня работает Код брал от сюда: https://stackoverflow.com/questions/63460167/how-to-save-imported-json-file-with-expo-filesystem?
import * as FileSystem from "expo-file-system"
const { StorageAccessFramework } = FileSystem
const saveFile = async () => {
try {
const permissions =
await StorageAccessFramework.requestDirectoryPermissionsAsync()
if (permissions.granted) {
// Get the directory uri that was approved
let directoryUri = permissions.directoryUri
let data = "Bye World"
// Create file and pass it's SAF URI
await StorageAccessFramework.createFileAsync(
directoryUri,
"test",
"text/plain"
)
.then(async (fileUri) => {
// Save data to newly created file
await FileSystem.writeAsStringAsync(fileUri, data, {
encoding: FileSystem.EncodingType.UTF8
})
})
.catch((e) => {
console.log(e)
})
} else {
alert("You must allow permission to save.")
}
} catch (err) {
console.warn(err)
}
}