更新时间:2022-11-27 18:15:08
------ EDITED ANSWER BELOW ------
Okay, so I finally have a Mac and was able to look into this issue in more details.
This is what I found for both Android and iOS.
The assumption is that you are using react-native-camera together with react-native-mail
- 1: Absolute Path
Add property captureTarget={Camera.constants.CaptureTarget.disk}
to Camera
component like so:
<Camera
captureTarget={Camera.constants.CaptureTarget.disk}
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
Now camera component should return absolute file path instead of uri.
So for Android you should see something like this:
"file:///storage/emulated/0/Pictures/RCTCameraModule/IMG_20160730_060652.jpg"
instead of:
"content://media/external/images/media/86"
and for iOS you should get something like this:
"/Users/anton/Library/Developer/CoreSimulator/Devices/9A15F203-9A58-41C5-A4FC-EA25FAAE92BD/data/Containers/Data/Application/79FF93F9-BA89-4F4C-8809-277BEECD447D/Documents/EFFF0ECE-4063-4FE5-984E-E76506788350.jpg"
instead of:
"assets-library://asset/asset.JPG?id=0058FA4A-268F-408A-9150-017A3DA368D2&ext=JPG"
- 2: Pitfalls
iOS:
If Apple's MFMailComposeViewController crashes and you see the following error message:
This is most likely because you are running the app on iOS 9 Simulator. Solution: either test the app on real device, or download an older Simulator such as iOS 8.4.
More information on this issue can be found here
Android:
As of this writing there is no attachment support for Android.
Solution: (PR has been made to add this feature, but if you can't wait)
Add the following code to file RNMAILModule.java
if (options.hasKey("attachment") && !options.isNull("attachment")) {
i.putExtra(Intent.EXTRA_STREAM, Uri.parse(options.getMap("attachment").getString("path")));
}
When both Android and iOS work you should have something like this:
And here is the working code:
var Mailer = require('NativeModules').RNMail;
import Camera from 'react-native-camera';
import React, {Component} from 'react';
import
{
View,
TouchableHighlight,
Text,
StyleSheet,
Dimensions,
CameraRoll
}
from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
height: Dimensions.get('window').height,
width: Dimensions.get('window').width
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
color: '#000',
padding: 10,
margin: 40
}
});
class SendPhoto extends Component {
takePicture() {
this.camera.capture()
.then((data) => {
console.log(data.path)
Mailer.mail({
subject: 'Ladunek',
recipients: ['placeholder@mail.com'],
body: 'body',
isHTML: true, // iOS only, exclude if false
attachment: {
path: data.path, // The absolute path of the file from which to read data.
type: 'jpg', // Mime Type: jpg, png, doc, ppt, html, pdf
name: 'Ladunek', // Optional: Custom filename for attachment
}
}, (error, event) => {
if(error) {
AlertIOS.alert('Error', 'Could not send mail. Please send a mail to support@example.com');
}
})
})
.catch(err => console.error(err));
}
render() {
return(
<View>
<View style={styles.container}>
<Camera
captureTarget={Camera.constants.CaptureTarget.disk}
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
</View>
</View>
);
}
}
export default SendPhoto;
------ OLD ANSWER BELOW ------
I never used this module before, but it looks like it expects absolute path of the file, however you are providing a file uri.
How are you obtaining this file uri?
Try using react-native-get-real-path module to see if it helps, you can find it here: react-native-get-real-path
i.e. convert your file uri to obtain real path, and use that as path