├── .gitignore ├── README.md ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── sensormanager │ ├── AccelerometerRecord.java │ ├── GyroscopeRecord.java │ ├── LightSensorRecord.java │ ├── MagnetometerRecord.java │ ├── MotionValueRecord.java │ ├── OrientationRecord.java │ ├── ProximityRecord.java │ ├── SensorManagerModule.java │ ├── SensorManagerPackage.java │ ├── StepCounterRecord.java │ └── ThermometerRecord.java ├── package.json └── react-native-sensor-manager.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | android/build 2 | **/*.swp 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | react-native-sensor-manager 2 | ============================ 3 | 4 | Wrapper for react-native. Accelerometer, Gyroscope, Magnetometer, Orientation, Step Counter, Thermometer, LightSensor, and Proximity Sensor are supported for now. 5 | 6 | Add it to your project 7 | ------------------------- 8 | 9 | `$ npm i react-native-sensor-manager --save` 10 | 11 | ### Option: With [`rnpm`](https://github.com/rnpm/rnpm) 12 | 13 | `rnpm link` 14 | 15 | ### Option: Manually (try it if an runtime error occurs after `nrpm link`) 16 | 17 | Make alterations to the following files: 18 | 19 | * `android/settings.gradle` 20 | 21 | ```gradle 22 | ... 23 | include ':react-native-sensor-manager' 24 | project(':react-native-sensor-manager').projectDir = new File(settingsDir, '../node_modules/react-native-sensor-manager/android') 25 | ``` 26 | 27 | * `android/app/build.gradle` 28 | 29 | ```gradle 30 | ... 31 | dependencies { 32 | ... 33 | compile project(':react-native-sensor-manager') 34 | } 35 | ``` 36 | 37 | * register module (in MainApplication.java) 38 | 39 | * For react-native below 0.19.0 (use `cat ./node_modules/react-native/package.json | grep version`) 40 | 41 | ```java 42 | import com.sensormanager.SensorManagerPackage; // <------ add package 43 | 44 | public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { 45 | 46 | ...... 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | mReactRootView = new ReactRootView(this); 52 | 53 | mReactInstanceManager = ReactInstanceManager.builder() 54 | .setApplication(getApplication()) 55 | .setBundleAssetName("index.android.bundle") 56 | .setJSMainModuleName("index.android") 57 | .addPackage(new MainReactPackage()) 58 | .addPackage(new SensorManagerPackage()) // <------- add package 59 | .setUseDeveloperSupport(BuildConfig.DEBUG) 60 | .setInitialLifecycleState(LifecycleState.RESUMED) 61 | .build(); 62 | 63 | mReactRootView.startReactApplication(mReactInstanceManager, "ExampleRN", null); 64 | 65 | setContentView(mReactRootView); 66 | } 67 | 68 | ...... 69 | 70 | } 71 | ``` 72 | 73 | * For react-native 0.19.0 and higher 74 | ```java 75 | import com.sensormanager.SensorManagerPackage; // <------ add package 76 | 77 | public class MainApplication extends Application implements ReactApplication { 78 | // ... 79 | @Override 80 | protected List getPackages() { 81 | return Arrays.asList( 82 | new MainReactPackage(), // <---- add comma 83 | new SensorManagerPackage() // <---------- add package 84 | ); 85 | } 86 | ``` 87 | 88 | Api 89 | ---- 90 | 91 | ### Setup 92 | ```js 93 | import React, { 94 | DeviceEventEmitter // will emit events that you can listen to 95 | } from 'react-native'; 96 | 97 | import { SensorManager } from 'NativeModules'; 98 | ``` 99 | 100 | 101 | ### Accelerometer 102 | ```js 103 | SensorManager.startAccelerometer(100); // To start the accelerometer with a minimum delay of 100ms between events. 104 | DeviceEventEmitter.addListener('Accelerometer', function (data) { 105 | /** 106 | * data.x 107 | * data.y 108 | * data.z 109 | **/ 110 | }); 111 | SensorManager.stopAccelerometer(); 112 | ``` 113 | 114 | ### Gyroscope 115 | ```js 116 | DeviceEventEmitter.addListener('Gyroscope', function (data) { 117 | /** 118 | * data.x 119 | * data.y 120 | * data.z 121 | **/ 122 | }); 123 | SensorManager.startGyroscope(100); 124 | SensorManager.stopGyroscope(); 125 | ``` 126 | 127 | ### Magnetometer 128 | ```js 129 | SensorManager.startMagnetometer(100); 130 | DeviceEventEmitter.addListener('Magnetometer', function (data) { 131 | /** 132 | * data.x 133 | * data.y 134 | * data.z 135 | **/ 136 | }); 137 | SensorManager.stopMagnetometer(); 138 | ``` 139 | 140 | ### Orientation 141 | ```js 142 | SensorManager.startOrientation(100); 143 | DeviceEventEmitter.addListener('Orientation', function (data) { 144 | /** 145 | * data.azimuth 146 | * data.pitch 147 | * data.roll 148 | **/ 149 | }); 150 | SensorManager.stopOrientation(); 151 | ``` 152 | 153 | ### Step Counter 154 | ```js 155 | SensorManager.startStepCounter(1000); 156 | DeviceEventEmitter.addListener('StepCounter', function (data) { 157 | /** 158 | * data.steps 159 | **/ 160 | }); 161 | SensorManager.stopStepCounter(); 162 | ``` 163 | 164 | ### Thermometer 165 | ```js 166 | SensorManager.startThermometer(1000); 167 | DeviceEventEmitter.addListener('Thermometer', function (data) { 168 | /** 169 | * data.temp 170 | **/ 171 | }); 172 | SensorManager.stopThermometer(); 173 | ``` 174 | 175 | ### LightSensor 176 | ```js 177 | SensorManager.startLightSensor(100); 178 | DeviceEventEmitter.addListener('LightSensor', function (data) { 179 | /** 180 | * data.light 181 | **/ 182 | }); 183 | SensorManager.stopLightSensor(); 184 | ``` 185 | 186 | 187 | ### Proximity Sensor 188 | ```js 189 | SensorManager.startProximity(100); 190 | DeviceEventEmitter.addListener('Proximity', function (data) { 191 | /** 192 | * data.isNear: [Boolean] A flag representing whether something is near the screen. 193 | * data.value: [Number] The raw value returned by the sensor (usually distance in cm). 194 | * data.maxRange: [Number] The maximum range of the sensor. 195 | **/ 196 | }); 197 | SensorManager.stopProximity(); 198 | ``` 199 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | 6 | dependencies { 7 | classpath 'com.android.tools.build:gradle:1.1.3' 8 | } 9 | } 10 | 11 | apply plugin: 'com.android.library' 12 | 13 | android { 14 | compileSdkVersion 23 15 | buildToolsVersion "23.0.1" 16 | 17 | defaultConfig { 18 | minSdkVersion 16 19 | targetSdkVersion 22 20 | versionCode 1 21 | versionName "1.0" 22 | } 23 | lintOptions { 24 | abortOnError false 25 | } 26 | } 27 | 28 | repositories { 29 | mavenCentral() 30 | } 31 | 32 | dependencies { 33 | compile 'com.facebook.react:react-native:0.12.+' 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/AccelerometerRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class AccelerometerRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mAccelerometer; 25 | private long lastUpdate = 0; 26 | private int i = 0, n = 0; 27 | private int delay; 28 | private int isRegistered = 0; 29 | 30 | private ReactContext mReactContext; 31 | private Arguments mArguments; 32 | 33 | 34 | public AccelerometerRecord(ReactApplicationContext reactContext) { 35 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 36 | mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 37 | mReactContext = reactContext; 38 | } 39 | 40 | public int start(int delay) { 41 | this.delay = delay; 42 | if (mAccelerometer != null && isRegistered == 0) { 43 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST); 44 | isRegistered = 1; 45 | return (1); 46 | } 47 | return (0); 48 | } 49 | 50 | public void stop() { 51 | if (isRegistered == 1) { 52 | mSensorManager.unregisterListener(this); 53 | isRegistered = 0; 54 | } 55 | } 56 | 57 | private void sendEvent(String eventName, @Nullable WritableMap params) 58 | { 59 | try { 60 | mReactContext 61 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 62 | .emit(eventName, params); 63 | } catch (RuntimeException e) { 64 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 65 | } 66 | } 67 | 68 | @Override 69 | public void onSensorChanged(SensorEvent sensorEvent) { 70 | Sensor mySensor = sensorEvent.sensor; 71 | WritableMap map = mArguments.createMap(); 72 | 73 | if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { 74 | long curTime = System.currentTimeMillis(); 75 | i++; 76 | if ((curTime - lastUpdate) > delay) { 77 | i = 0; 78 | map.putDouble("x", sensorEvent.values[0]); 79 | map.putDouble("y", sensorEvent.values[1]); 80 | map.putDouble("z", sensorEvent.values[2]); 81 | sendEvent("Accelerometer", map); 82 | lastUpdate = curTime; 83 | } 84 | } 85 | } 86 | 87 | @Override 88 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/GyroscopeRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class GyroscopeRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mGyroscope; 25 | private long lastUpdate = 0; 26 | private int i = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | 33 | public GyroscopeRecord(ReactApplicationContext reactContext) { 34 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 35 | mReactContext = reactContext; 36 | } 37 | 38 | public int start(int delay) { 39 | this.delay = delay; 40 | if ((mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)) != null) { 41 | mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_FASTEST); 42 | return (1); 43 | } 44 | return (0); 45 | } 46 | 47 | public void stop() { 48 | mSensorManager.unregisterListener(this); 49 | } 50 | 51 | private void sendEvent(String eventName, @Nullable WritableMap params) 52 | { 53 | try { 54 | mReactContext 55 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 56 | .emit(eventName, params); 57 | } catch (RuntimeException e) { 58 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 59 | } 60 | } 61 | 62 | @Override 63 | public void onSensorChanged(SensorEvent sensorEvent) { 64 | Sensor mySensor = sensorEvent.sensor; 65 | WritableMap map = mArguments.createMap(); 66 | 67 | if (mySensor.getType() == Sensor.TYPE_GYROSCOPE) { 68 | long curTime = System.currentTimeMillis(); 69 | i++; 70 | if ((curTime - lastUpdate) > delay) { 71 | i = 0; 72 | map.putDouble("x", sensorEvent.values[0]); 73 | map.putDouble("y", sensorEvent.values[1]); 74 | map.putDouble("z", sensorEvent.values[2]); 75 | sendEvent("Gyroscope", map); 76 | lastUpdate = curTime; 77 | } 78 | } 79 | } 80 | 81 | @Override 82 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/LightSensorRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class LightSensorRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mLightSensor; 25 | private long lastUpdate = 0; 26 | private int i = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | public LightSensorRecord(ReactApplicationContext reactContext) { 33 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 34 | mReactContext = reactContext; 35 | } 36 | 37 | public int start(int delay) { 38 | this.delay = delay; 39 | if ((mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)) != null) { 40 | mSensorManager.registerListener(this, mLightSensor, SensorManager.SENSOR_DELAY_FASTEST); 41 | return (1); 42 | } 43 | return (0); 44 | } 45 | 46 | public void stop() { 47 | mSensorManager.unregisterListener(this); 48 | } 49 | 50 | private void sendEvent(String eventName, @Nullable WritableMap params) 51 | { 52 | try { 53 | mReactContext 54 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 55 | .emit(eventName, params); 56 | } catch (RuntimeException e) { 57 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 58 | } 59 | } 60 | 61 | @Override 62 | public void onSensorChanged(SensorEvent sensorEvent) { 63 | Sensor mySensor = sensorEvent.sensor; 64 | WritableMap map = mArguments.createMap(); 65 | 66 | if (mySensor.getType() == Sensor.TYPE_LIGHT) { 67 | long curTime = System.currentTimeMillis(); 68 | i++; 69 | if ((curTime - lastUpdate) > delay) { 70 | i = 0; 71 | map.putDouble("light", sensorEvent.values[0]); 72 | sendEvent("LightSensor", map); 73 | lastUpdate = curTime; 74 | } 75 | } 76 | } 77 | 78 | @Override 79 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/MagnetometerRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class MagnetometerRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mMagnetometer; 25 | private long lastUpdate = 0; 26 | private int i = 0, n = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | 33 | public MagnetometerRecord(ReactApplicationContext reactContext) { 34 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 35 | mReactContext = reactContext; 36 | } 37 | 38 | public int start(int delay) { 39 | this.delay = delay; 40 | if ((mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)) != null) { 41 | mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_FASTEST); 42 | return (1); 43 | } 44 | return (0); 45 | } 46 | 47 | public void stop() { 48 | mSensorManager.unregisterListener(this); 49 | } 50 | 51 | private void sendEvent(String eventName, @Nullable WritableMap params) 52 | { 53 | try { 54 | mReactContext 55 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 56 | .emit(eventName, params); 57 | } catch (RuntimeException e) { 58 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 59 | } 60 | } 61 | 62 | @Override 63 | public void onSensorChanged(SensorEvent sensorEvent) { 64 | Sensor mySensor = sensorEvent.sensor; 65 | WritableMap map = mArguments.createMap(); 66 | 67 | if (mySensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 68 | long curTime = System.currentTimeMillis(); 69 | i++; 70 | if ((curTime - lastUpdate) > 92) { 71 | i = 0; 72 | map.putDouble("x", sensorEvent.values[0]); 73 | map.putDouble("y", sensorEvent.values[1]); 74 | map.putDouble("z", sensorEvent.values[2]); 75 | sendEvent("Magnetometer", map); 76 | lastUpdate = curTime; 77 | } 78 | } 79 | } 80 | 81 | @Override 82 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/MotionValueRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | 22 | public class MotionValueRecord implements SensorEventListener { 23 | private static final int ARRAY_SIZE = 100; 24 | 25 | private SensorManager mSensorManager; 26 | private Sensor mAccelerometer; 27 | private long lastUpdate = 0; 28 | private int i = 0, n = 0; 29 | private float motionValue = 0; 30 | private float currentValue = 0; 31 | private float x = 0, y = 0, z = 0; 32 | private int delay; 33 | 34 | private ReactContext mReactContext; 35 | private Arguments mArguments; 36 | 37 | Timer t = new Timer(); 38 | 39 | public MotionValueRecord(ReactApplicationContext reactContext) { 40 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 41 | mReactContext = reactContext; 42 | } 43 | 44 | public int start(int delay) { 45 | this.delay = delay; 46 | if ((mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)) != null) { 47 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST); 48 | return (1); 49 | } 50 | return (0); 51 | } 52 | 53 | public void stop() { 54 | mSensorManager.unregisterListener(this); 55 | } 56 | 57 | private void sendEvent(String eventName, @Nullable WritableMap params) 58 | { 59 | try { 60 | mReactContext 61 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 62 | .emit(eventName, params); 63 | } catch (RuntimeException e) { 64 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 65 | } 66 | } 67 | 68 | @Override 69 | public void onSensorChanged(SensorEvent sensorEvent) { 70 | Sensor mySensor = sensorEvent.sensor; 71 | WritableMap map = mArguments.createMap(); 72 | 73 | if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { 74 | 75 | currentValue += (Math.pow(sensorEvent.values[0] - x, 2) 76 | + Math.pow(sensorEvent.values[1] - y, 2) 77 | + Math.pow(sensorEvent.values[2] - z, 2)); 78 | x = sensorEvent.values[0]; 79 | y = sensorEvent.values[1]; 80 | z = sensorEvent.values[2]; 81 | 82 | long curTime = System.currentTimeMillis(); 83 | i++; 84 | if ((curTime - lastUpdate) > delay) { 85 | i = 0; 86 | map.putDouble("value", currentValue); 87 | sendEvent("MotionValue", map); 88 | motionValue = currentValue; 89 | currentValue = 0; 90 | lastUpdate = curTime; 91 | } 92 | } 93 | } 94 | 95 | @Override 96 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/OrientationRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class OrientationRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mAccelerometer; 25 | private Sensor mMagnetometer; 26 | private long lastUpdate = 0; 27 | private int i = 0, n = 0; 28 | private int delay; 29 | private int isRegistered = 0; 30 | 31 | private ReactContext mReactContext; 32 | private Arguments mArguments; 33 | 34 | 35 | public OrientationRecord(ReactApplicationContext reactContext) { 36 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 37 | mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 38 | mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 39 | mReactContext = reactContext; 40 | } 41 | 42 | public int start(int delay) { 43 | this.delay = delay; 44 | if (mAccelerometer != null && isRegistered == 0) { 45 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI); 46 | mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_UI); 47 | isRegistered = 1; 48 | return (1); 49 | } 50 | return (0); 51 | } 52 | 53 | public void stop() { 54 | if (isRegistered == 1) { 55 | mSensorManager.unregisterListener(this); 56 | isRegistered = 0; 57 | } 58 | } 59 | 60 | private void sendEvent(String eventName, @Nullable WritableMap params) 61 | { 62 | try { 63 | mReactContext 64 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 65 | .emit(eventName, params); 66 | } catch (RuntimeException e) { 67 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 68 | } 69 | } 70 | 71 | float[] mGravity; 72 | float[] mGeomagnetic; 73 | 74 | @Override 75 | public void onSensorChanged(SensorEvent sensorEvent) { 76 | Sensor mySensor = sensorEvent.sensor; 77 | WritableMap map = mArguments.createMap(); 78 | 79 | if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) 80 | mGravity = sensorEvent.values; 81 | if (mySensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) 82 | mGeomagnetic = sensorEvent.values; 83 | if (mGravity != null && mGeomagnetic != null) { 84 | float R[] = new float[9]; 85 | float I[] = new float[9]; 86 | boolean success = mSensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic); 87 | if (success) { 88 | long curTime = System.currentTimeMillis(); 89 | float orientation[] = new float[3]; 90 | mSensorManager.getOrientation(R, orientation); 91 | 92 | float heading = (float)((Math.toDegrees(orientation[0])) % 360.0f); 93 | float pitch = (float)((Math.toDegrees(orientation[1])) % 360.0f); 94 | float roll = (float)((Math.toDegrees(orientation[2])) % 360.0f); 95 | 96 | if (heading < 0) { 97 | heading = 360 - (0 - heading); 98 | } 99 | 100 | if (pitch < 0) { 101 | pitch = 360 - (0 - pitch); 102 | } 103 | 104 | if (roll < 0) { 105 | roll = 360 - (0 - roll); 106 | } 107 | 108 | map.putDouble("azimuth", heading); 109 | map.putDouble("pitch", pitch); 110 | map.putDouble("roll", roll); 111 | sendEvent("Orientation", map); 112 | lastUpdate = curTime; 113 | } 114 | } 115 | } 116 | 117 | @Override 118 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/ProximityRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class ProximityRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mProximity; 25 | private long lastUpdate = 0; 26 | private int i = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | public ProximityRecord(ReactApplicationContext reactContext) { 33 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 34 | mReactContext = reactContext; 35 | } 36 | 37 | public int start(int delay) { 38 | this.delay = delay; 39 | if ((mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)) != null) { 40 | mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_FASTEST); 41 | return (1); 42 | } 43 | return (0); 44 | } 45 | 46 | public void stop() { 47 | mSensorManager.unregisterListener(this); 48 | } 49 | 50 | private void sendEvent(String eventName, @Nullable WritableMap params) { 51 | try { 52 | mReactContext 53 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 54 | .emit(eventName, params); 55 | } catch (RuntimeException e) { 56 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 57 | } 58 | } 59 | 60 | @Override 61 | public void onSensorChanged(SensorEvent sensorEvent) { 62 | Sensor mySensor = sensorEvent.sensor; 63 | WritableMap map = mArguments.createMap(); 64 | double maxRange = mProximity.getMaximumRange(); 65 | 66 | if (mySensor.getType() == Sensor.TYPE_PROXIMITY) { 67 | long curTime = System.currentTimeMillis(); 68 | 69 | if ((curTime - lastUpdate) > delay) { 70 | boolean isNear = false; 71 | double value = sensorEvent.values[0]; 72 | 73 | // NOTE: Android devices vary in the values they provide. A reasonably 74 | // safe rule of thumb is that if the value is less than the maximum range 75 | // of the sensor, then the phone is reporting that something is "near". 76 | // See https://developer.android.com/guide/topics/sensors/sensors_position.html 77 | // for more details. We also provide the raw value and maximum range in case 78 | // those are needed. 79 | map.putBoolean("isNear", value < maxRange); 80 | map.putDouble("value", value); 81 | map.putDouble("maxRange", maxRange); 82 | 83 | sendEvent("Proximity", map); 84 | lastUpdate = curTime; 85 | } 86 | } 87 | } 88 | 89 | @Override 90 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/SensorManagerModule.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 2 | 3 | import com.facebook.react.bridge.NativeModule; 4 | import com.facebook.react.bridge.ReactApplicationContext; 5 | import com.facebook.react.bridge.ReactContext; 6 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 7 | import com.facebook.react.bridge.ReactMethod; 8 | import com.facebook.react.bridge.Callback; 9 | 10 | import android.util.Log; 11 | 12 | public class SensorManagerModule extends ReactContextBaseJavaModule { 13 | private static final String REACT_CLASS = "SensorManager"; 14 | private AccelerometerRecord mAccelerometerRecord = null; 15 | private GyroscopeRecord mGyroscopeRecord = null; 16 | private MagnetometerRecord mMagnetometerRecord = null; 17 | private StepCounterRecord mStepCounterRecord = null; 18 | private ThermometerRecord mThermometerRecord = null; 19 | private MotionValueRecord mMotionValueRecord = null; 20 | private OrientationRecord mOrientationRecord = null; 21 | private ProximityRecord mProximityRecord = null; 22 | private LightSensorRecord mLightSensorRecord = null; 23 | 24 | private ReactApplicationContext mReactContext; 25 | 26 | @Override 27 | public String getName() { 28 | return REACT_CLASS; 29 | } 30 | 31 | public SensorManagerModule(ReactApplicationContext reactContext) { 32 | super(reactContext); 33 | mReactContext = reactContext; 34 | } 35 | 36 | @ReactMethod 37 | public int startAccelerometer(int delay) { 38 | if (mAccelerometerRecord == null) 39 | mAccelerometerRecord = new AccelerometerRecord(mReactContext); 40 | return (mAccelerometerRecord.start(delay)); 41 | } 42 | 43 | @ReactMethod 44 | public void stopAccelerometer() { 45 | if (mAccelerometerRecord != null) 46 | mAccelerometerRecord.stop(); 47 | } 48 | 49 | @ReactMethod 50 | public int startGyroscope(int delay) { 51 | if (mGyroscopeRecord == null) 52 | mGyroscopeRecord = new GyroscopeRecord(mReactContext); 53 | return (mGyroscopeRecord.start(delay)); 54 | } 55 | 56 | @ReactMethod 57 | public void stopGyroscope() { 58 | if (mGyroscopeRecord != null) 59 | mGyroscopeRecord.stop(); 60 | } 61 | 62 | @ReactMethod 63 | public int startMagnetometer(int delay) { 64 | if (mMagnetometerRecord == null) 65 | mMagnetometerRecord = new MagnetometerRecord(mReactContext); 66 | return (mMagnetometerRecord.start(delay)); 67 | } 68 | 69 | @ReactMethod 70 | public void stopMagnetometer() { 71 | if (mMagnetometerRecord != null) 72 | mMagnetometerRecord.stop(); 73 | } 74 | 75 | @ReactMethod 76 | public int startStepCounter(int delay) { 77 | if (mStepCounterRecord == null) 78 | mStepCounterRecord = new StepCounterRecord(mReactContext); 79 | return (mStepCounterRecord.start(delay)); 80 | } 81 | 82 | @ReactMethod 83 | public void stopStepCounter() { 84 | if (mStepCounterRecord != null) 85 | mStepCounterRecord.stop(); 86 | } 87 | 88 | @ReactMethod 89 | public int startThermometer(int delay) { 90 | if (mThermometerRecord == null) 91 | mThermometerRecord = new ThermometerRecord(mReactContext); 92 | return (mThermometerRecord.start(delay)); 93 | } 94 | 95 | @ReactMethod 96 | public void stopThermometer() { 97 | if (mThermometerRecord != null) 98 | mThermometerRecord.stop(); 99 | } 100 | 101 | @ReactMethod 102 | public int startMotionValue(int delay) { 103 | if (mMotionValueRecord == null) 104 | mMotionValueRecord = new MotionValueRecord(mReactContext); 105 | return (mMotionValueRecord.start(delay)); 106 | } 107 | 108 | @ReactMethod 109 | public void stopMotionValue() { 110 | if (mMotionValueRecord != null) 111 | mMotionValueRecord.stop(); 112 | } 113 | 114 | @ReactMethod 115 | public int startOrientation(int delay) { 116 | if (mOrientationRecord == null) 117 | mOrientationRecord = new OrientationRecord(mReactContext); 118 | return (mOrientationRecord.start(delay)); 119 | } 120 | 121 | @ReactMethod 122 | public void stopOrientation() { 123 | if (mOrientationRecord != null) 124 | mOrientationRecord.stop(); 125 | } 126 | 127 | @ReactMethod 128 | public int startProximity(int delay) { 129 | if (mProximityRecord == null) 130 | mProximityRecord = new ProximityRecord(mReactContext); 131 | return (mProximityRecord.start(delay)); 132 | } 133 | 134 | @ReactMethod 135 | public void stopProximity() { 136 | if (mProximityRecord != null) 137 | mProximityRecord.stop(); 138 | } 139 | 140 | @ReactMethod 141 | public int startLightSensor(int delay) { 142 | if(mLightSensorRecord == null) 143 | mLightSensorRecord = new LightSensorRecord(mReactContext); 144 | return (mLightSensorRecord.start(delay)); 145 | } 146 | 147 | @ReactMethod 148 | public void stopLightSensor() { 149 | if(mLightSensorRecord != null) 150 | mLightSensorRecord.stop(); 151 | } 152 | 153 | /* 154 | @Override 155 | public ReactBarcodeScannerView createViewInstance(ThemedReactContext context) { 156 | } 157 | 158 | @Override 159 | public void onDropViewInstance(ReactBarcodeScannerView view) { 160 | } 161 | 162 | @Override 163 | public void onHostResume() { 164 | } 165 | 166 | @Override 167 | public void onHostPause() { 168 | } 169 | 170 | @Override 171 | public void onHostDestroy() { 172 | } 173 | */ 174 | } 175 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/SensorManagerPackage.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class SensorManagerPackage implements ReactPackage { 15 | 16 | @Override 17 | public List createNativeModules(ReactApplicationContext reactContext) { 18 | List modules = new ArrayList<>(); 19 | modules.add(new SensorManagerModule(reactContext)); 20 | return modules; 21 | } 22 | 23 | @Override 24 | public List> createJSModules() { 25 | return Collections.emptyList(); 26 | } 27 | 28 | @Override 29 | public List createViewManagers(ReactApplicationContext reactContext) { 30 | return Arrays.asList(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/StepCounterRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class StepCounterRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mStepCounter; 25 | private long lastUpdate = 0; 26 | private int i = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | 33 | public StepCounterRecord(ReactApplicationContext reactContext) { 34 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 35 | mReactContext = reactContext; 36 | } 37 | 38 | public int start(int delay) { 39 | this.delay = delay; 40 | if ((mStepCounter = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)) != null) { 41 | mSensorManager.registerListener(this, mStepCounter, SensorManager.SENSOR_DELAY_FASTEST); 42 | return (1); 43 | } 44 | return (0); 45 | } 46 | 47 | public void stop() { 48 | mSensorManager.unregisterListener(this); 49 | } 50 | 51 | private void sendEvent(String eventName, @Nullable WritableMap params) 52 | { 53 | try { 54 | mReactContext 55 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 56 | .emit(eventName, params); 57 | } catch (RuntimeException e) { 58 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 59 | } 60 | } 61 | 62 | @Override 63 | public void onSensorChanged(SensorEvent sensorEvent) { 64 | Sensor mySensor = sensorEvent.sensor; 65 | WritableMap map = mArguments.createMap(); 66 | 67 | if (mySensor.getType() == Sensor.TYPE_STEP_COUNTER) { 68 | long curTime = System.currentTimeMillis(); 69 | i++; 70 | if ((curTime - lastUpdate) > delay) { 71 | i = 0; 72 | map.putDouble("steps", sensorEvent.values[0]); 73 | sendEvent("StepCounter", map); 74 | lastUpdate = curTime; 75 | } 76 | } 77 | } 78 | 79 | @Override 80 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /android/src/main/java/com/sensormanager/ThermometerRecord.java: -------------------------------------------------------------------------------- 1 | package com.sensormanager; 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 java.io.*; 12 | import java.util.Date; 13 | import java.util.Timer; 14 | 15 | import com.facebook.react.bridge.Arguments; 16 | import com.facebook.react.bridge.ReactContext; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.modules.core.DeviceEventManagerModule; 19 | import com.facebook.react.bridge.ReactApplicationContext; 20 | 21 | public class ThermometerRecord implements SensorEventListener { 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mThermometer; 25 | private long lastUpdate = 0; 26 | private int i = 0, n = 0; 27 | private int delay; 28 | 29 | private ReactContext mReactContext; 30 | private Arguments mArguments; 31 | 32 | 33 | public ThermometerRecord(ReactApplicationContext reactContext) { 34 | mSensorManager = (SensorManager)reactContext.getSystemService(reactContext.SENSOR_SERVICE); 35 | mReactContext = reactContext; 36 | } 37 | 38 | public int start(int delay) { 39 | this.delay = delay; 40 | if ((mThermometer = mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE)) != null) { 41 | mSensorManager.registerListener(this, mThermometer, SensorManager.SENSOR_DELAY_FASTEST); 42 | } else { 43 | return (0); 44 | } 45 | return (1); 46 | } 47 | 48 | public void stop() { 49 | mSensorManager.unregisterListener(this); 50 | } 51 | 52 | private void sendEvent(String eventName, @Nullable WritableMap params) 53 | { 54 | try { 55 | mReactContext 56 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 57 | .emit(eventName, params); 58 | } catch (RuntimeException e) { 59 | Log.e("ERROR", "java.lang.RuntimeException: Trying to invoke JS before CatalystInstance has been set!"); 60 | } 61 | } 62 | 63 | @Override 64 | public void onSensorChanged(SensorEvent sensorEvent) { 65 | Sensor mySensor = sensorEvent.sensor; 66 | WritableMap map = mArguments.createMap(); 67 | 68 | if (mySensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) { 69 | long curTime = System.currentTimeMillis(); 70 | i++; 71 | if ((curTime - lastUpdate) > delay) { 72 | i = 0; 73 | map.putDouble("temp", sensorEvent.values[0]); 74 | sendEvent("Thermometer", map); 75 | lastUpdate = curTime; 76 | } 77 | } 78 | } 79 | 80 | @Override 81 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-sensor-manager", 3 | "version": "0.1.10", 4 | "description": "A react-native module that allows you to use the accelerometer, gyroscope and magnetometer and Android devices\"", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "make test" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/kprimice/react-native-sensor-manager.git" 12 | }, 13 | "keywords": [ 14 | "react-native", 15 | "android", 16 | "react-native-sensor-manager", 17 | "accelerometer", 18 | "gyroscope", 19 | "magnetometer", 20 | "thermometer", 21 | "step-counter" 22 | ], 23 | "author": "Kevin Primicerio ", 24 | "license": "ISC", 25 | "bugs": { 26 | "url": "https://github.com/kprimice/react-native-sensor-manager/issues" 27 | }, 28 | "homepage": "https://github.com/kprimice/react-native-sensor-manager#readme" 29 | } 30 | -------------------------------------------------------------------------------- /react-native-sensor-manager.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "react-native-sensor-manager" 3 | s.version = "0.1" 4 | s.license = "NONE" 5 | s.homepage = "https://github.com/kprimice/react-native-sensor-manager" 6 | s.authors = { 'Kevin Primicerio' => 'kevin.primicerio@gmail.com' } 7 | s.summary = "A React Native module that allows you to use the native sensorManager in order to use the accelerometer, gyroscope and magnetometer" 8 | s.source = { :git => "https://github.com/marcshilling/react-native-sensor-manager" } 9 | 10 | s.dependency 'React' 11 | end 12 | --------------------------------------------------------------------------------