👉 Please use https://github.com/react-native-community/react-native-webview, which is maintained by the React Native Community.
This is a Custom React Native Android module that enables file uploads from a WebView <input type="file" />
element:
- by taking a new photo using the camera
- by recording a new video using the camera
- by choosing an existing photo/video from the gallery
What this module does:
- takes dahjelle's react-native-android-webview-file-image-upload implementation;
- fixes some bugs where you couldn't open the camera after first usage;
- extracts it into a separate module like lucasferreira's react-native-webview-android for easier setup;
- adds the video recording functionality;
- adds support for the
accept
attribute; - adds support for the
multiple
attribute; - adds support for sdk 26, using
FileProvider
; - adds runtime Camera Permissions (thanks Pablo Navarro);
It should work with React Native 0.50+, and reverts to the built-in WebView on iOS.
npm install git+ssh://[email protected]:andreipfeiffer/react-native-webview-android-file-upload.git
react-native link react-native-webview-android-file-upload
The above should make (most of) the changes listed below. If it didn't, you should try manual linking.
- Update
android/setting.gradle
......
include ':react-native-webview-android-file-upload'
project(':react-native-webview-android-file-upload').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-android-file-upload/android')
......
- Update
android/app/build.gradle
......
dependencies {
......
// for gradle < 3.0
compile project(':react-native-webview-android-file-upload')
// for gradle 3+
implementation project(':react-native-webview-android-file-upload')
}
- Register Module in
android/app/src/main/java/com/[your-project-package]/MainApplication.java
import com.rncustomwebview.CustomWebViewPackage; // <--- import package
public class MainApplication extends Application implements ReactApplication {
......
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CustomWebViewPackage() // <------ add this line to your MainApplication class
);
}
......
}
- Add file provider path resource
file_provider_paths.xml
in[your project]/android/app/src/main/res/xml/
folder. If the folder does not exist, create a new one.
NOTE: this is a requirement for sdk 26
. This approach should NOT require you to ask/handle any dangerous permissions.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="shared" path="." />
</paths>
- Add permissions & configure file provider in
AndroidManifest.xml
:
<manifest ...>
......
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application ...>
......
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
</application>
</manifest>
Since you have changed native code, reloading the JS code alone won't work:
react-native run-android
import React, { Component } from "react";
// import module
import CustomWebView from "react-native-webview-android-file-upload";
export default class App extends Component {
render() {
return (
<CustomWebView
source={{ uri: "your-web-url" }}
startInLoadingState={true}
// any other props supported by React Native's WebView
/>
);
}
}
export default class App extends Component {
render() {
return (
<CustomWebView
source={{ uri: "your-web-url" }}
webviewRef={e => (this.webview = e)}
/>
);
}
// then you can call any of the methods available on the built-in ref, like:
// this.webview.reload();
// this.webview.injectJavaScript();
}
You can use the accept
attribute on the <input />
element to control what type of media your users will be allowed to upload:
<input type="file" />
will default to images and videos<input type="file" accept="image/*" />
will allow only image capture / selection<input type="file" accept="video/*" />
will allow only video recording / selection<input type="file" accept="image/*, video/*" />
same as default
Check out the example html.
You can use the multiple
attribute on the <input />
element to allow users to select multiple existing files:
<input type="file" multiple />
Please refer to CHANGELOG.md.