Reputation: 99
I'm currently trying to open a file using expo's FileSystem after getting the path from expo's DocumentPicker, but I can't find a way to make the URI from DocumentPicker readable to FileSystem. Everything works fine, I've no problems with permissions or anything else, but every tutorial I could find so far are basically for react native projects with exposed native code or Java.
Here I call DocumentPicker:
import * as DocumentPicker from 'expo-document-picker';
const Hello = ({navigation}) => (
<HelloView>
<HelloButton
style={{
backgroundColor: WhatsappStyles.colors.lightGreen,
}}
activeOpacity={0.5}
onPress={() => {
DocumentPicker.getDocumentAsync({
copyToCacheDirectory: false,
}).then(({uri}) => {
navigation.navigate('LoadFile', {path: uri});
});
}
}>
<HelloButtonText>Go to App</HelloButtonText>
</HelloButton>
</HelloView>
);
And here I try (unsuccessfully) read the path:
import * as FileSystem from 'expo-file-system';
const LoadFile = ({navigation, route}) => {
let [loading, setLoading] = useState(true);
useEffect(() => {
FileSystem.readAsStringAsync(route.params.path).then(result => {
// do something here
}
setLoading(false);
}, []);
...
I'm using react-navigation/stack for stack navigation and styled-components/native to build the components.
Upvotes: 5
Views: 6813
Reputation: 306
Other answers suggest using expo-file-system
's downloadAsync
method which does not support content://
schemes [1].
In this table, you can see what type of URI can be handled by each method. For example, if you have an URI, which begins with content://, you cannot use FileSystem.readAsStringAsync(), but you can use FileSystem.copyAsync() which supports this scheme.
Here is an example of using the suggested FileSystem.copyAsync
to move the file to our app's document directory:
const oldFile = "content://.../file.txt"
const newFile = FileSystem.documentDirectory + `newFile.txt`
await FileSystem.copyAsync({
from: oldFile,
to: newFile
});
// Now we can read the file with `readAsStringAsync`
const fileContent = await FileSystem.readAsStringAsync(newFile);
Upvotes: 0
Reputation: 99
So, as far as I could find there's no way to "convert" content:// uri to file:// uri, but you can actually download the file to a cache or to the internal storage using FileSystem's downloadAsync function and use the file:// uri resulting from there.
e.g.
DocumentPicker.getDocumentAsync({
copyToCacheDirectory: false,
}).then(({contentUri}) => {
FileSystem.downloadAsync(
contentUri,
FileSystem.documentDirectory + '<file name>')
.then(({uri}) => {
FileSystem.readAsStringAsync(uri)
.then(result => {
// do what you want here.
});
});
});
Upvotes: 1
Reputation: 33
import * as ImagePicker from 'expo-image-picker'
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
base64: true,
aspect: [4, 3]
})
{ imageURL: result.uri, base64: result.base64 }
So, result.uri
an image URL from FileSystem which you can use for displaying in Image
and base64
send to yout store :)
Upvotes: 1