15d59e2b8SBrent Vatneimport AsyncStorage from '@react-native-async-storage/async-storage'; 2e331da1dSEvan Baconimport { Asset } from 'expo-asset'; 3e331da1dSEvan Baconimport * as FileSystem from 'expo-file-system'; 45d59e2b8SBrent Vatne// import * as Progress from 'expo-progress'; 56b7802baSBartosz Kaszubowskiimport type { 66b7802baSBartosz Kaszubowski DownloadProgressData, 76b7802baSBartosz Kaszubowski DownloadResumable, 86b7802baSBartosz Kaszubowski FileSystemNetworkTaskProgressCallback, 94ee48f97SGabriel Donadel Dall'Agnol UploadProgressData, 104ee48f97SGabriel Donadel Dall'Agnol UploadTask, 116b7802baSBartosz Kaszubowski} from 'expo-file-system'; 1269185572SBartłomiej Bukowskiimport React from 'react'; 135d59e2b8SBrent Vatneimport { Alert, ScrollView, Text, Platform } from 'react-native'; 14284d38c7SEvan Bacon 15400de723SŁukasz Kosmatyimport HeadingText from '../components/HeadingText'; 1669185572SBartłomiej Bukowskiimport ListButton from '../components/ListButton'; 17400de723SŁukasz Kosmatyimport SimpleActionDemo from '../components/SimpleActionDemo'; 18400de723SŁukasz Kosmaty 19400de723SŁukasz Kosmatyconst { StorageAccessFramework } = FileSystem; 2069185572SBartłomiej Bukowski 2169185572SBartłomiej Bukowskiinterface State { 2269185572SBartłomiej Bukowski downloadProgress: number; 234ee48f97SGabriel Donadel Dall'Agnol uploadProgress: number; 24400de723SŁukasz Kosmaty permittedURI: string | null; 25400de723SŁukasz Kosmaty createdFileURI: string | null; 2669185572SBartłomiej Bukowski} 2769185572SBartłomiej Bukowski 286b7802baSBartosz Kaszubowskiexport default class FileSystemScreen extends React.Component<object, State> { 2969185572SBartłomiej Bukowski static navigationOptions = { 3069185572SBartłomiej Bukowski title: 'FileSystem', 3169185572SBartłomiej Bukowski }; 3269185572SBartłomiej Bukowski 3369185572SBartłomiej Bukowski readonly state: State = { 3469185572SBartłomiej Bukowski downloadProgress: 0, 354ee48f97SGabriel Donadel Dall'Agnol uploadProgress: 0, 36400de723SŁukasz Kosmaty permittedURI: null, 37400de723SŁukasz Kosmaty createdFileURI: null, 3869185572SBartłomiej Bukowski }; 3969185572SBartłomiej Bukowski 406b7802baSBartosz Kaszubowski download?: DownloadResumable; 414ee48f97SGabriel Donadel Dall'Agnol upload?: UploadTask; 4269185572SBartłomiej Bukowski 4369185572SBartłomiej Bukowski _download = async () => { 4469185572SBartłomiej Bukowski const url = 'http://ipv4.download.thinkbroadband.com/256KB.zip'; 4569185572SBartłomiej Bukowski await FileSystem.downloadAsync(url, FileSystem.documentDirectory + '256KB.zip'); 4669185572SBartłomiej Bukowski alert('Download complete!'); 47edaf9ec0SŁukasz Kosmaty }; 4869185572SBartłomiej Bukowski 4969185572SBartłomiej Bukowski _startDownloading = async () => { 5069185572SBartłomiej Bukowski const url = 'http://ipv4.download.thinkbroadband.com/5MB.zip'; 5169185572SBartłomiej Bukowski const fileUri = FileSystem.documentDirectory + '5MB.zip'; 526b7802baSBartosz Kaszubowski const callback: FileSystemNetworkTaskProgressCallback<DownloadProgressData> = ( 536b7802baSBartosz Kaszubowski downloadProgress 546b7802baSBartosz Kaszubowski ) => { 5569185572SBartłomiej Bukowski const progress = 5669185572SBartłomiej Bukowski downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite; 5769185572SBartłomiej Bukowski this.setState({ 5869185572SBartłomiej Bukowski downloadProgress: progress, 5969185572SBartłomiej Bukowski }); 6069185572SBartłomiej Bukowski }; 6169185572SBartłomiej Bukowski const options = { md5: true }; 6269185572SBartłomiej Bukowski this.download = FileSystem.createDownloadResumable(url, fileUri, options, callback); 6369185572SBartłomiej Bukowski 6469185572SBartłomiej Bukowski try { 65edaf9ec0SŁukasz Kosmaty const result = await this.download.downloadAsync(); 66edaf9ec0SŁukasz Kosmaty if (result) { 67edaf9ec0SŁukasz Kosmaty this._downloadComplete(); 6869185572SBartłomiej Bukowski } 6969185572SBartłomiej Bukowski } catch (e) { 7069185572SBartłomiej Bukowski console.log(e); 7169185572SBartłomiej Bukowski } 72edaf9ec0SŁukasz Kosmaty }; 7369185572SBartłomiej Bukowski 7469185572SBartłomiej Bukowski _pause = async () => { 7569185572SBartłomiej Bukowski if (!this.download) { 7669185572SBartłomiej Bukowski alert('Initiate a download first!'); 7769185572SBartłomiej Bukowski return; 7869185572SBartłomiej Bukowski } 7969185572SBartłomiej Bukowski try { 8069185572SBartłomiej Bukowski const downloadSnapshot = await this.download.pauseAsync(); 8169185572SBartłomiej Bukowski await AsyncStorage.setItem('pausedDownload', JSON.stringify(downloadSnapshot)); 8269185572SBartłomiej Bukowski alert('Download paused...'); 8369185572SBartłomiej Bukowski } catch (e) { 8469185572SBartłomiej Bukowski console.log(e); 8569185572SBartłomiej Bukowski } 86edaf9ec0SŁukasz Kosmaty }; 8769185572SBartłomiej Bukowski 8869185572SBartłomiej Bukowski _resume = async () => { 8969185572SBartłomiej Bukowski try { 9069185572SBartłomiej Bukowski if (this.download) { 91edaf9ec0SŁukasz Kosmaty const result = await this.download.resumeAsync(); 92edaf9ec0SŁukasz Kosmaty if (result) { 93edaf9ec0SŁukasz Kosmaty this._downloadComplete(); 9469185572SBartłomiej Bukowski } 9569185572SBartłomiej Bukowski } else { 9669185572SBartłomiej Bukowski this._fetchDownload(); 9769185572SBartłomiej Bukowski } 9869185572SBartłomiej Bukowski } catch (e) { 9969185572SBartłomiej Bukowski console.log(e); 10069185572SBartłomiej Bukowski } 101edaf9ec0SŁukasz Kosmaty }; 102edaf9ec0SŁukasz Kosmaty 10352eeb172SŁukasz Kosmaty _cancel = async () => { 10452eeb172SŁukasz Kosmaty if (!this.download) { 10552eeb172SŁukasz Kosmaty alert('Initiate a download first!'); 10652eeb172SŁukasz Kosmaty return; 10752eeb172SŁukasz Kosmaty } 10852eeb172SŁukasz Kosmaty 10952eeb172SŁukasz Kosmaty try { 11052eeb172SŁukasz Kosmaty await this.download.cancelAsync(); 11152eeb172SŁukasz Kosmaty delete this.download; 11252eeb172SŁukasz Kosmaty await AsyncStorage.removeItem('pausedDownload'); 11352eeb172SŁukasz Kosmaty this.setState({ 11452eeb172SŁukasz Kosmaty downloadProgress: 0, 11552eeb172SŁukasz Kosmaty }); 11652eeb172SŁukasz Kosmaty } catch (e) { 11752eeb172SŁukasz Kosmaty console.log(e); 11852eeb172SŁukasz Kosmaty } 11952eeb172SŁukasz Kosmaty }; 12052eeb172SŁukasz Kosmaty 121edaf9ec0SŁukasz Kosmaty _downloadComplete = () => { 122edaf9ec0SŁukasz Kosmaty if (this.state.downloadProgress !== 1) { 123edaf9ec0SŁukasz Kosmaty this.setState({ 124edaf9ec0SŁukasz Kosmaty downloadProgress: 1, 125edaf9ec0SŁukasz Kosmaty }); 12669185572SBartłomiej Bukowski } 127edaf9ec0SŁukasz Kosmaty alert('Download complete!'); 128edaf9ec0SŁukasz Kosmaty }; 12969185572SBartłomiej Bukowski 13069185572SBartłomiej Bukowski _fetchDownload = async () => { 13169185572SBartłomiej Bukowski try { 13269185572SBartłomiej Bukowski const downloadJson = await AsyncStorage.getItem('pausedDownload'); 13369185572SBartłomiej Bukowski if (downloadJson !== null) { 13469185572SBartłomiej Bukowski const downloadFromStore = JSON.parse(downloadJson); 1356b7802baSBartosz Kaszubowski const callback: FileSystemNetworkTaskProgressCallback<DownloadProgressData> = ( 1366b7802baSBartosz Kaszubowski downloadProgress 1376b7802baSBartosz Kaszubowski ) => { 13869185572SBartłomiej Bukowski const progress = 13969185572SBartłomiej Bukowski downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite; 14069185572SBartłomiej Bukowski this.setState({ 14169185572SBartłomiej Bukowski downloadProgress: progress, 14269185572SBartłomiej Bukowski }); 14369185572SBartłomiej Bukowski }; 14469185572SBartłomiej Bukowski this.download = new FileSystem.DownloadResumable( 14569185572SBartłomiej Bukowski downloadFromStore.url, 14669185572SBartłomiej Bukowski downloadFromStore.fileUri, 14769185572SBartłomiej Bukowski downloadFromStore.options, 14869185572SBartłomiej Bukowski callback, 14969185572SBartłomiej Bukowski downloadFromStore.resumeData 15069185572SBartłomiej Bukowski ); 15169185572SBartłomiej Bukowski await this.download.resumeAsync(); 15269185572SBartłomiej Bukowski if (this.state.downloadProgress === 1) { 15369185572SBartłomiej Bukowski alert('Download complete!'); 15469185572SBartłomiej Bukowski } 15569185572SBartłomiej Bukowski } else { 15669185572SBartłomiej Bukowski alert('Initiate a download first!'); 15769185572SBartłomiej Bukowski } 15869185572SBartłomiej Bukowski } catch (e) { 15969185572SBartłomiej Bukowski console.log(e); 16069185572SBartłomiej Bukowski } 161edaf9ec0SŁukasz Kosmaty }; 16269185572SBartłomiej Bukowski 1634ee48f97SGabriel Donadel Dall'Agnol _upload = async () => { 1644ee48f97SGabriel Donadel Dall'Agnol try { 1654ee48f97SGabriel Donadel Dall'Agnol const fileUri = FileSystem.documentDirectory + '5MB.zip'; 1664ee48f97SGabriel Donadel Dall'Agnol const downloadUrl = 'https://xcal1.vodafone.co.uk/5MB.zip'; 1674ee48f97SGabriel Donadel Dall'Agnol await FileSystem.downloadAsync(downloadUrl, fileUri); 1684ee48f97SGabriel Donadel Dall'Agnol 1694ee48f97SGabriel Donadel Dall'Agnol const callback: FileSystemNetworkTaskProgressCallback<UploadProgressData> = ( 1704ee48f97SGabriel Donadel Dall'Agnol uploadProgress 1714ee48f97SGabriel Donadel Dall'Agnol ) => { 172*89c23745SGabriel Donadel Dall'Agnol const progress = uploadProgress.totalBytesSent / uploadProgress.totalBytesExpectedToSend; 1734ee48f97SGabriel Donadel Dall'Agnol this.setState({ 1744ee48f97SGabriel Donadel Dall'Agnol uploadProgress: progress, 1754ee48f97SGabriel Donadel Dall'Agnol }); 1764ee48f97SGabriel Donadel Dall'Agnol }; 1774ee48f97SGabriel Donadel Dall'Agnol const uploadUrl = 'http://httpbin.org/post'; 1784ee48f97SGabriel Donadel Dall'Agnol this.upload = FileSystem.createUploadTask(uploadUrl, fileUri, {}, callback); 1794ee48f97SGabriel Donadel Dall'Agnol 1804ee48f97SGabriel Donadel Dall'Agnol await this.upload.uploadAsync(); 1814ee48f97SGabriel Donadel Dall'Agnol } catch (e) { 1824ee48f97SGabriel Donadel Dall'Agnol console.log(e); 1834ee48f97SGabriel Donadel Dall'Agnol } 1844ee48f97SGabriel Donadel Dall'Agnol }; 1854ee48f97SGabriel Donadel Dall'Agnol 18669185572SBartłomiej Bukowski _getInfo = async () => { 18769185572SBartłomiej Bukowski if (!this.download) { 18869185572SBartłomiej Bukowski alert('Initiate a download first!'); 18969185572SBartłomiej Bukowski return; 19069185572SBartłomiej Bukowski } 19169185572SBartłomiej Bukowski try { 19252eeb172SŁukasz Kosmaty const info = await FileSystem.getInfoAsync(this.download.fileUri); 19369185572SBartłomiej Bukowski Alert.alert('File Info:', JSON.stringify(info), [{ text: 'OK', onPress: () => {} }]); 19469185572SBartłomiej Bukowski } catch (e) { 19569185572SBartłomiej Bukowski console.log(e); 19669185572SBartłomiej Bukowski } 197edaf9ec0SŁukasz Kosmaty }; 19869185572SBartłomiej Bukowski 19969185572SBartłomiej Bukowski _readAsset = async () => { 20069185572SBartłomiej Bukowski const asset = Asset.fromModule(require('../../assets/index.html')); 20169185572SBartłomiej Bukowski await asset.downloadAsync(); 20269185572SBartłomiej Bukowski try { 20369185572SBartłomiej Bukowski const result = await FileSystem.readAsStringAsync(asset.localUri!); 20469185572SBartłomiej Bukowski Alert.alert('Result', result); 20569185572SBartłomiej Bukowski } catch (e) { 20669185572SBartłomiej Bukowski Alert.alert('Error', e.message); 20769185572SBartłomiej Bukowski } 208edaf9ec0SŁukasz Kosmaty }; 20969185572SBartłomiej Bukowski 21069185572SBartłomiej Bukowski _getInfoAsset = async () => { 21169185572SBartłomiej Bukowski const asset = Asset.fromModule(require('../../assets/index.html')); 21269185572SBartłomiej Bukowski await asset.downloadAsync(); 21369185572SBartłomiej Bukowski try { 21469185572SBartłomiej Bukowski const result = await FileSystem.getInfoAsync(asset.localUri!); 21569185572SBartłomiej Bukowski Alert.alert('Result', JSON.stringify(result, null, 2)); 21669185572SBartłomiej Bukowski } catch (e) { 21769185572SBartłomiej Bukowski Alert.alert('Error', e.message); 21869185572SBartłomiej Bukowski } 219edaf9ec0SŁukasz Kosmaty }; 22069185572SBartłomiej Bukowski 22169185572SBartłomiej Bukowski _copyAndReadAsset = async () => { 22269185572SBartłomiej Bukowski const asset = Asset.fromModule(require('../../assets/index.html')); 22369185572SBartłomiej Bukowski await asset.downloadAsync(); 22469185572SBartłomiej Bukowski const tmpFile = FileSystem.cacheDirectory + 'test.html'; 22569185572SBartłomiej Bukowski try { 22669185572SBartłomiej Bukowski await FileSystem.copyAsync({ from: asset.localUri!, to: tmpFile }); 22769185572SBartłomiej Bukowski const result = await FileSystem.readAsStringAsync(tmpFile); 22869185572SBartłomiej Bukowski Alert.alert('Result', result); 22969185572SBartłomiej Bukowski } catch (e) { 23069185572SBartłomiej Bukowski Alert.alert('Error', e.message); 23169185572SBartłomiej Bukowski } 232edaf9ec0SŁukasz Kosmaty }; 23369185572SBartłomiej Bukowski 234031bd34fSStanisław Chmiela _alertFreeSpace = async () => { 235031bd34fSStanisław Chmiela const freeBytes = await FileSystem.getFreeDiskStorageAsync(); 236031bd34fSStanisław Chmiela alert(`${Math.round(freeBytes / 1024 / 1024)} MB available`); 237edaf9ec0SŁukasz Kosmaty }; 238031bd34fSStanisław Chmiela 239400de723SŁukasz Kosmaty _askForDirPermissions = async () => { 240400de723SŁukasz Kosmaty const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(); 241400de723SŁukasz Kosmaty if (permissions.granted) { 2426b7802baSBartosz Kaszubowski const url = permissions.directoryUri; 243400de723SŁukasz Kosmaty this.setState({ 2446b7802baSBartosz Kaszubowski permittedURI: url, 245400de723SŁukasz Kosmaty }); 2466b7802baSBartosz Kaszubowski alert(`You selected: ${url}`); 247400de723SŁukasz Kosmaty } 248400de723SŁukasz Kosmaty }; 249400de723SŁukasz Kosmaty 250400de723SŁukasz Kosmaty _readSAFDirAsync = async () => { 251400de723SŁukasz Kosmaty return await StorageAccessFramework.readDirectoryAsync(this.state.permittedURI!); 252400de723SŁukasz Kosmaty }; 253400de723SŁukasz Kosmaty 254400de723SŁukasz Kosmaty _creatSAFFileAsync = async () => { 255400de723SŁukasz Kosmaty const createdFile = await StorageAccessFramework.createFileAsync( 256400de723SŁukasz Kosmaty // eslint-disable-next-line react/no-access-state-in-setstate 257400de723SŁukasz Kosmaty this.state.permittedURI!, 258400de723SŁukasz Kosmaty 'test', 259400de723SŁukasz Kosmaty 'text/plain' 260400de723SŁukasz Kosmaty ); 261400de723SŁukasz Kosmaty 262400de723SŁukasz Kosmaty this.setState({ 263400de723SŁukasz Kosmaty createdFileURI: createdFile, 264400de723SŁukasz Kosmaty }); 265400de723SŁukasz Kosmaty 266400de723SŁukasz Kosmaty return createdFile; 267400de723SŁukasz Kosmaty }; 268400de723SŁukasz Kosmaty 269400de723SŁukasz Kosmaty _writeToSAFFileAsync = async () => { 270400de723SŁukasz Kosmaty await StorageAccessFramework.writeAsStringAsync( 271400de723SŁukasz Kosmaty this.state.createdFileURI!, 272400de723SŁukasz Kosmaty 'Expo is awesome ' 273400de723SŁukasz Kosmaty ); 274400de723SŁukasz Kosmaty 275400de723SŁukasz Kosmaty return 'Done '; 276400de723SŁukasz Kosmaty }; 277400de723SŁukasz Kosmaty 278400de723SŁukasz Kosmaty _readSAFFileAsync = async () => { 279400de723SŁukasz Kosmaty return await StorageAccessFramework.readAsStringAsync(this.state.createdFileURI!); 280400de723SŁukasz Kosmaty }; 281400de723SŁukasz Kosmaty 282400de723SŁukasz Kosmaty _deleteSAFFileAsync = async () => { 283400de723SŁukasz Kosmaty await StorageAccessFramework.deleteAsync(this.state.createdFileURI!); 284400de723SŁukasz Kosmaty 285400de723SŁukasz Kosmaty this.setState({ 286400de723SŁukasz Kosmaty createdFileURI: null, 287400de723SŁukasz Kosmaty }); 288400de723SŁukasz Kosmaty }; 289400de723SŁukasz Kosmaty 290400de723SŁukasz Kosmaty _copySAFFileToInternalStorageAsync = async () => { 291400de723SŁukasz Kosmaty const outputDir = FileSystem.cacheDirectory! + '/SAFTest'; 292400de723SŁukasz Kosmaty await StorageAccessFramework.copyAsync({ 293400de723SŁukasz Kosmaty from: this.state.createdFileURI!, 294400de723SŁukasz Kosmaty to: outputDir, 295400de723SŁukasz Kosmaty }); 296400de723SŁukasz Kosmaty 297400de723SŁukasz Kosmaty return await FileSystem.readDirectoryAsync(outputDir); 298400de723SŁukasz Kosmaty }; 299400de723SŁukasz Kosmaty 300400de723SŁukasz Kosmaty _moveSAFFileToInternalStorageAsync = async () => { 301400de723SŁukasz Kosmaty await StorageAccessFramework.moveAsync({ 302400de723SŁukasz Kosmaty from: this.state.createdFileURI!, 303400de723SŁukasz Kosmaty to: FileSystem.cacheDirectory!, 304400de723SŁukasz Kosmaty }); 305400de723SŁukasz Kosmaty 306400de723SŁukasz Kosmaty this.setState({ 307400de723SŁukasz Kosmaty createdFileURI: null, 308400de723SŁukasz Kosmaty }); 309400de723SŁukasz Kosmaty }; 310400de723SŁukasz Kosmaty 31169185572SBartłomiej Bukowski render() { 31269185572SBartłomiej Bukowski return ( 31369185572SBartłomiej Bukowski <ScrollView style={{ padding: 10 }}> 31469185572SBartłomiej Bukowski <ListButton onPress={this._download} title="Download file (512KB)" /> 31569185572SBartłomiej Bukowski <ListButton onPress={this._startDownloading} title="Start Downloading file (5MB)" /> 3165d59e2b8SBrent Vatne {this.state.downloadProgress ? ( 3175d59e2b8SBrent Vatne <Text style={{ paddingVertical: 15 }}> 3185d59e2b8SBrent Vatne Download progress: {this.state.downloadProgress * 100}% 3195d59e2b8SBrent Vatne </Text> 3205d59e2b8SBrent Vatne ) : null} 3215d59e2b8SBrent Vatne {/* Add back progress bar once deprecation warnings from reanimated 2 are resolved */} 3225d59e2b8SBrent Vatne {/* <Progress.Bar style={styles.progress} isAnimated progress={this.state.downloadProgress} /> */} 32369185572SBartłomiej Bukowski <ListButton onPress={this._pause} title="Pause Download" /> 32469185572SBartłomiej Bukowski <ListButton onPress={this._resume} title="Resume Download" /> 32552eeb172SŁukasz Kosmaty <ListButton onPress={this._cancel} title="Cancel Download" /> 3264ee48f97SGabriel Donadel Dall'Agnol <ListButton onPress={this._upload} title="Download & Upload file (5MB)" /> 3274ee48f97SGabriel Donadel Dall'Agnol {this.state.uploadProgress ? ( 3284ee48f97SGabriel Donadel Dall'Agnol <Text style={{ paddingVertical: 15 }}> 3294ee48f97SGabriel Donadel Dall'Agnol Upload progress: {this.state.uploadProgress * 100}% 3304ee48f97SGabriel Donadel Dall'Agnol </Text> 3314ee48f97SGabriel Donadel Dall'Agnol ) : null} 33269185572SBartłomiej Bukowski <ListButton onPress={this._getInfo} title="Get Info" /> 33369185572SBartłomiej Bukowski <ListButton onPress={this._readAsset} title="Read Asset" /> 33469185572SBartłomiej Bukowski <ListButton onPress={this._getInfoAsset} title="Get Info Asset" /> 33569185572SBartłomiej Bukowski <ListButton onPress={this._copyAndReadAsset} title="Copy and Read Asset" /> 336031bd34fSStanisław Chmiela <ListButton onPress={this._alertFreeSpace} title="Alert free space" /> 337400de723SŁukasz Kosmaty {Platform.OS === 'android' && ( 338400de723SŁukasz Kosmaty <> 339400de723SŁukasz Kosmaty <HeadingText>Storage Access Framework</HeadingText> 340400de723SŁukasz Kosmaty <ListButton 341400de723SŁukasz Kosmaty onPress={this._askForDirPermissions} 342400de723SŁukasz Kosmaty title="Ask for directory permissions" 343400de723SŁukasz Kosmaty /> 344400de723SŁukasz Kosmaty {this.state.permittedURI && ( 345400de723SŁukasz Kosmaty <> 346400de723SŁukasz Kosmaty <SimpleActionDemo title="Read directory" action={this._readSAFDirAsync} /> 347400de723SŁukasz Kosmaty <SimpleActionDemo title="Create a file" action={this._creatSAFFileAsync} /> 348400de723SŁukasz Kosmaty 349400de723SŁukasz Kosmaty {this.state.createdFileURI && ( 350400de723SŁukasz Kosmaty <> 351400de723SŁukasz Kosmaty <SimpleActionDemo 352400de723SŁukasz Kosmaty title="Write to created file" 353400de723SŁukasz Kosmaty action={this._writeToSAFFileAsync} 354400de723SŁukasz Kosmaty /> 355400de723SŁukasz Kosmaty <SimpleActionDemo 356400de723SŁukasz Kosmaty title="Read from created file" 357400de723SŁukasz Kosmaty action={this._readSAFFileAsync} 358400de723SŁukasz Kosmaty /> 359400de723SŁukasz Kosmaty <ListButton title="Delete created file" onPress={this._deleteSAFFileAsync} /> 360400de723SŁukasz Kosmaty <SimpleActionDemo 361400de723SŁukasz Kosmaty title="Copy file to internal storage" 362400de723SŁukasz Kosmaty action={this._copySAFFileToInternalStorageAsync} 363400de723SŁukasz Kosmaty /> 364400de723SŁukasz Kosmaty <ListButton 365400de723SŁukasz Kosmaty title="Move file to internal storage" 366400de723SŁukasz Kosmaty onPress={this._moveSAFFileToInternalStorageAsync} 367400de723SŁukasz Kosmaty /> 368400de723SŁukasz Kosmaty </> 369400de723SŁukasz Kosmaty )} 370400de723SŁukasz Kosmaty </> 371400de723SŁukasz Kosmaty )} 372400de723SŁukasz Kosmaty </> 373400de723SŁukasz Kosmaty )} 37469185572SBartłomiej Bukowski </ScrollView> 37569185572SBartłomiej Bukowski ); 37669185572SBartłomiej Bukowski } 37769185572SBartłomiej Bukowski} 378