尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Intel RealSense SDK 2.0 Android 开发指南:从 AAR 集成到 Java/Native 应用实战

Intel RealSense SDK 2.0 Android 开发指南:从 AAR 集成到 Java/Native 应用实战 Intel RealSense SDK 2.0 Android 开发指南从 AAR 集成到 Java/Native 应用实战【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense本指南基于开源仓库 librealsenseIntel RealSense SDK 2.0的 Android 官方文档系统讲解如何在 Android 平台构建与集成 RealSense 应用。读完本文你将掌握librealsense.aarAndroid Archive的两种集成方式Maven 依赖与源码构建、Android 权限与 USB 连接机制以及基于 Pipeline 的 Java 流式编程与基于 JNI 的 C/C 原生编程并了解仓库内置的 capture、recording、playback 等图形化示例。RealSense SDK 2.0 在 Android 设备上的应用运行界面图片来源doc/img/realsense-android.pngSDK 2.0 对 Android 的支持现状与边界Intel RealSense SDK 2.0 是一套跨平台的开源库与工具链允许开发者在多个操作系统与开发环境下开发应用。根据 doc/android.md 的官方声明RealSense 已在Windows 与 Linux平台对 SDK 2.0 做过完整验证具体构建版本可参考官方 Release 说明Android 平台虽未经过 RealSense 官方的显式验证但预期可以正常工作其构建方式见下文在 Android 上暂不提供标定Calibration与固件更新Firmware Update工具——这两类工具通常用于生产与制造环节如确有需求需联系 Intel 代表获取额外信息。从仓库结构看Android 支持链路是一个完整的独立工程wrappers/android/目录下同时包含 AAR 库工程librealsense/、图形化工具tools/camera/与多个示例应用examples/并通过 settings.gradle 统一组织各模块。历史说明v2.18.1 之前的旧版 Android 方案仅支持root 过的设备该方案已不再推荐当前基于 AAR 的解决方案对普通设备即可工作。Android 架构AAR、JNI 与 USB 权限使用 Android wrapper 可以同时构建原生C/C应用与Java 应用。其核心机制是RealSense Android App 需要在其依赖中包含librealsense.aarAndroid Archive该 AAR 文件负责获取相机访问权限同时提供一套基于 JNI 的 RealSense Java API让 Java 层可以直接操控 RealSense 设备。USB 权限与设备过滤AAR 内置的 AndroidManifest.xml 注册了一个DeviceWatcherActivity它通过 intent-filter 监听系统广播android.hardware.usb.action.USB_DEVICE_ATTACHED即 RealSense 设备通过 OTG 接入时自动感知activity android:name.DeviceWatcherActivity android:themeandroid:style/Theme.NoDisplay android:directBootAwaretrue android:exportedtrue intent-filter action android:nameandroid.hardware.usb.action.USB_DEVICE_ATTACHED / /intent-filter meta-data android:nameandroid.hardware.usb.action.USB_DEVICE_ATTACHED android:resourcexml/usb_filter / /activity其中 usb_filter.xml 定义了哪些 USB 设备会被识别为 RealSense 设备仓库内置的 vendor-id 列表如下resources usb-device vendor-id0x08086 / usb-device vendor-id0x08087 / usb-device vendor-id0x003E7 / /resources这三个 vendor-id 分别对应 Intel0x8086、Intel0x8087以及 RealSense 设备0x03E7。从源码结构看USB 权限的申请与设备枚举逻辑分别实现在 UsbUtilities.java 与 Enumerator.java 中设备插拔事件的分发则由 DeviceWatcher.java 负责最终将设备连接状态上报给上层的DeviceListener回调。开发前置条件Ingredients开始之前请确保备齐以下三样东西Android 目标设备系统版本 Android 6.0API 23且支持OTG功能Android Studio IDE用于打开工程、构建与运行USB3 OTG 线缆用于连接 RealSense 设备与 Android 设备RealSense 深度相机对带宽要求较高务必使用 USB3 规格的 OTG 线。从源码构建 librealsense.aar官方推荐两种方式获取 AAR直接使用 Maven 仓库中的发布版本或从源码自行构建。如果你需要定制 SDK 或验证最新代码可按照 wrappers/android/readme.md 的说明从源码构建。方式一Gradle 命令行构建在仓库根目录下进入wrappers/android执行# Windows 主机 gradlew assembleRelease # Linux 主机 ./gradlew assembleRelease构建成功后生成的 AAR 位于librealsense_root_dir/wrappers/android/librealsense/build/outputs/aar方式二Android Studio 构建下载并安装 Android Studio IDE将本仓库克隆到本地主机打开 Android Studio通过File -- Open选择 wrappers/android/build.gradle 打开 Android 工程在 Gradle 任务面板中依次执行:librealsense -- build -- assembleRelease。由于库需要针对4 种不同的 ABI 配置对应不同 ARM 架构分别编译整个构建过程可能需要数分钟。构建成功后 AAR 同样输出到wrappers/android/librealsense/build/outputs/aar。原生库的 CMake 组织方式从 librealsense/CMakeLists.txt 可以看出 AAR 的构建本质它直接以仓库根目录为子工程add_subdirectory并针对当前 ABI 输出librealsense2.soinclude(../config.cmake) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LRS_ANDROID_ROOT_DIR}/build/jniLibs/${ANDROID_ABI}) add_subdirectory(${LRS_ROOT_DIR} ${LRS_ANDROID_ROOT_DIR}/build-${ANDROID_ABI})路径基准由 config.cmake 定义LRS_ROOT_DIR指向仓库根目录LRS_ANDROID_ROOT_DIR指向wrappers/android。同时 gradle.properties 中开启了android.useAndroidXtrue与android.enableJetifiertrue并设置 JVM 堆为 1536m确保依赖库迁移与编译内存充足。在 Java 应用中集成 RealSense仓库提供了两个独立示例演示如何从 Maven 仓库链接 librealsense AAR它们聚焦于 Gradle 配置且代码量最小Java 示例与Native 示例。这里先讲 Java 路线完整源码见 java_example 说明 与 MainActivity.java。模块 build.gradle 配置在应用模块的build.gradle中加入 librealsense 依赖该依赖托管在 Maven 私有仓库中repositories { maven{ url https://egiintel.jfrog.io/artifactory/librealsense } } dependencies { implementation com.intel.realsense:librealsense:2.aar }上述写法表示使用大于 2.0.0 的任意版本生产环境建议锁定具体版本例如implementation com.intel.realsense:librealsense:2.18.0aarGradle 同步完成后即可在代码中 import librealsense 的类。若同步后仍无法导入可尝试File -- Invalidate Caches -- Invalidate and restart使缓存失效后重启。AndroidManifest 声明相机权限Android 9API 28及以上要求显式声明相机权限target 更低版本的应用则无需uses-permission android:nameandroid.permission.CAMERA/示例工程的完整清单见 java_example 的 AndroidManifest.xml。初始化 RsContextRsContext.init必须在应用生命周期内、与任何物理 RealSense 设备交互之前调用一次。对于多 Activity 的应用应使用Application Context而非 Activity ContextRsContext.init(getApplicationContext());随后创建RsContext并注册DeviceListener回调监听 RealSense 设备的插入/拔出事件。下面的示例在检测到设备时启动流线程拔出时中断mRsContext new RsContext(); mRsContext.setDevicesChangedCallback(new DeviceListener() { Override public void onDeviceAttach() { mStreamingThread.start(); } Override public void onDeviceDetach() { mStreamingThread.interrupt(); } });使用 Pipeline 流式获取深度数据检测到设备后用专用线程启动流。核心是Pipeline类start()启动默认配置的流waitForFrames()阻塞等待新帧到达然后从FrameSet中取出深度帧读取画面中心像素的距离值并刷新 UIprivate void stream() throws Exception { Pipeline pipe new Pipeline(); pipe.start(); final DecimalFormat df new DecimalFormat(#.##); while (!mStreamingThread.isInterrupted()) { try (FrameSet frames pipe.waitForFrames()) { try (Frame f frames.first(StreamType.DEPTH)) { DepthFrame depth f.as(Extension.DEPTH_FRAME); final float deptValue depth.getDistance(depth.getWidth()/2, depth.getHeight()/2); runOnUiThread(new Runnable() { Override public void run() { TextView textView findViewById(R.id.distanceTextView); textView.setText(Distance: df.format(deptValue)); } }); } } } pipe.stop(); }重要资源管理提示SDK 持有原生硬件资源因此必须确定性地调用close释放对象尤其是派生自Frame的对象。若不在代码中显式释放垃圾回收器将无法跟上新帧的分配节奏导致内存持续增长。尽量利用try(){...}try-with-resources语法处理帧对象。在 NativeC/C应用中集成 RealSenseNative 示例展示的是如何配置一个使用原生代码的 Android 应用并链接 librealsense完整说明见 native_example 说明。除了同样要下载 AAR 之外还需要额外下载 C 头文件包用于编译原生代码。模块 build.gradle下载头文件与动态库repositories { maven{ url https://egiintel.jfrog.io/artifactory/librealsense } } configurations { downloadHeader downloadSo } dependencies { def version 2. downloadSo com.intel.realsense:librealsense: version aar implementation com.intel.realsense:librealsense: version aar downloadHeader com.intel.realsense:librealsense: version zip } task extractHeaders(type: Sync) { dependsOn configurations.downloadHeader from { configurations.downloadHeader.collect { zipTree(it) } } into $projectDir/src/main/cpp/include } task extractSo(type: Sync) { dependsOn configurations.downloadSo from { configurations.downloadSo.collect { zipTree(it) } } include(jni/**) into $buildDir/ } preBuild.dependsOn(extractHeaders) preBuild.dependsOn(extractSo)extractHeaders将zip依赖中的头文件解压到src/main/cpp/includeextractSo将 AAR 中jni/**下的.so动态库解压到构建目录两者都挂在preBuild之前执行。同样建议锁定具体版本例如def version 2.18.0。CMakeLists引入并链接 librealsense.so在应用的 CMakeLists.txt 中将解压出的头文件目录加入搜索路径并把动态库声明为 IMPORTED 目标include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/include) add_library(realsense2 SHARED IMPORTED) set_target_properties( realsense2 PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/build/jni/${ANDROID_ABI}/librealsense2.so )然后链接到你的原生库target_link_libraries( native-lib ${log-lib} realsense2 )Java 侧调用原生 APIJava 层依然要完成RsContext.init(getApplicationContext())与DeviceListener注册见前文随后通过 JNI 方法调用原生代码int cameraCount nGetCamerasCountFromJNI(); String version nGetLibrealsenseVersionFromJNI();原生侧实现原生实现位于 native-lib.cpp。读取 SDK 版本直接使用RS2_API_VERSION_STR宏extern C JNIEXPORT jstring JNICALL Java_com_example_realsense_1native_1example_MainActivity_nGetLibrealsenseVersionFromJNI(JNIEnv *env, jclass type) { return (*env).NewStringUTF(RS2_API_VERSION_STR); }查询已连接设备数量则使用与桌面端完全一致的rs2::contextAPI——这印证了 Android 与桌面端共享同一套 C 核心extern C JNIEXPORT jint JNICALL Java_com_example_realsense_1native_1example_MainActivity_nGetCamerasCountFromJNI(JNIEnv *env, jclass type) { rs2::context ctx; return ctx.query_devices().size();; }仓库内置的示例与工具模块除上述两个最小化配置示例外Android wrapper 工程还附带若干可直接运行的图形化 Java 示例位于wrappers/android/examples/下。根据 settings.gradle 的模块声明完整模块清单为模块路径说明:librealsensewrappers/android/librealsenseAAR 库本体:tools:camerawrappers/android/tools/camera相机工具集预览/录制/播放/终端等:examples:capturewrappers/android/examples/capture采集示例:examples:playbackwrappers/android/examples/playback回放示例:examples:recordingwrappers/android/examples/recording录制示例:examples:processingwrappers/android/examples/processing后处理示例:examples:multicamwrappers/android/examples/multicam多相机示例:examples:sensorwrappers/android/examples/sensor传感器示例:examples:stream_pipeline_callbackwrappers/android/examples/stream_pipeline_callbackPipeline 回调流式示例在 Android Studio 中可通过顶部 Configuration box 选择任意示例模块连接目标手机后直接运行。库本体还内置了若干深度预设PresetJSON位于 librealsense/src/main/assets/presets例如DefaultPreset_D415.json、DefaultPreset_D435.json、HighResHighAccuracyPreset.json、ShortRangePreset.json等可供上层应用直接加载使用。常见问题与排查建议导入类失败Gradle 同步后仍无法 import librealsense 类时尝试File -- Invalidate Caches -- Invalidate and restart使缓存失效并重启版本漂移2.通配符写法方便尝鲜但可能引入不可预期的 API 变化正式项目务必锁定具体版本号如2.18.0Android 9 无画面确认在应用清单中声明了android.permission.CAMERA并已在运行时向用户申请权限内存持续增长检查是否在每一帧处理后显式close了Frame/FrameSet未释放原生资源是 Android 上最常见的性能问题设备无法识别确认目标设备支持 OTG、使用 USB3 OTG 线缆并核对设备 vendor-id 是否在 usb_filter.xml 的过滤列表中。延伸阅读Android 官方支持文档本文的依据文档从源码构建 AAR 指南两种构建方式的完整说明Java 示例说明 与 Native 示例说明AAR 库工程JNI 桥接层与权限处理源码若需在桌面端Windows/Linux开发可参考 安装指南 与 SDK 架构说明。【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表