RN 调用 Android 闪光灯

本文介绍了如何在ReactNative应用中使用FlashLight模块控制手电筒,包括创建和注册模块、处理不同Android版本兼容、添加摄像头和闪光灯权限,以及在模拟器和真机上的操作差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        我的 SDK 版本33,安装的模拟器上并没有闪光灯这个功能(灰色),所以只能连接真机才能看得到效果,在模拟器上会报以下错:

        setTorchMode:2246: Camera "0" does not have a flash unit

        但是在真机上就是正常的~

目录

 一、创建手电筒 FlashLight 模块

二、注册手电筒 FlashLightPackage 模块

三、添加 FlashLightPackage 包

四、添加权限

五、将原生模块封装成 JavaScript 模块

六、调用方法


 一、创建手电筒 FlashLight 模块

将创建的 FlashLight.java 放置在 app/src/main/java/com/your-project-name 中

package com.invokingandroid;

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 调用,getName 返回的就是调用的名称。

        然后写一个方法 switchState 来控制手电筒开关,注意要加上 @ReactMethod 注解才能被调用,具体代码还包括不同 Android 版本的适配,都是 Android 原生的代码


二、注册手电筒 FlashLightPackage 模块

在 app/src/main/java/com/your-project-name 中新建 FlashLightPackage.java 包

package com.invokingandroid;

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模块


三、添加 FlashLightPackage

在同级目录下的 MainApplication.java 中的getPackages方法里添加刚才的FlashLightPackage包:

    @Override
    protected List<ReactPackage> getPackages() {
      @SuppressWarnings("UnnecessaryLocalVariable")
      List<ReactPackage> packages = new PackageList(this).getPackages();
      // Packages that cannot be autolinked yet can be added manually here, for
      // example:
      // packages.add(new MyReactNativePackage());
      packages.add(new FlashLightPackage()); // <-- 添加这一行,类名替换成你的Package类的名字 name.

      return packages;
    }

四、添加权限

在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" />
    <uses-feature android:name="android.hardware.camera.flash" />

五、将原生模块封装成 JavaScript 模块

// FlashLight.js

import { NativeModules } from 'react-native';
// 下一句中的FlashLight即对应上文
// public String getName()中返回的字符串
export default NativeModules.FlashLight;

六、调用方法

从NativeModules取出FlashLight模块,然后调用FlashLight的switchState来打开和关闭手电筒

function openFlashLight() {
  FlashLight.switchState(
    true,
    () => {},
    (message: any) => {
      console.error(message);
    },
  );
}

function closeFlashLight() {
  FlashLight.switchState(
    false,
    () => {},
    (message: any) => {
      console.error(message);
    },
  );
}


function App(): JSX.Element {
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={() => {
          openFlashLight();
        }}>
        <Text>打开手电筒</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() => {
          closeFlashLight();
        }}>
        <Text>关闭手电筒</Text>
      </TouchableOpacity>
    </View>
  );
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值