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来打开和关闭手电筒