Merge pull request #18 from cjdell/master

Experimental Android support
This commit is contained in:
cjdell 2015-10-19 16:07:47 +01:00
commit 283016c401
8 changed files with 300 additions and 12 deletions

View File

@ -1,11 +0,0 @@
'use strict';
var warning = require('warning');
var FS = {
test: function() {
warning("Not yet implemented for Android.");
}
};
module.exports = FS;

View File

@ -1,5 +1,12 @@
'use strict';
// This file supports both iOS and Android
// Stop bluebird going nuts because it can't find "self"
if (typeof self === 'undefined') {
global.self = global;
}
var RNFSManager = require('react-native').NativeModules.RNFSManager;
var Promise = require('bluebird');
var base64 = require('base-64');

View File

@ -22,6 +22,64 @@ In XCode, in the project navigator, select your project. Add the lib*.a from the
Run your project (Cmd+R)
## Android
Android support is still experimental. Currently only the `DocumentDirectory` is supported. This maps to the app's `files` directory.
Make alterations to the following files:
* `android/settings.gradle`
```gradle
...
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
```
* `android/app/build.gradle`
```gradle
...
dependencies {
...
compile project(':react-native-fs')
}
```
* register module (in MainActivity.java)
```java
import com.rnfs.RNFSPackage; // <--- import
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
......
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new RNFSPackage()) // <------- add package
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "ExampleRN", null);
setContentView(mReactRootView);
}
......
}
```
## Examples
### Basic

34
android/build.gradle Normal file
View File

@ -0,0 +1,34 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
}
repositories {
mavenCentral()
}
dependencies {
compile 'com.facebook.react:react-native:0.12.+'
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rnfs" >
</manifest>

View File

@ -0,0 +1,166 @@
package com.rnfs;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import android.os.Environment;
import android.util.Base64;
import android.content.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableArray;
public class RNFSManager extends ReactContextBaseJavaModule {
private static final String NSDocumentDirectoryPath = "NSDocumentDirectoryPath";
private static final String NSDocumentDirectory = "NSDocumentDirectory";
private static final String NSFileTypeRegular = "NSFileTypeRegular";
private static final String NSFileTypeDirectory = "NSFileTypeDirectory";
public RNFSManager(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RNFSManager";
}
@ReactMethod
public void writeFile(String filepath, String base64Content, ReadableMap options, Callback callback) {
try {
byte[] bytes = Base64.decode(base64Content, Base64.DEFAULT);
FileOutputStream outputStream = new FileOutputStream(filepath);
outputStream.write(bytes);
outputStream.close();
callback.invoke();
} catch (Exception ex) {
ex.printStackTrace();
callback.invoke(makeErrorPayload(ex));
}
}
@ReactMethod
public void readFile(String filepath, Callback callback) {
try {
File file = new File(filepath);
if (!file.exists()) throw new Exception("File does not exist");
FileInputStream inputStream = new FileInputStream(filepath);
byte[] buffer = new byte[(int)file.length()];
inputStream.read(buffer);
String base64Content = Base64.encodeToString(buffer, Base64.DEFAULT);
callback.invoke(null, base64Content);
} catch (Exception ex) {
ex.printStackTrace();
callback.invoke(makeErrorPayload(ex));
}
}
@ReactMethod
public void readDir(String directory, Integer folder, Callback callback) {
try {
if (folder != 0) throw new Exception("Only NSDocumentDirectory supported");
String folderPath = this.getReactApplicationContext().getFilesDir().getAbsolutePath();
File file = new File(folderPath, directory);
File[] files = file.listFiles();
WritableArray fileMaps = Arguments.createArray();
for (File childFile : files) {
WritableMap fileMap = Arguments.createMap();
fileMap.putString("name", childFile.getName());
fileMap.putString("path", childFile.getAbsolutePath());
fileMaps.pushMap(fileMap);
}
callback.invoke(null, fileMaps);
} catch (Exception ex) {
ex.printStackTrace();
callback.invoke(makeErrorPayload(ex));
}
}
@ReactMethod
public void stat(String filepath, Callback callback) {
try {
File file = new File(filepath);
if (!file.exists()) throw new Exception("File does not exist");
WritableMap statMap = Arguments.createMap();
statMap.putInt("ctime", (int)(file.lastModified() / 1000));
statMap.putInt("mtime", (int)(file.lastModified() / 1000));
statMap.putInt("size", (int)file.length());
statMap.putInt("type", file.isDirectory() ? 1 : 0);
callback.invoke(null, statMap);
} catch (Exception ex) {
ex.printStackTrace();
callback.invoke(makeErrorPayload(ex));
}
}
@ReactMethod
public void unlink(String filepath, Callback callback) {
try {
File file = new File(filepath);
if (!file.exists()) throw new Exception("File does not exist");
boolean success = file.delete();
callback.invoke(null, success, filepath);
} catch (Exception ex) {
ex.printStackTrace();
callback.invoke(makeErrorPayload(ex));
}
}
@ReactMethod
public void pathForBundle(String bundleNamed, Callback callback) {
// TODO: Not sure what equilivent would be?
}
private WritableMap makeErrorPayload(Exception ex) {
WritableMap error = Arguments.createMap();
error.putString("message", ex.getMessage());
return error;
}
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(NSDocumentDirectory, 0);
constants.put(NSDocumentDirectoryPath, this.getReactApplicationContext().getFilesDir().getAbsolutePath());
constants.put(NSFileTypeRegular, 0);
constants.put(NSFileTypeDirectory, 1);
return constants;
}
}

View File

@ -0,0 +1,29 @@
package com.rnfs;
import java.util.*;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
public class RNFSPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new RNFSManager(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList();
}
}

View File

@ -2,7 +2,7 @@
"name": "react-native-fs",
"version": "0.3.4",
"description": "Native filesystem access for react-native",
"main": "FS.ios.js",
"main": "FS.common.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
@ -14,6 +14,7 @@
"react-component",
"react-native",
"ios",
"android",
"fs",
"filesystem"
],