react-native init flashlight
以後用AndroidStudio打開項目的Android代碼java
在app/java/com.flashlight下新建一個模塊FlashLight.java:react
package com.flashlight; import android.content.Context; import android.hardware.Camera; import android.hardware.camera2.CameraManager; import android.os.Build; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; public class FlashLight extends ReactContextBaseJavaModule{ private Camera camera; private Boolean isLightOn = false; private final ReactApplicationContext myReactContext; public FlashLight(ReactApplicationContext reactContext) { super(reactContext); this.myReactContext = reactContext; } /** * 繼承ReactContextBaseJavaModule後重寫的方法,返回一個模塊名稱,rn經過NativeModules能夠調用此模塊 */ @Override public String getName() { return "FlashLight"; } /** * @param state 控制手電筒開關,true:打開,false:關閉 * @param successCallback 打開成功的回調 * @param failCallback 打開失敗的回調 */ @ReactMethod public void switchState(Boolean state, Callback successCallback, Callback failCallback) { if (isM()) { CameraManager cameraManager = (CameraManager) this.myReactContext.getSystemService(Context.CAMERA_SERVICE); try { String camreaId = cameraManager.getCameraIdList()[0]; cameraManager.setTorchMode(camreaId, state); successCallback.invoke(true); }catch (Exception e) { String errorMessage = e.getMessage(); failCallback.invoke(errorMessage); } } else { Camera.Parameters params; if (!isLightOn) { camera = Camera.open(); params = camera.getParameters(); params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); camera.setParameters(params); camera.startPreview(); isLightOn = true; } else { params = camera.getParameters(); params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); camera.setParameters(params); camera.stopPreview(); camera.release(); isLightOn = false; } } } private boolean isM() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return true; } else { return false; } } }
上面的FlashLight類繼承自ReactContextBaseJavaModule,須要重寫getName方法,返回一個模塊供rn調用android
而後寫一個方法switchState來控制手電筒開關,注意要加上@ReactMethod註解才能被調用,具體代碼還包括不一樣Android版本的適配,都是Android原生的代碼,不作過多解釋shell
以後在app/java/com.flashlight下新建一個包FlashLightPackage.java:react-native
package com.flashlight; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class FlashLightPackage implements ReactPackage{ @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); // 註冊FlashLight模塊 modules.add(new FlashLight(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
實現ReactPackage的兩個方法,在createNativeModules裏添加註冊FlashLight模塊app
最後,在MainApplication.java的getPackages方法裏添加剛纔的FlashLightPackage包:ide
package com.flashlight; import android.app.Application; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; import java.util.Arrays; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new FlashLightPackage() ); } @Override protected String getJSMainModuleName() { return "index"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); } }
在AndroidManifest.xml配置文件裏添加照相機和閃光燈的權限:flex
<uses-permission android:name="android.permission.FLASHLIGHT" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.autofocus" />
如今原生的接口已經寫好,能夠去rn調用這個接口來打開或者關閉手電筒了ui
修改App.js文件,添加兩個按鈕用於打開和關閉手電筒this
import React, {Component} from 'react'; import { StyleSheet, Text, View, TouchableOpacity, NativeModules } from 'react-native'; let FlashLight = NativeModules.FlashLight export default class App extends Component<Props> { openFlashLight() { FlashLight.switchState(true, () => { }, (message) => { console.error(message) }) } closeFlashLight() { FlashLight.switchState(false, () => { }, (message) => { console.error(message) }) } render() { return ( <View style={styles.container}> <TouchableOpacity onPress={() => { this.openFlashLight() }}> <Text>打開手電筒</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { this.closeFlashLight() }}> <Text>關閉手電筒</Text> </TouchableOpacity> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, });
從NativeModules取出FlashLight模塊,而後調用FlashLight的switchState來打開和關閉手電筒