├── index.js
├── android
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── sensors
│ │ ├── RNSensorsPackage.java
│ │ ├── Gyroscope.java
│ │ └── Accelerometer.java
└── build.gradle
├── package.json
├── ios
├── Gyroscope.h
├── Accelerometer.h
├── Gyroscope.m
├── Accelerometer.m
└── RNSensors.xcodeproj
│ └── project.pbxproj
├── .gitignore
├── src
├── sensors.js
└── decorator.js
└── README.md
/index.js:
--------------------------------------------------------------------------------
1 | import Sensors from './src/sensors';
2 | import decorator from './src/decorator';
3 |
4 | export default {
5 | ...Sensors,
6 | decorator,
7 | };
8 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-sensors",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "keywords": [
7 | "react-native"
8 | ],
9 | "author": "",
10 | "license": "",
11 | "peerDependencies": {
12 | "react-native": "^0.40.0"
13 | },
14 | "dependencies": {
15 | "rxjs": "^5.0.2"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ios/Gyroscope.h:
--------------------------------------------------------------------------------
1 | // Inspired by https://github.com/pwmckenna/react-native-motion-manager
2 |
3 | #import
4 | #import
5 |
6 | @interface Gyroscope : NSObject {
7 | CMMotionManager *_motionManager;
8 | }
9 |
10 | - (void) setUpdateInterval:(double) interval;
11 | - (void) getUpdateInterval:(RCTResponseSenderBlock) cb;
12 | - (void) getData:(RCTResponseSenderBlock) cb;
13 | - (void) startUpdates;
14 | - (void) stopUpdates;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ios/Accelerometer.h:
--------------------------------------------------------------------------------
1 | // Inspired by https://github.com/pwmckenna/react-native-motion-manager
2 |
3 | #import
4 | #import
5 |
6 | @interface Accelerometer : NSObject {
7 | CMMotionManager *_motionManager;
8 | }
9 |
10 | - (void) setUpdateInterval:(double) interval;
11 | - (void) getUpdateInterval:(RCTResponseSenderBlock) cb;
12 | - (void) getData:(RCTResponseSenderBlock) cb;
13 | - (void) startUpdates;
14 | - (void) stopUpdates;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | apply plugin: 'com.android.library'
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.1"
7 |
8 | defaultConfig {
9 | minSdkVersion 16
10 | targetSdkVersion 22
11 | versionCode 1
12 | versionName "1.0"
13 | ndk {
14 | abiFilters "armeabi-v7a", "x86"
15 | }
16 | }
17 | lintOptions {
18 | warning 'InvalidPackage'
19 | }
20 | }
21 |
22 | dependencies {
23 | compile 'com.facebook.react:react-native:0.20.+'
24 | }
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IJ
26 | #
27 | *.iml
28 | .idea
29 | .gradle
30 | local.properties
31 |
32 | # node.js
33 | #
34 | node_modules/
35 | npm-debug.log
36 |
37 | # BUCK
38 | buck-out/
39 | \.buckd/
40 | android/app/libs
41 | android/keystores/debug.keystore
42 |
--------------------------------------------------------------------------------
/android/src/main/java/com/sensors/RNSensorsPackage.java:
--------------------------------------------------------------------------------
1 |
2 | package com.sensors;
3 |
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.bridge.NativeModule;
10 | import com.facebook.react.bridge.ReactApplicationContext;
11 | import com.facebook.react.uimanager.ViewManager;
12 | import com.facebook.react.bridge.JavaScriptModule;
13 | public class RNSensorsPackage implements ReactPackage {
14 | @Override
15 | public List createNativeModules(ReactApplicationContext reactContext) {
16 | return Arrays.asList(new Gyroscope(reactContext), new Accelerometer(reactContext));
17 | }
18 |
19 | @Override
20 | public List> createJSModules() {
21 | return Collections.emptyList();
22 | }
23 |
24 | @Override
25 | public List createViewManagers(ReactApplicationContext reactContext) {
26 | return Collections.emptyList();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/sensors.js:
--------------------------------------------------------------------------------
1 | import { NativeModules, DeviceEventEmitter } from 'react-native';
2 | import Rx from 'rxjs/Rx';
3 | const { Gyroscope: GyroNative, Accelerometer: AccNative } = NativeModules;
4 |
5 | const handle = {
6 | Accelerometer: AccNative,
7 | Gyroscope: GyroNative,
8 | };
9 |
10 | const RNSensors = {
11 | start: function (type, updateInterval) {
12 | const api = handle[type];
13 | api.setUpdateInterval(updateInterval);
14 | api.startUpdates();
15 | },
16 |
17 | stop: function (type) {
18 | const api = handle[type];
19 | api.stopUpdates();
20 | },
21 | };
22 |
23 | function createSensorMonitorCreator(sensorType) {
24 | function Creator(options = {}) {
25 | const {
26 | updateInterval = 100, // time in ms
27 | } = (options || {});
28 | let observer;
29 | // Start the sensor manager
30 | RNSensors.start(sensorType, updateInterval);
31 |
32 | // Instanciate observable
33 | const observable = Rx.Observable.create(function (obs) {
34 | observer = obs;
35 | DeviceEventEmitter.addListener(sensorType, function(data) {
36 | observer.next(data);
37 | });
38 | })
39 |
40 | // Stop the sensor manager
41 | observable.stop = () => {
42 | RNSensors.stop(sensorType);
43 | observer.complete();
44 | };
45 |
46 | return observable;
47 | }
48 |
49 | return Creator;
50 | }
51 |
52 | // TODO: lazily intialize them (maybe via getter)
53 | const Accelerometer = createSensorMonitorCreator('Accelerometer');
54 | const Gyroscope = createSensorMonitorCreator('Gyroscope');
55 | const Magnetometer = createSensorMonitorCreator('Magnetometer');
56 |
57 | export default {
58 | Accelerometer,
59 | Gyroscope,
60 | Magnetometer,
61 | };
62 |
--------------------------------------------------------------------------------
/src/decorator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Sensors from './sensors';
3 |
4 | const AVAILABLE_SENSORS = ['Accelerometer', 'Gyroscope'];
5 | const optionsType = React.PropTypes.shape({
6 | updateInterval: React.PropTypes.number,
7 | });
8 |
9 | class SensorWrapper extends React.Component {
10 | static propTypes = {
11 | children: React.PropTypes.node.isRequired,
12 | sensors: React.PropTypes.shape({
13 | Accelerometer: React.PropTypes.oneOfType([
14 | React.PropTypes.bool,
15 | optionsType,
16 | ]),
17 | Gyroscope: React.PropTypes.oneOfType([
18 | React.PropTypes.bool,
19 | optionsType,
20 | ]),
21 | Magnetometer: React.PropTypes.oneOfType([
22 | React.PropTypes.bool,
23 | optionsType,
24 | ]),
25 | }),
26 | }
27 |
28 | constructor(props) {
29 | super(props);
30 | this.state = {
31 | _observables: [],
32 | };
33 | }
34 |
35 | componentWillMount() {
36 | const observables = [];
37 | Object.entries(this.props.sensors).forEach(([name, sensorOptions]) => {
38 | const options = typeof(sensorOptions) === 'boolean' ? null : sensorOptions;
39 | const observable = new Sensors[name](options);
40 | observables.push(observable);
41 |
42 | observable.subscribe(sensorValue => {
43 | this.setState({
44 | [name]: sensorValue,
45 | });
46 | });
47 | });
48 |
49 | this.setState({
50 | _observables: observables,
51 | });
52 | }
53 |
54 | componentWillUnmount() {
55 | this.state._observables.forEach(observable => observable.stop());
56 | }
57 |
58 | render() {
59 | return React.cloneElement(this.props.children, this.state);
60 | }
61 | }
62 |
63 | export default function decorator(options = {}) {
64 | const sensors = Object.keys(options)
65 | .filter(key => AVAILABLE_SENSORS.includes(key))
66 | .filter(key => options[key])
67 | .reduce((carry, key) => {
68 | carry[key] = options[key];
69 | return carry
70 | }, {});
71 |
72 | return Component => props => (
73 |
74 |
75 |
76 | )
77 | }
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # react-native-sensors
3 |
4 | ## Getting started
5 |
6 | `$ npm install react-native-sensors --save`
7 |
8 | ### Mostly automatic installation
9 |
10 | `$ react-native link react-native-sensors`
11 |
12 | ### Manual installation
13 |
14 | #### iOS
15 |
16 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
17 | 2. Go to `node_modules` ➜ `react-native-sensors` and add `RNSensors.xcodeproj`
18 | 3. In XCode, in the project navigator, select your project. Add `libRNSensors.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
19 | 4. Run your project (`Cmd+R`)<
20 |
21 | #### Android
22 |
23 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
24 | - Add `import com.reactlibrary.RNSensorsPackage;` to the imports at the top of the file
25 | - Add `new RNSensorsPackage()` to the list returned by the `getPackages()` method
26 | 2. Append the following lines to `android/settings.gradle`:
27 | ```
28 | include ':react-native-sensors'
29 | project(':react-native-sensors').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sensors/android')
30 | ```
31 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
32 | ```
33 | compile project(':react-native-sensors')
34 | ```
35 |
36 | ## Usage
37 |
38 | ### Sensor API
39 |
40 | ```javascript
41 | import { Accelerometer, Gyroscope } from 'react-native-sensors';
42 | const accelerationObservable = new Accelerometer({
43 | updateInterval: 100, // defaults to 100ms
44 | });
45 |
46 | // Normal RxJS functions
47 | accelerationObservable
48 | .map(({ x, y, z }) => x + y + z)
49 | .filter(speed => speed > 20)
50 | .subscribe(speed => console.log(`You moved your phone with ${speed}`));
51 |
52 | setTimeout(() => {
53 | accelerationObservable.stop();
54 | }, 1000);
55 | ```
56 |
57 | ### Decorator usage
58 |
59 | ```javascript
60 | import React, { Component } from 'react';
61 | import { Text, View } from 'react-native';
62 | import { decorator as sensors } from 'react-native-sensors';
63 |
64 | class MyComponent { // no lifecycle needed
65 | render() {
66 | const {
67 | Accelerometer,
68 | Gyroscope,
69 | } = this.props;
70 |
71 | return (
72 |
73 |
74 | Acceleration has value: {Accelerometer}
75 | Gyro has value: {Gyroscope}
76 |
77 |
78 | );
79 | }
80 | }
81 |
82 | export default sensors({
83 | Accelerometer: {
84 | updateInterval: 300, // optional
85 | },
86 | Gyroscope: true,
87 | Magnetometer: false, // disabled
88 | })(MyComponent);
89 | ```
90 |
91 | ## Credits
92 |
93 | This project is inspired by the [react-native-sensor-manager](https://github.com/kprimice/react-native-sensor-manager) and by the [react-native-motion-manager](https://github.com/pwmckenna/react-native-motion-manager). Both have similar solutions with a non-uniform interface and this project aims to unify both.
94 |
--------------------------------------------------------------------------------
/android/src/main/java/com/sensors/Gyroscope.java:
--------------------------------------------------------------------------------
1 | package com.sensors;
2 |
3 | import android.os.Bundle;
4 | import android.hardware.Sensor;
5 | import android.hardware.SensorEvent;
6 | import android.hardware.SensorEventListener;
7 | import android.hardware.SensorManager;
8 | import android.util.Log;
9 | import android.support.annotation.Nullable;
10 |
11 | import com.facebook.react.bridge.Arguments;
12 | import com.facebook.react.bridge.ReactApplicationContext;
13 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
14 | import com.facebook.react.bridge.ReactMethod;
15 | import com.facebook.react.bridge.WritableMap;
16 | import com.facebook.react.bridge.Callback;
17 | import com.facebook.react.modules.core.DeviceEventManagerModule;
18 |
19 | public class Gyroscope extends ReactContextBaseJavaModule implements SensorEventListener {
20 |
21 | private final ReactApplicationContext reactContext;
22 | private final SensorManager sensorManager;
23 | private final Sensor sensor;
24 | private int interval;
25 | private Arguments arguments;
26 |
27 | public Gyroscope(ReactApplicationContext reactContext) {
28 | super(reactContext);
29 | this.reactContext = reactContext;
30 | this.sensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE);
31 | this.sensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
32 |
33 | if (this.sensor == null) {
34 | // No sensor found, throw error
35 | throw new RuntimeException("No Gyroscope found");
36 | }
37 | }
38 |
39 | // RN Methods
40 | @ReactMethod
41 | public void setUpdateInterval(int newInterval) {
42 | this.interval = newInterval;
43 | }
44 |
45 | @ReactMethod
46 | public void startUpdates() {
47 | // Milisecond to Mikrosecond conversion
48 | sensorManager.registerListener(this, sensor, this.interval * 1000);
49 | }
50 |
51 | @ReactMethod
52 | public void stopUpdates() {
53 | sensorManager.unregisterListener(this);
54 | }
55 |
56 | @Override
57 | public String getName() {
58 | return "Gyroscope";
59 | }
60 |
61 | // SensorEventListener Interface
62 | private void sendEvent(String eventName, @Nullable WritableMap params) {
63 | try {
64 | this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
65 | .emit(eventName, params);
66 | } catch (RuntimeException e) {
67 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke Javascript before CatalystInstance has been set!");
68 | }
69 | }
70 |
71 | @Override
72 | public void onSensorChanged(SensorEvent sensorEvent) {
73 | Sensor mySensor = sensorEvent.sensor;
74 | WritableMap map = arguments.createMap();
75 |
76 | if (mySensor.getType() == Sensor.TYPE_GYROSCOPE) {
77 | map.putDouble("x", sensorEvent.values[0]);
78 | map.putDouble("y", sensorEvent.values[1]);
79 | map.putDouble("z", sensorEvent.values[2]);
80 | map.putDouble("timestamp", (double) System.currentTimeMillis());
81 | sendEvent("Gyroscope", map);
82 | }
83 | }
84 |
85 | @Override
86 | public void onAccuracyChanged(Sensor sensor, int accuracy) {
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/android/src/main/java/com/sensors/Accelerometer.java:
--------------------------------------------------------------------------------
1 | package com.sensors;
2 |
3 | import android.os.Bundle;
4 | import android.hardware.Sensor;
5 | import android.hardware.SensorEvent;
6 | import android.hardware.SensorEventListener;
7 | import android.hardware.SensorManager;
8 | import android.util.Log;
9 | import android.support.annotation.Nullable;
10 |
11 | import com.facebook.react.bridge.Arguments;
12 | import com.facebook.react.bridge.ReactApplicationContext;
13 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
14 | import com.facebook.react.bridge.ReactMethod;
15 | import com.facebook.react.bridge.WritableMap;
16 | import com.facebook.react.bridge.Callback;
17 | import com.facebook.react.modules.core.DeviceEventManagerModule;
18 |
19 | public class Accelerometer extends ReactContextBaseJavaModule implements SensorEventListener {
20 |
21 | private final ReactApplicationContext reactContext;
22 | private final SensorManager sensorManager;
23 | private final Sensor sensor;
24 | private int interval;
25 | private Arguments arguments;
26 |
27 | public Accelerometer(ReactApplicationContext reactContext) {
28 | super(reactContext);
29 | this.reactContext = reactContext;
30 | this.sensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE);
31 | this.sensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
32 |
33 | if (this.sensor == null) {
34 | // No sensor found, throw error
35 | throw new RuntimeException("No Accelerometer found");
36 | }
37 | }
38 |
39 | // RN Methods
40 | @ReactMethod
41 | public void setUpdateInterval(int newInterval) {
42 | this.interval = newInterval;
43 | }
44 |
45 | @ReactMethod
46 | public void startUpdates() {
47 | // Milisecond to Mikrosecond conversion
48 | sensorManager.registerListener(this, sensor, this.interval * 1000);
49 | }
50 |
51 | @ReactMethod
52 | public void stopUpdates() {
53 | sensorManager.unregisterListener(this);
54 | }
55 |
56 | @Override
57 | public String getName() {
58 | return "Accelerometer";
59 | }
60 |
61 | // SensorEventListener Interface
62 | private void sendEvent(String eventName, @Nullable WritableMap params) {
63 | try {
64 | this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
65 | .emit(eventName, params);
66 | } catch (RuntimeException e) {
67 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke Javascript before CatalystInstance has been set!");
68 | }
69 | }
70 |
71 | @Override
72 | public void onSensorChanged(SensorEvent sensorEvent) {
73 | Sensor mySensor = sensorEvent.sensor;
74 | WritableMap map = arguments.createMap();
75 |
76 | if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
77 | map.putDouble("x", sensorEvent.values[0]);
78 | map.putDouble("y", sensorEvent.values[1]);
79 | map.putDouble("z", sensorEvent.values[2]);
80 | map.putDouble("timestamp", (double) System.currentTimeMillis());
81 | sendEvent("Accelerometer", map);
82 | }
83 | }
84 |
85 | @Override
86 | public void onAccuracyChanged(Sensor sensor, int accuracy) {
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/ios/Gyroscope.m:
--------------------------------------------------------------------------------
1 | // Inspired by https://github.com/pwmckenna/react-native-motion-manager
2 |
3 | #import "Gyroscope.h"
4 | #import
5 | #import
6 |
7 | @implementation Gyroscope
8 |
9 | @synthesize bridge = _bridge;
10 | RCT_EXPORT_MODULE();
11 |
12 | - (id) init {
13 | self = [super init];
14 | NSLog(@"Gyroscope");
15 |
16 | if (self) {
17 | self->_motionManager = [[CMMotionManager alloc] init];
18 | //Gyroscope
19 | if([self->_motionManager isGyroAvailable])
20 | {
21 | NSLog(@"Gyroscope available");
22 | /* Start the gyroscope if it is not active already */
23 | if([self->_motionManager isGyroActive] == NO)
24 | {
25 | NSLog(@"Gyroscope active");
26 | } else {
27 | NSLog(@"Gyroscope not active");
28 | }
29 | }
30 | else
31 | {
32 | NSLog(@"Gyroscope not Available!");
33 | }
34 | }
35 | return self;
36 | }
37 |
38 | RCT_EXPORT_METHOD(setUpdateInterval:(double) interval) {
39 | NSLog(@"setGyroUpdateInterval: %f", interval);
40 | double intervalInSeconds = interval * 1000;
41 |
42 | [self->_motionManager setGyroUpdateInterval:intervalInSeconds];
43 | }
44 |
45 | RCT_EXPORT_METHOD(getUpdateInterval:(RCTResponseSenderBlock) cb) {
46 | double interval = self->_motionManager.gyroUpdateInterval;
47 | NSLog(@"getUpdateInterval: %f", interval);
48 | cb(@[[NSNull null], [NSNumber numberWithDouble:interval]]);
49 | }
50 |
51 | RCT_EXPORT_METHOD(getData:(RCTResponseSenderBlock) cb) {
52 | double x = self->_motionManager.gyroData.rotationRate.x;
53 | double y = self->_motionManager.gyroData.rotationRate.y;
54 | double z = self->_motionManager.gyroData.rotationRate.z;
55 | double timestamp = self->_motionManager.gyroData.timestamp;
56 |
57 | NSLog(@"getData: %f, %f, %f, %f", x, y, z, timestamp);
58 |
59 | cb(@[[NSNull null], @{
60 | @"x" : [NSNumber numberWithDouble:x],
61 | @"y" : [NSNumber numberWithDouble:y],
62 | @"z" : [NSNumber numberWithDouble:z],
63 | @"timestamp" : [NSNumber numberWithDouble:timestamp]
64 | }]
65 | );
66 | }
67 |
68 | RCT_EXPORT_METHOD(startUpdates) {
69 | NSLog(@"startUpdates");
70 | [self->_motionManager startGyroUpdates];
71 |
72 | /* Receive the gyroscope data on this block */
73 | [self->_motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
74 | withHandler:^(CMGyroData *gyroData, NSError *error)
75 | {
76 | double x = gyroData.rotationRate.x;
77 | double y = gyroData.rotationRate.y;
78 | double z = gyroData.rotationRate.z;
79 | double timestamp = gyroData.timestamp;
80 | NSLog(@"startUpdates: %f, %f, %f, %f", x, y, z, timestamp);
81 |
82 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"Gyroscope" body:@{
83 | @"x" : [NSNumber numberWithDouble:x],
84 | @"y" : [NSNumber numberWithDouble:y],
85 | @"z" : [NSNumber numberWithDouble:z],
86 | @"timestamp" : [NSNumber numberWithDouble:timestamp]
87 | }];
88 | }];
89 |
90 | }
91 |
92 | RCT_EXPORT_METHOD(stopUpdates) {
93 | NSLog(@"stopUpdates");
94 | [self->_motionManager stopGyroUpdates];
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/ios/Accelerometer.m:
--------------------------------------------------------------------------------
1 |
2 | // Accelerometer.m
3 |
4 |
5 | #import
6 | #import
7 | #import "Accelerometer.h"
8 |
9 | @implementation Accelerometer
10 |
11 | @synthesize bridge = _bridge;
12 |
13 | RCT_EXPORT_MODULE();
14 |
15 | - (id) init {
16 | self = [super init];
17 | NSLog(@"Accelerometer");
18 |
19 | if (self) {
20 | self->_motionManager = [[CMMotionManager alloc] init];
21 | //Accelerometer
22 | if([self->_motionManager isAccelerometerAvailable])
23 | {
24 | NSLog(@"Accelerometer available");
25 | /* Start the accelerometer if it is not active already */
26 | if([self->_motionManager isAccelerometerActive] == NO)
27 | {
28 | NSLog(@"Accelerometer active");
29 | } else {
30 | NSLog(@"Accelerometer not active");
31 | }
32 | }
33 | else
34 | {
35 | NSLog(@"Accelerometer not available!");
36 | }
37 | }
38 | return self;
39 | }
40 |
41 | RCT_EXPORT_METHOD(setUpdateInterval:(double) interval) {
42 | NSLog(@"setUpdateInterval: %f", interval);
43 | double intervalInSeconds = interval * 1000;
44 |
45 | [self->_motionManager setAccelerometerUpdateInterval:intervalInSeconds];
46 | }
47 |
48 | RCT_EXPORT_METHOD(getUpdateInterval:(RCTResponseSenderBlock) cb) {
49 | double interval = self->_motionManager.accelerometerUpdateInterval;
50 | NSLog(@"getUpdateInterval: %f", interval);
51 | cb(@[[NSNull null], [NSNumber numberWithDouble:interval]]);
52 | }
53 |
54 | RCT_EXPORT_METHOD(getData:(RCTResponseSenderBlock) cb) {
55 | double x = self->_motionManager.accelerometerData.acceleration.x;
56 | double y = self->_motionManager.accelerometerData.acceleration.y;
57 | double z = self->_motionManager.accelerometerData.acceleration.z;
58 | double timestamp = self->_motionManager.accelerometerData.timestamp;
59 |
60 | NSLog(@"getData: %f, %f, %f, %f", x, y, z, timestamp);
61 |
62 | cb(@[[NSNull null], @{
63 | @"x" : [NSNumber numberWithDouble:x],
64 | @"y" : [NSNumber numberWithDouble:y],
65 | @"z" : [NSNumber numberWithDouble:z],
66 | @"timestamp" : [NSNumber numberWithDouble:timestamp]
67 | }]
68 | );
69 | }
70 |
71 | RCT_EXPORT_METHOD(startUpdates) {
72 | NSLog(@"startUpdates");
73 | [self->_motionManager startAccelerometerUpdates];
74 |
75 | /* Receive the ccelerometer data on this block */
76 | [self->_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]
77 | withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
78 | {
79 | double x = accelerometerData.acceleration.x;
80 | double y = accelerometerData.acceleration.y;
81 | double z = accelerometerData.acceleration.z;
82 | double timestamp = accelerometerData.timestamp;
83 | NSLog(@"startAccelerometerUpdates: %f, %f, %f, %f", x, y, z, timestamp);
84 |
85 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"Accelerometer" body:@{
86 | @"x" : [NSNumber numberWithDouble:x],
87 | @"y" : [NSNumber numberWithDouble:y],
88 | @"z" : [NSNumber numberWithDouble:z],
89 | @"timestamp" : [NSNumber numberWithDouble:timestamp]
90 | }];
91 | }];
92 |
93 | }
94 |
95 | RCT_EXPORT_METHOD(stopUpdates) {
96 | NSLog(@"stopUpdates");
97 | [self->_motionManager stopAccelerometerUpdates];
98 | }
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/ios/RNSensors.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E7FCE1881E14639E005C5155 /* Gyroscope.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FCE1871E14639E005C5155 /* Gyroscope.m */; };
11 | E7FCE18B1E150266005C5155 /* Accelerometer.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FCE18A1E150266005C5155 /* Accelerometer.m */; };
12 | /* End PBXBuildFile section */
13 |
14 | /* Begin PBXCopyFilesBuildPhase section */
15 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
16 | isa = PBXCopyFilesBuildPhase;
17 | buildActionMask = 2147483647;
18 | dstPath = "include/$(PRODUCT_NAME)";
19 | dstSubfolderSpec = 16;
20 | files = (
21 | );
22 | runOnlyForDeploymentPostprocessing = 0;
23 | };
24 | /* End PBXCopyFilesBuildPhase section */
25 |
26 | /* Begin PBXFileReference section */
27 | 134814201AA4EA6300B7C361 /* libRNSensors.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNSensors.a; sourceTree = BUILT_PRODUCTS_DIR; };
28 | E7FCE1861E14639E005C5155 /* Gyroscope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gyroscope.h; sourceTree = ""; };
29 | E7FCE1871E14639E005C5155 /* Gyroscope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Gyroscope.m; sourceTree = ""; };
30 | E7FCE1891E150266005C5155 /* Accelerometer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Accelerometer.h; sourceTree = ""; };
31 | E7FCE18A1E150266005C5155 /* Accelerometer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Accelerometer.m; sourceTree = ""; };
32 | /* End PBXFileReference section */
33 |
34 | /* Begin PBXFrameworksBuildPhase section */
35 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
36 | isa = PBXFrameworksBuildPhase;
37 | buildActionMask = 2147483647;
38 | files = (
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | 134814211AA4EA7D00B7C361 /* Products */ = {
46 | isa = PBXGroup;
47 | children = (
48 | 134814201AA4EA6300B7C361 /* libRNSensors.a */,
49 | );
50 | name = Products;
51 | sourceTree = "";
52 | };
53 | 58B511D21A9E6C8500147676 = {
54 | isa = PBXGroup;
55 | children = (
56 | E7FCE1891E150266005C5155 /* Accelerometer.h */,
57 | E7FCE18A1E150266005C5155 /* Accelerometer.m */,
58 | E7FCE1861E14639E005C5155 /* Gyroscope.h */,
59 | E7FCE1871E14639E005C5155 /* Gyroscope.m */,
60 | 134814211AA4EA7D00B7C361 /* Products */,
61 | );
62 | sourceTree = "";
63 | };
64 | /* End PBXGroup section */
65 |
66 | /* Begin PBXNativeTarget section */
67 | 58B511DA1A9E6C8500147676 /* RNSensors */ = {
68 | isa = PBXNativeTarget;
69 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNSensors" */;
70 | buildPhases = (
71 | 58B511D71A9E6C8500147676 /* Sources */,
72 | 58B511D81A9E6C8500147676 /* Frameworks */,
73 | 58B511D91A9E6C8500147676 /* CopyFiles */,
74 | );
75 | buildRules = (
76 | );
77 | dependencies = (
78 | );
79 | name = RNSensors;
80 | productName = RCTDataManager;
81 | productReference = 134814201AA4EA6300B7C361 /* libRNSensors.a */;
82 | productType = "com.apple.product-type.library.static";
83 | };
84 | /* End PBXNativeTarget section */
85 |
86 | /* Begin PBXProject section */
87 | 58B511D31A9E6C8500147676 /* Project object */ = {
88 | isa = PBXProject;
89 | attributes = {
90 | LastUpgradeCheck = 0610;
91 | ORGANIZATIONNAME = Facebook;
92 | TargetAttributes = {
93 | 58B511DA1A9E6C8500147676 = {
94 | CreatedOnToolsVersion = 6.1.1;
95 | };
96 | };
97 | };
98 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNSensors" */;
99 | compatibilityVersion = "Xcode 3.2";
100 | developmentRegion = English;
101 | hasScannedForEncodings = 0;
102 | knownRegions = (
103 | en,
104 | );
105 | mainGroup = 58B511D21A9E6C8500147676;
106 | productRefGroup = 58B511D21A9E6C8500147676;
107 | projectDirPath = "";
108 | projectRoot = "";
109 | targets = (
110 | 58B511DA1A9E6C8500147676 /* RNSensors */,
111 | );
112 | };
113 | /* End PBXProject section */
114 |
115 | /* Begin PBXSourcesBuildPhase section */
116 | 58B511D71A9E6C8500147676 /* Sources */ = {
117 | isa = PBXSourcesBuildPhase;
118 | buildActionMask = 2147483647;
119 | files = (
120 | E7FCE1881E14639E005C5155 /* Gyroscope.m in Sources */,
121 | E7FCE18B1E150266005C5155 /* Accelerometer.m in Sources */,
122 | );
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | /* End PBXSourcesBuildPhase section */
126 |
127 | /* Begin XCBuildConfiguration section */
128 | 58B511ED1A9E6C8500147676 /* Debug */ = {
129 | isa = XCBuildConfiguration;
130 | buildSettings = {
131 | ALWAYS_SEARCH_USER_PATHS = NO;
132 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
133 | CLANG_CXX_LIBRARY = "libc++";
134 | CLANG_ENABLE_MODULES = YES;
135 | CLANG_ENABLE_OBJC_ARC = YES;
136 | CLANG_WARN_BOOL_CONVERSION = YES;
137 | CLANG_WARN_CONSTANT_CONVERSION = YES;
138 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
139 | CLANG_WARN_EMPTY_BODY = YES;
140 | CLANG_WARN_ENUM_CONVERSION = YES;
141 | CLANG_WARN_INT_CONVERSION = YES;
142 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
143 | CLANG_WARN_UNREACHABLE_CODE = YES;
144 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
145 | COPY_PHASE_STRIP = NO;
146 | ENABLE_STRICT_OBJC_MSGSEND = YES;
147 | GCC_C_LANGUAGE_STANDARD = gnu99;
148 | GCC_DYNAMIC_NO_PIC = NO;
149 | GCC_OPTIMIZATION_LEVEL = 0;
150 | GCC_PREPROCESSOR_DEFINITIONS = (
151 | "DEBUG=1",
152 | "$(inherited)",
153 | );
154 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
155 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
156 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
157 | GCC_WARN_UNDECLARED_SELECTOR = YES;
158 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
159 | GCC_WARN_UNUSED_FUNCTION = YES;
160 | GCC_WARN_UNUSED_VARIABLE = YES;
161 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
162 | MTL_ENABLE_DEBUG_INFO = YES;
163 | ONLY_ACTIVE_ARCH = YES;
164 | SDKROOT = iphoneos;
165 | };
166 | name = Debug;
167 | };
168 | 58B511EE1A9E6C8500147676 /* Release */ = {
169 | isa = XCBuildConfiguration;
170 | buildSettings = {
171 | ALWAYS_SEARCH_USER_PATHS = NO;
172 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
173 | CLANG_CXX_LIBRARY = "libc++";
174 | CLANG_ENABLE_MODULES = YES;
175 | CLANG_ENABLE_OBJC_ARC = YES;
176 | CLANG_WARN_BOOL_CONVERSION = YES;
177 | CLANG_WARN_CONSTANT_CONVERSION = YES;
178 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
179 | CLANG_WARN_EMPTY_BODY = YES;
180 | CLANG_WARN_ENUM_CONVERSION = YES;
181 | CLANG_WARN_INT_CONVERSION = YES;
182 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
183 | CLANG_WARN_UNREACHABLE_CODE = YES;
184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
185 | COPY_PHASE_STRIP = YES;
186 | ENABLE_NS_ASSERTIONS = NO;
187 | ENABLE_STRICT_OBJC_MSGSEND = YES;
188 | GCC_C_LANGUAGE_STANDARD = gnu99;
189 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
190 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
191 | GCC_WARN_UNDECLARED_SELECTOR = YES;
192 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
193 | GCC_WARN_UNUSED_FUNCTION = YES;
194 | GCC_WARN_UNUSED_VARIABLE = YES;
195 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
196 | MTL_ENABLE_DEBUG_INFO = NO;
197 | SDKROOT = iphoneos;
198 | VALIDATE_PRODUCT = YES;
199 | };
200 | name = Release;
201 | };
202 | 58B511F01A9E6C8500147676 /* Debug */ = {
203 | isa = XCBuildConfiguration;
204 | buildSettings = {
205 | HEADER_SEARCH_PATHS = (
206 | "$(inherited)",
207 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
208 | );
209 | LIBRARY_SEARCH_PATHS = "$(inherited)";
210 | OTHER_LDFLAGS = "-ObjC";
211 | PRODUCT_NAME = RNSensors;
212 | SKIP_INSTALL = YES;
213 | };
214 | name = Debug;
215 | };
216 | 58B511F11A9E6C8500147676 /* Release */ = {
217 | isa = XCBuildConfiguration;
218 | buildSettings = {
219 | HEADER_SEARCH_PATHS = (
220 | "$(inherited)",
221 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
222 | );
223 | LIBRARY_SEARCH_PATHS = "$(inherited)";
224 | OTHER_LDFLAGS = "-ObjC";
225 | PRODUCT_NAME = RNSensors;
226 | SKIP_INSTALL = YES;
227 | };
228 | name = Release;
229 | };
230 | /* End XCBuildConfiguration section */
231 |
232 | /* Begin XCConfigurationList section */
233 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNSensors" */ = {
234 | isa = XCConfigurationList;
235 | buildConfigurations = (
236 | 58B511ED1A9E6C8500147676 /* Debug */,
237 | 58B511EE1A9E6C8500147676 /* Release */,
238 | );
239 | defaultConfigurationIsVisible = 0;
240 | defaultConfigurationName = Release;
241 | };
242 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNSensors" */ = {
243 | isa = XCConfigurationList;
244 | buildConfigurations = (
245 | 58B511F01A9E6C8500147676 /* Debug */,
246 | 58B511F11A9E6C8500147676 /* Release */,
247 | );
248 | defaultConfigurationIsVisible = 0;
249 | defaultConfigurationName = Release;
250 | };
251 | /* End XCConfigurationList section */
252 | };
253 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
254 | }
255 |
--------------------------------------------------------------------------------