首先新建一个rn项目
react-native init flashlight
之后用AndroidStudio打开项目的Android代码新建手电筒模块
在app/java/com.flashlight下新建一个模块FlashLight.java:
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调用
然后写一个方法switchState来控制手电筒开关,注意要加上@ReactMethod注解才能被调用,具体代码还包括不同Android版本的适配,都是Android原生的代码,不做过多解释
注册手电筒模块
之后在app/java/com.flashlight下新建一个包FlashLightPackage.java:
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 ListcreateNativeModules(ReactApplicationContext reactContext) { List modules = new ArrayList<>(); // 注册FlashLight模块 modules.add(new FlashLight(reactContext)); return modules; } @Override public List createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }}
实现ReactPackage的两个方法,在createNativeModules里添加注册FlashLight模块
最后,在MainApplication.java的getPackages方法里添加刚才的FlashLightPackage包:
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 ListgetPackages() { return Arrays. 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配置文件里添加照相机和闪光灯的权限:
现在原生的接口已经写好,可以去rn调用这个接口来打开或者关闭手电筒了
React Native调用接口
修改App.js文件,添加两个按钮用于打开和关闭手电筒
import React, {Component} from 'react';import { StyleSheet, Text, View, TouchableOpacity, NativeModules} from 'react-native';let FlashLight = NativeModules.FlashLight export default class App extends Component{ openFlashLight() { FlashLight.switchState(true, () => { }, (message) => { console.error(message) }) } closeFlashLight() { FlashLight.switchState(false, () => { }, (message) => { console.error(message) }) } render() { return ( ); }} const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', },}); { this.openFlashLight() }}> 打开手电筒 { this.closeFlashLight() }}> 关闭手电筒
从NativeModules取出FlashLight模块,然后调用FlashLight的switchState来打开和关闭手电筒