React Native调用Android原生代码打开和关闭手电筒
首先新建一个rn项目
react-native init flashlight
之后用AndroidStudio打开项目的Android代码
1.新建手电筒模块
在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原生的代码,不做过多解释
2.注册手电筒模块
之后在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 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模块
最后,在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 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);
}
}
3.添加权限
在AndroidManifest.xml配置文件里添加照相机和闪光灯的权限:
<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调用这个接口来打开或者关闭手电筒了
4.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<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来打开和关闭手电筒