
简介DJI SDK开发包是面向无人机应用开发者的官方软件开发工具包适用于基于DJI飞行平台如Phantom 4或Windows等系统的软件功能扩展与二次开发核心价值在于帮助开发者利用官方API接口快速接入无人机完成通信控制、数据订阅、指令集调用等任务适合具备一定编程基础并希望深入无人机开发的工程师学习使用。资源共包含493个文件压缩包整体约19.76MB文件类型以HTML文档、JavaScript脚本、SCSS/CSS样式、PNG资源以及Markdown说明为主同时包含Doxygen生成的API依赖图、SVG图标、字体文件及YAML配置等便于从界面、逻辑、样式和文档四个层面理解SDK的结构与调用方式。已有6751人学习浏览了这套SDK开发包说明其在无人机SDK入门者中具有较高的参考价值。通过阅读内置HTML与Markdown文档结合源码中的JS示例和代码结构可以快速掌握DJI SDK的环境组织方式与核心模块划分为后续开发或移植提供清晰的起点。 做无人机二次开发的人基本都绕不开DJI SDK这套东西。我最早接触它是在一个电力巡检的项目里需求很直接用安卓平板连接Mavic 3行业版一键起飞、按航线自动拍照、把实时画面和飞行状态传回后台。当时我第一反应是“大疆不是有自带的DJI Pilot吗还要自己开发”等真正跑起来才发现行业场景里的自动化需求靠遥控器上那套操作界面根本实现不了必须走SDK把飞机的能力接进自己的App里。这篇博文就围绕DJI SDK开发包聊清楚几个事不同SDK怎么选、环境怎么搭、飞机怎么真正“接”进来以及我实际踩过的那些坑。如果你想用大疆无人机做行业应用、搞二次开发或者研究无人机编程入门这篇文章基本能帮你少走一个月的弯路。1. 先搞清楚你要接的是哪个DJI SDK选错等于白干很多人一听“DJI SDK”就想直接打开Android Studio开始写代码这是第一个大坑。DJI官方提供了多条SDK路线它们面向的硬件和场景完全不一样选错开发包后面整个应用架构都得推翻。1.1 MSDK、PSDK、OSDK、Cloud API到底分别是干什么的我按实际用途把这几个SDK拆开讲。Mobile SDK简称MSDK运行在Android或iOS手机App里手机通过USB或有线方式连接遥控器遥控器再连接飞机。你写一个App在里面完成起飞、降落、拍照、传图、航线任务全靠它。这是大多数“用App控制无人机”需求的正解。UX SDK这是MSDK的补充它提供了一堆现成的UI组件比如地图、飞行控制面板、相机设置面板、报错提示你不用从零画界面。适合想快速出原型的朋友但对界面定制要求高的项目这一层经常会被换掉。Onboard SDKOSDK跑在机载电脑上比如Jetson或者树莓派直接通过开发套件跟飞控通信。它适合在飞机上做边缘计算、实时避障、机载航线重算。如果识别算法必须部署在飞机端而不是手机端选它。Payload SDKPSDK给挂载设备用的比如热成像相机、喊话器、探照灯、喊话照明一体设备。开发目标不是控制飞机而是开发挂在飞机下面的负载硬件。Cloud API直接对上云接口适合做远程任务调度、多机集群管理、云端直播推流。它不做端侧实时控制而是通过HTTPS或MQTT跟大疆云平台打交道。我给一个最简单的选型判断逻辑你的控制命令是写在手机App里还是写在飞机上的电脑里是改遥控器附近的软件还是改挂在飞机下面的硬件如果答案是“手机App”那就是MSDK没有第二种选择。文章的标题说“DJI SDK开发包接入无人机”绝大多数场景都落在MSDK这条主线上所以后面所有内容都以MSDK 4.x为例。1.2 实际项目里我是怎么选的有一次做果园巡检需求甲方想要的效果是“一个App框选区域自动生成航线无人机自己飞完并拍照”。这个需求的核心在航线规划和自动任务执行上而航线规划能力MSDK本身就提供了Waypoint Mission直接搞定所以我选了MSDK 4.x加UX SDK辅助界面。还有一次是给测绘公司做方案他们要在飞机上跑实时正射拼接要求数据不出飞机。这个用MSDK就不行了因为图像数据走到手机端再拼接延迟高、带宽也不够。当时方案改成了Onboard SDK在Jetson上做拼图MSDK只负责看状态和下发指令。这就是“按场景选SDK”的现实没搞清需求边界前不要动代码。2. 环境搭建里最容易卡住的几个配置点确认走MSDK之后第一件事不是写起飞代码而是把开发环境、账号、依赖这些地基打牢。这一节我按实际操作的顺序讲照着做能省很多时间。2.1 开发者账号、App Key和包名绑定大疆SDK的授权机制是这样的你在DJI开发者平台创建一个应用平台会分配一个App Key这个Key跟应用的包名和签名绑定。Android端App在启动时会拿当前应用的包名和签名去校验Key对不上就直接拒绝连接。我第一次跑Demo时长随便起了个项目、随便填了包名结果SDK初始化一直报错查了半天才发现App Key绑定的是另一个包名。这里有两个细节包名一旦确定就别改应用市场里的包名和开发者后台创建的包名必须一致。Android签名文件开发期和上线期如果不一样最好在后台提前处理好否则上线后App会校验失败。具体操作注册账号后在开发者后台创建应用选择Android平台填包名和签名SHA1提交后获取App Key。签名可以用keytool命令拿到keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android把SHA1填进去再把返回的App Key复制到AndroidManifest里这一步就算完成。2.2 Gradle依赖配置和Manifest声明MSDK 4.x已经发布到Maven仓库官方Maven仓库地址是https://maven.dji.com/repository/public/。在根级build.gradle里配好仓库后模块级build.gradle添加依赖implementation com.dji:dji-sdk:4.16.4 implementation com.dji:dji-uxsdk:4.16.4需要注意几个配置点compileSdk建议使用33或34太低会碰到Android 13以上的权限兼容问题。minSdk官方要求21以上但如果你的App还要做定位、蓝牙这些功能建议直接提到26。如果工程里有依赖冲突用implementation而不是api否则会暴露过多传递依赖。老项目必须开multiDexEnabled true因为MSDK体积很大65K方法数很容易超。在AndroidManifest.xml里必须声明几个关键权限uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / uses-permission android:nameandroid.permission.ACCESS_WIFI_STATE / uses-permission android:nameandroid.permission.BLUETOOTH / uses-permission android:nameandroid.permission.BLUETOOTH_ADMIN / uses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION /以及最重要的App Key声明写在application标签下meta-data android:namecom.dji.sdk.API_KEY android:value你的App Key /Android 9及以上默认禁用了明文HTTP而大疆SDK通信里有一部分用的是非HTTPS协议所以还要在application标签里加一句android:usesCleartextTraffictrue。这个不加很多设备上会出现正常的连接请求被系统拦截。2.3 初始化流程和权限处理MSDK要求在Application的onCreate里做初始化。初始化有两种方式一种是注册回调等待结果另一种是注册小部件的方式。官方的Demo用的是注册方式class MyApplication : Application() { override fun onCreate() { super.onCreate() SDKManager.getInstance().init(this, object : SDKMangerCallback { override fun onRegisterSuccess() { Log.d(DJI, SDK注册成功) } override fun onRegisterFailure(error: DJISDKError) { Log.e(DJI, SDK注册失败: $error) } }) } }这里有个容易忽略的细节SDKManager的init方法会做异步注册回调返回前不能调用任何飞行器相关API否则会拿到空对象。很多新手一进App就点击起飞按钮然后发现飞机没反应本质不是SDK没接好而是初始化还没完成就开始操作了。运行时权限方面Android 6.0以上需要在Activity里动态申请定位、相机、存储权限。这里建议不要只申请一个权限而是把SDK会用到的权限一次性申请完因为飞行器的状态信息、路线规划都可能用到定位权限。我见过很多案例是App能打开但拿不到GPS数据最后发现是定位权限没给。3. 把飞机真正“接”进来从连接动作到起飞控制环境配好了接下来就是硬核部分让App和飞机建立通信链路然后成功控制起飞。这一节我把整个链路拆开讲。3.1 四步连接法的顺序为什么不能乱大疆MSDK连接飞机的步骤看起来很简单开遥控器、插USB线、开飞机、调用API。但顺序一旦乱了后面就会遇到莫名其妙的问题。我实践的稳定顺序是先把遥控器开机。用数据线把手机或平板连接到遥控器。打开无人机电源。调用SDKManager.getInstance().startConnection()。为什么顺序重要因为SDK内部要依次完成几件事枚举USB设备、识别DJI的Vendor ID、跟飞控做协议握手、校验App Key、拉取产品信息。如果先开飞机再连USBSDK有可能在USB枚举阶段就超时如果先调连接API再插线App会认为当前没有可用设备。这个顺序并不是文档里特意强调的但实际调试中80%的连接失败都跟顺序有关。在Activity的onCreate里大概是这样触发连接SDKManager.getInstance().startConnection()连接成功后SDK会通过广播或回调告诉你当前产品状态。你可以主动去查询val product SDKManager.getInstance().product if (product null) { Toast.makeText(this, 未检测到飞机, Toast.LENGTH_SHORT).show() } else { val flightController product.flightController }这里有个细节我得提醒product返回的是Product基类不是所有机型都返回同一个类型。比如Mavic系列返回的可能是Aircraft对象而Pocket和Osmo这类产品可能没有飞行控制器。在代码里做类型判断能避免很多空指针。3.2 读取飞行状态、设置返航高度和起飞拿到FlightController之后可以读取IMU、GPS、气压计等状态也可以设置返航高度。返航高度这个参数建议在起飞前就设好我一般在App里写一个默认值50米防止低电量触发返航时撞上障碍物。flightController.setHomePointUsingAircraftLocation { error - if (error null) { Log.d(DJI, 返航点已刷新) } }设置起飞高度和起飞flightController.startTakeoff { error - if (error null) { Log.d(DJI, 起飞指令成功) } else { Log.e(DJI, 起飞失败: ${error.description}) } }起飞前最好加一个电池和GPS信号判断。行业项目里最怕的不是起飞失败而是信号没满的时候强行起飞导致后续航迹漂移。我习惯的阈值是GPS卫星数大于10颗电池电量大于60%IMU状态正常才允许执行起飞。降落和返航也一样API名字很直接flightController.startLanding(callback) flightController.startGoHome(callback)3.3 用模拟器在没飞机时调试逻辑这里有个非常实用的功能MSDK内置了仿真器Simulator。它可以模拟一个虚拟的GPS位置并把飞机“放”到地图上让你在没有真飞机的情况下调试航线、按钮逻辑和UI。开启模拟器的方法val simulator flightController.flightAssistant?.simulator simulator?.enableSimulation( LatLng(31.2304, 121.4737), 0.0, 0.0, object : DJICommonCallbacks.DJICallbackCompletionCallback() {} )参数含义第一个是模拟GPS坐标第二个是飞机速度米/秒第三个是初始机头朝向度。关闭模拟器则调用disableSimulation。模拟器有一个大坑它模拟的只是飞控层面的数据不会模拟真实的风场、禁飞区和传感器异常。所以模拟器里跑通的航线的逻辑不代表真机上就一定顺利。我一般把它当“UI调试器”用验证按钮点击流程但航线长度、转弯半径这些参数还是要靠真机实测校准。4. 实测踩坑记录那些文档里没写明白的经典问题说实话大疆SDK的接口设计整体还算规范但真正让它难上手的是那些只在特定机型、特定固件版本下才出现的诡异问题。我把自己和同行遇到最多的几类问题拿出来说每一个都是花时间换来的教训。4.1 Mini系列机型不是都能用MSDK很多人想用最便宜的Mini系列做开发这是个典型误区。Mini 2、Mini 3、Mini 3 Pro在很长一段时间里并不开放MSDK控制接口就算连接上了很多行业功能也调用不了。Mini 4 Pro开始才逐步支持MSDK。选机型前一定要去官网查“Mobile SDK支持产品列表”。项目都做了一半才发现买的飞机不支持那就不只是换硬件的问题整个技术方案都要改。我自己就吃过一次亏最初用Mini 3 Pro验证的原型后来客户买了Air 2S代码层面虽然能跑通但云台回调参数完全不一样硬调了两天。4.2 “Version not matched”到底是哪里不匹配连接失败时如果看到Version not matched或者INVALID_VERSION这样的错误很多人第一反应是SDK版本太低于是去升级SDK结果还是报错。这个错通常是三处不匹配造成的遥控器固件版本和SDK版本不兼容。飞机固件版本和SDK版本不兼容。App Key对应的产品固件版本过期。解决方法是登录开发者后台查看你需要支持的机型对应的SDK版本对照表然后把飞机、遥控器都升级到匹配的固件版本。升级时不要只升飞机不升遥控器两个设备必须配对一致。如果固件版本差异太大SDK握手失败就会报这个错。这里我特别建议在App启动时加一个版本检查逻辑把飞机固件版本、遥控器固件版本、SDK版本都打出来方便远程排查问题。省得用户发一句“连不上”你连他那边是什么状态都不知道。4.3 航线任务执行到一半停了是怎么回事Waypoint Mission跑了一半停住是行业项目里最头痛的问题。我遇到的典型案例是无人机飞到第5个航点时App收到一个错误回调然后飞机悬停在那里不动。排查链路是这样的第一步看回调错误码发现是DISCONNECTED第二步看蓝牙和USB连接状态发现遥控器和手机还在连接第三步查飞行日志发现飞机在接近第5航点时信号强度剧烈下降。最终定位是航线里有一个点位于一棵大树后方遥控器信号被挡住导致图传和控制链路中断。SDK出于安全考虑在链路断开时会自动悬停并等待重连而不是继续执行任务。解决办法是在任务开始前根据环境评估信号遮挡风险尽量把航线高度提升到障碍物以上并把失联动作设置为“继续任务”而不是“悬停”。这里顺带说一个参数Waypoint Mission里的finishedAction决定任务结束后的动作一般有NO_ACTION、GO_HOME、AUTO_LAND三种。很多事故是因为设了GO_HOME但返航高度没设置飞机在返航途中撞上高架桥。val mission WaypointMission.Builder() .addWaypoint(waypoint1) .addWaypoint(waypoint2) .autoFlightSpeed(8.0) .finishedAction(WaypointMissionFinishedAction.GO_HOME) .build() val operator SDKManager.getInstance().missionControl?.waypointMissionOperator operator?.loadMission(mission) { error - if (error null) { operator.startMission { err - Log.d(DJI, 航线开始: ${err?.description}) } } }5. 进阶玩法让无人机真正落到业务场景里把飞机稳定接进来、能起飞降落只是第一步。行业应用里真正有价值的是把航线任务、云台控制、数据回传跟业务逻辑打通。这一节分享一些我觉得比较实用的进阶思路。5.1 航点任务与实时控制的结合纯航点任务的局限性在于它是离线的任务一旦加载到飞控App不能随时改路径。有些巡检场景需要无人机飞到某个区域后根据实时识别结果调整拍摄角度或者悬停拍摄这就需要把Waypoint Mission里的某个动作跟云台控制结合起来。我的做法是在航点之间使用WaypointMission的addWaypoint设置到达动作同时监听FlightControllerState回调里的flightMode状态。识别到飞机到达某个指定经纬度范围后App主动调用云台旋转命令val gimbal product?.gimbal gimbal?.rotate(GimbalState.Rotation.Builder() .mode(GimbalState.RotationMode.ANGLE) .pitch(-60.0) .build()) { error - Log.d(DJI, 云台角度设置: ${error?.description}) }这样做的好处是航线仍由飞控接管不担心断链后飞机失控同时拍照角度可以由业务逻辑动态调整。5.2 数据回传和遥测处理行业项目通常需要把无人机的位置、电池、高度、云台角度等信息回传到后台大屏。MSDK提供了FlightControllerState和BatteryState等数据模型可以通过定时器或回调机制持续读取。我常用的做法是开一个高频定时器每秒拉一次状态然后通过WebSocket推送val state flightController.state val battery batteryState.chargeRemainingInPercent val altitude state.aircraftLocation.altitude这里有个性能建议不要把拉取逻辑放在UI线程MSDK内部本身是异步的但频繁的UI刷新会掉帧。最好用一个Handler在子线程采集数据再通过LiveData或StateFlow分发到UI层。5.3 无人机接入业务系统时的账号体系设计最后聊一个容易忽略但影响很大的问题授权。MSDK的App Key是跟包名绑定的一个App Key就是一个开发身份。如果你做了多端App安卓平板端、指挥中心端、运维手机端每一端的包名和签名不同需要分别创建应用获取不同的Key。还有一点MSDK本身没有用户登录账号体系但真机飞行需要遵守当地空域管理要求建议在App里有自己的任务审批流。我们项目里是接了内部工单系统操作员起飞前必须扫设备二维码验证机型和任务单匹配再向飞控申请起飞。SDK层面虽然没有强制但这条流程对行业客户来说几乎是刚需早设计比晚补好。我也遇到过客户希望用同一个后台同时管理多架飞机的情况这种场景需要了解大疆的上云API和独立部署的服务端方案单纯依赖MSDK做多机并发是不现实的。MSDK更适合单机交互型应用多机协同调度需要走Cloud API这条线。做DJI SDK接入这件事最核心的经验就一句话多看固件版本对照表多留日志多跑真机实测。模拟器能帮你调试逻辑但最终能不能飞起来还得靠你在真实环境下把每个环节都验证一遍。我踩过最大的坑就是过分依赖官方Demo以为能跑通Demo就能跑通项目实际上每个行业项目的飞机型号、遥控器型号、手机型号都不一样排列组合出来的问题千奇百怪。建议一开始就建立一个“机型-固件-SDK版本-测试结论”的对照表每次换设备前先查表再动手能省掉大量排查时间。本文还有配套的精品资源点击获取