首页
/ 无网传输革命:CFC Android 项目实现摄像头文件拷贝全指南

无网传输革命:CFC Android 项目实现摄像头文件拷贝全指南

2026-01-23 04:37:49作者:姚月梅Lane

项目概述

CFC(CameraFileCopy)是一个基于 libcimbar 库的 Android 应用程序,它允许通过手机摄像头在设备之间传输文件,无需任何网络连接(如 Wi-Fi、蓝牙、NFC 等),即使在飞行模式下也能正常工作。该应用通过读取动画的 cimbar 码 来接收数据,核心逻辑由 libcimbar 提供,CFC 主要作为其 Android 平台的演示和测试应用。

应用截图与资源

应用使用了多种图标资源来表示不同的模式,例如:

项目结构解析

CFC 项目的主要目录结构如下:

app/
├── src/
│   ├── cpp/                # C++ 代码目录,包含 libcimbar 库和 JNI 接口
│   │   ├── cfc-cpp/        # CFC 项目的 C++ 代码,如 [MultiThreadedDecoder.h](https://gitcode.com/gh_mirrors/cfc/cfc/blob/05a7e1f9b8cf01c73d6be3111b32b00767b8a62b/app/src/cpp/cfc-cpp/MultiThreadedDecoder.h?utm_source=gitcode_repo_files) 和 [jni.cpp](https://gitcode.com/gh_mirrors/cfc/cfc/blob/05a7e1f9b8cf01c73d6be3111b32b00767b8a62b/app/src/cpp/cfc-cpp/jni.cpp?utm_source=gitcode_repo_files)
│   │   ├── concurrent/     # 并发相关代码,如 [thread_pool.h](https://gitcode.com/gh_mirrors/cfc/cfc/blob/05a7e1f9b8cf01c73d6be3111b32b00767b8a62b/app/src/cpp/concurrent/thread_pool.h?utm_source=gitcode_repo_files)
│   │   └── libcimbar/      # cimbar 库,包含编码解码核心逻辑
│   └── main/               # Android 应用主目录
│       ├── java/           # Java 代码,如 [MainActivity.java](https://gitcode.com/gh_mirrors/cfc/cfc/blob/05a7e1f9b8cf01c73d6be3111b32b00767b8a62b/app/src/main/java/org/cimbar/camerafilecopy/MainActivity.java?utm_source=gitcode_repo_files)
│       ├── res/            # 资源文件,如布局、字符串、图片等
│       └── AndroidManifest.xml  # 应用清单文件,声明权限、组件等

核心功能与实现

1. 摄像头权限获取

应用需要摄像头权限来捕获图像以解码 cimbar 码。在 AndroidManifest.xml 中声明了相关权限:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="true"/>

MainActivity.java 中,通过 onRequestPermissionsResult 方法处理权限请求结果:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == CAMERA_PERMISSION_REQUEST) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            mOpenCvCameraView.setCameraPermissionGranted();
        } else {
            String message = "Camera permission was not granted";
            Log.e(TAG, message);
            Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        }
    } else {
        Log.e(TAG, "Unexpected permission request");
    }
}

2. OpenCV 初始化与摄像头预览

应用使用 OpenCV 库处理摄像头帧。在 MainActivity.javaonResume 方法中初始化 OpenCV:

@Override
public void onResume() {
    super.onResume();
    if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }
}

初始化成功后,加载本地库并启用摄像头预览:

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        if (status == LoaderCallbackInterface.SUCCESS) {
            Log.i(TAG, "OpenCV loaded successfully");
            System.loadLibrary("cfc-cpp");
            mOpenCvCameraView.enableView();
        } else {
            super.onManagerConnected(status);
        }
    }
};

3. 图像处理与文件接收

摄像头捕获的每一帧图像通过 JNI 调用 C++ 代码进行处理。在 MainActivity.javaonCameraFrame 方法中:

@Override
public Mat onCameraFrame(CvCameraViewFrame frame) {
    Mat mat = frame.rgba();
    String res = processImageJNI(mat.getNativeObjAddr(), this.dataPath, this.modeVal);
    // 处理返回结果,若接收到文件则提示用户保存
    if (!res.isEmpty() && !res.startsWith("/")) {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        // ... 设置 intent 参数并启动保存文件活动
    }
    return mat;
}

其中 processImageJNI 是一个 native 方法,实现在 jni.cpp 中,用于调用 libcimbar 库解码图像中的数据。

4. 模式切换功能

应用支持不同的解码模式(Mode 4C 和 Mode B),用户可以通过界面上的切换按钮进行选择。在 MainActivity.java 中,通过 ToggleButton 的状态变化来切换模式:

mModeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            modeVal = detectedMode;
        } else {
            modeVal = 0;
        }
    }
});

模式对应的字符串资源在 strings.xml 中定义:

<string name="mode_4c">Mode 4C</string>
<string name="mode_b">Mode B</string>

构建与安装

环境准备

  1. 安装 Android Studio 和 Android NDK。
  2. 下载 OpenCV for Android 并解压。
  3. 克隆项目仓库:git clone https://gitcode.com/gh_mirrors/cfc/cfc.git

配置项目

  1. 在 Android Studio 中打开项目,将 OpenCV Android SDK 的路径配置到 gradle.properties 文件中:opencvsdk=path/to/opencv-android-sdk
  2. 同步项目,确保依赖正确加载。

编译与运行

连接 Android 设备或启动模拟器,点击 "Run" 按钮编译并安装应用。

使用方法

  1. 在发送端,通过 cimbar.org 网站或 libcimbar 的 cimbar_send 工具生成包含文件数据的 cimbar 动画码。
  2. 在接收端,打开 CFC 应用,授予摄像头权限。
  3. 将发送端显示的动画码对准接收端的摄像头,应用将自动解码并接收文件,接收完成后提示用户保存文件。

总结

CFC 项目展示了如何利用摄像头和 cimbar 码技术实现无网文件传输,为在无网络环境下的数据共享提供了一种创新的解决方案。通过深入理解其代码结构和实现逻辑,开发者可以进一步扩展其功能,如优化解码速度、增加文件传输进度显示等。项目的核心代码位于 app/src/cpp/cfc-cpp/app/src/main/java/org/cimbar/camerafilecopy/ 目录,感兴趣的开发者可以参考这些代码进行二次开发。

登录后查看全文
热门项目推荐
相关项目推荐