RN 手電筒

首先新建一個rn項目

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

React Native調用接口

修改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來打開和關閉手電筒

相關文章
相關標籤/搜索