空白项目集成 MSDK
本指引介绍如何将 MSDK V5 Sample 中的 MSDK 包和 UXSDK 开源框架移植到用户的空白项目中。
推荐环境
- Android Studio:
Android Studio Koala | 2024.1.1
- Java Runtime:
17
or11
- Kotlin:
1.8.10
- Gradle:
7.6.2
- Android Gradle Plugin:
7.4.2
- minSdkVersion:
23
- targetSdkVersion:
34
- 如需使用非推荐版本,请根据实际版本自行适配整个集成过程。Android Studio Koala 2024.1.1 默认集成 Java Runtime 17,一般可以直接使用即可,无需做任何配置。
- Kotlin Android 扩展已被弃用,即不再支持使用 Kotlin 合成视图绑定。如需使用 Kotlin 合成技术,请按照如下指南迁移到 Jetpack 视图绑定:从 Kotlin 合成迁移到 Jetpack 视图绑定。
获取已集成 MSDK 的空白工程
如果不打算按照下述教程手动配置你的工程,可以选择下载 [已集成 MSDK 的空白工程],参考本文档从 测试与调试 处直接开始进行最后一步配置与调试。
新建空白项目
- 在 Android Studio 启动页,选择 New Project > Phone and Tablet > Empty Views Activity
- 按照下图完成配置。
- Name:
MSDKSample
- Package name:
com.example.msdksample
- Minimum SDK:
24
或者更高 - Build configuration language:
Groovy DSL (build.gradle)
- Name:

修改 build.gradle (Project) 文件
打开 Gradle Scripts
下的 build.gradle (Project)
,将文件内的代码替换为如下代码,这段代码的作用是提供正确的引用库。
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
// 推荐的 Android Gradle Plugin 版本,不做强求,可以自定适配需要的版本。但是如果你需要引入 UXSDK 框架,则建议使用推荐版本,否则可能会出现编译兼容性问题。
classpath "com.android.tools.build:gradle:7.4.2"
// 推荐的 Kotlin 版本,如果你需要引入 UXSDK 框架,则建议使用推荐版本,否则可能会出现编译兼容性问题
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION" //DJI MSDK 建议的版本
// ... (remaining code)
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
修改 build.gradle (Module: app) 文件
- 在
android
项中的defaultConfig
中配置minSdkVersion
以及ndk
,配置packagingOptions
。
注意版本:
minSdkVersion
的最低版本号不要低于 23。- 当前 MSDK 只支持 arm64-v8a 架构。
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
namespace 'com.example.msdksample'
compileSdkVersion 34 // 建议大于等 34,因为 MSDK 已经适配 Android 14 版本
defaultConfig {
applicationId "com.example.msdksample"
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'arm64-v8a' // 当前 MSDK 只支持 arm64-v8a 架构
}
// MSDK 相关的 so 库,加上一下配置
packagingOptions {
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
}
// MSDK 相关的 so 库,加上一下配置
packagingOptions {
doNotStrip "*/*/libconstants.so"
doNotStrip "*/*/libdji_innertools.so"
doNotStrip "*/*/libdjibase.so"
doNotStrip "*/*/libDJICSDKCommon.so"
doNotStrip "*/*/libDJIFlySafeCore-CSDK.so"
doNotStrip "*/*/libdjifs_jni-CSDK.so"
doNotStrip "*/*/libDJIRegister.so"
doNotStrip "*/*/libdjisdk_jni.so"
doNotStrip "*/*/libDJIUpgradeCore.so"
doNotStrip "*/*/libDJIUpgradeJNI.so"
doNotStrip "*/*/libDJIWaypointV2Core-CSDK.so"
doNotStrip "*/*/libdjiwpv2-CSDK.so"
doNotStrip "*/*/libFlightRecordEngine.so"
doNotStrip "*/*/libvideo-framing.so"
doNotStrip "*/*/libwaes.so"
doNotStrip "*/*/libagora-rtsa-sdk.so"
doNotStrip "*/*/libc++.so"
doNotStrip "*/*/libc++_shared.so"
doNotStrip "*/*/libmrtc_28181.so"
doNotStrip "*/*/libmrtc_agora.so"
doNotStrip "*/*/libmrtc_core.so"
doNotStrip "*/*/libmrtc_core_jni.so"
doNotStrip "*/*/libmrtc_data.so"
doNotStrip "*/*/libmrtc_log.so"
doNotStrip "*/*/libmrtc_onvif.so"
doNotStrip "*/*/libmrtc_rtmp.so"
doNotStrip "*/*/libmrtc_rtsp.so"
}
- 在
dependencies
中配置 SDK 包,并将其他引用库修改到对应的版本。
注意:{$SDK_VERSION} 为 MSDK 最新版本。如需替换,参考修改 gradle.properties 文件。
dependencies {
implementation project(":android-sdk-v5-uxsdk")
implementation "com.dji:dji-sdk-v5-aircraft:$SDK_VERSION"
compileOnly "com.dji:dji-sdk-v5-aircraft-provided:$SDK_VERSION"
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
修改 AndroidManifest.xml 文件
以下操作请参考 MSDK V5 Sample 的 AndroidManifest.xml 文件进行修改,注意代码段与标签之间位置。
- 参照添加 SDK 需要的最基础权限。在添加权限前,请确认已了解 MSDK V5 都需要哪些安卓系统权限 和 权限具体含义。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
- 在
manifest
标签内添加 USB 相关权限,为了连接遥控器使用。
<uses-feature
android:name="android.hardware.usb.host"
android:required="false"/>
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="true"/>
- 在
application
标签中添加Myapplication
文件的声明,启动的时候需要加载。
<application
android:name=".MyApplication"
//... (remaining code)
- 在
application
标签属性修改为如下代码段,用于配置 app key。
前往 开发者网站 申请 app key,申请 app key 时,Package Name 需填写 com.example.msdksample
。 成功后将如下代码添加到 application
项中,保持android:name
不变,将android:value
中的 your app key 替换为你申请的 app key。

<meta-data
android:name="com.dji.sdk.API_KEY"
android:value="your app key"/>
- 在
activity
标签中配置 USB 配件通知。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
新建 MyApplication.kt 文件
- 在
com.example.msdksample
文件夹下新建MyApplication.kt
文件,与MainActivity.kt
同级。 - 文件内容写为如下代码,作用是引入 SDK 的解密加固包。
注意: 注意包名的一致性:com.example.msdksample。
package com.example.msdksample
import android.app.Application
import android.content.Context
import android.util.Log
import dji.v5.common.error.IDJIError
import dji.v5.common.register.DJISDKInitEvent
import dji.v5.manager.SDKManager
import dji.v5.manager.interfaces.SDKManagerCallback
class MyApplication : Application() {
private val TAG = this::class.simpleName
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
// 在调用 install 前,请勿调用任何 MSDK 相关接口
// MSDK v5.10.0 之前的版本请使用 com.secneo.sdk.Helper.install(this)
com.cySdkyc.clx.Helper.install(this)
}
override fun onCreate() {
super.onCreate()
// 初始化 MSDK,建议初始化逻辑放在 Application 中,当然也可以根据自己的需要放在任意地方。
SDKManager.getInstance().init(this,object:SDKManagerCallback{
override fun onInitProcess(event: DJISDKInitEvent?, totalProcess: Int) {
Log.i(TAG, "onInitProcess: ")
if (event == DJISDKInitEvent.INITIALIZE_COMPLETE) {
SDKManager.getInstance().registerApp()
}
}
override fun onRegisterSuccess() {
Log.i(TAG, "onRegisterSuccess: ")
}
override fun onRegisterFailure(error: IDJIError?) {
Log.i(TAG, "onRegisterFailure: ")
}
override fun onProductConnect(productId: Int) {
Log.i(TAG, "onProductConnect: ")
}
override fun onProductDisconnect(productId: Int) {
Log.i(TAG, "onProductDisconnect: ")
}
override fun onProductChanged(productId: Int)
{
Log.i(TAG, "onProductChanged: ")
}
override fun onDatabaseDownloadProgress(current: Long, total: Long) {
Log.i(TAG, "onDatabaseDownloadProgress: ${current/total}")
}
})
}
}
修改 MainActivity.kt 文件
- 在
MainActivity.kt
同级目录下,删除ui
文件夹。 - 修改
MainActivity.kt
文件,将其内容替换为如下代码。
注意: 注意包名的一致性:com.example.msdksample。
package com.example.msdksample
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
新建 activity_main.xml 文件
- 在 app > src > main > res 目录下,新建
layout
文件夹,并在文件夹下新建activity_main.xml
文件。 - 修改
activity_main.xml
文件,将其内容替换为如下代码。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 在 app > src > main > res > values 目录下,修改
themes.xml
文件,将其内容替换为如下代码。
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.MSDKSample" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.MSDKSample" parent="Base.Theme.MSDKSample" />
</resources>
导入 UXSDK 开源框架
将 UXSDK 项目(android-sdk-v5-uxsdk)整个复制到
SDKSample
项目路径的根目录下,与app
文件夹同级。修改
gradle.properties
文件,添加以下代码来配置正确的版本,因为 UXSDK Module 的build.gradle
默认读取gradle.properties
所定义的常量作为配置版本。当然你也可以直接修改build.gradle
中的配置版本,但是建议使用 DJI 推荐的版本,否则可能有版本适配的成本。
#buildconfig
ANDROID_MIN_SDK_VERSION=23 //DJI MSDK 最低支持的版本
ANDROID_TARGET_SDK_VERSION=34 //DJI MSDK 最高支持的版本
ANDROID_COMPILE_SDK_VERSION=34 //DJI MSDK 推荐使用的版本
- 在与
build.gradle (project)
同级的路径下新建dependencies.gradle
,将 dependencies.gradle 内容导入进去。 并将以下代码段加入build.gradle (Project)
文件顶部。
apply from:rootProject.file('dependencies.gradle')
- 在
setting.gradle
文件中调整代码为以下内容。
rootProject.name = "MSDKSample"
include ':app'
include ':android-sdk-v5-uxsdk'
- 文件夹目录 app > res > values > strings.xml,在文件中修改这行字符串的属性,这行代码的意义是修改 app 名称。
<string name="your_app_name">MSDKSample</string>
在实际开发中可以修改上面这行代码的 id 和字段,只需要和项目中 AndroidManifest.xml
中如下对应的 id 名称保持一致,在这个示例中应用程序的 id 名称为 "your_app_name"。
<application
android:label="@string/your_app_name">
修改 gradle.properties 文件
- 在
gradle.properties
文件内,可以使用KOTLIN_VERSION
项和SDK_VERSION
项控制空白工程使用的 Kotlin 版本和 MSDK 版本。譬如,可在#buildconfig
项后增加以下两行代码,以使用 Kotlin 1.8.10 版本和 MSDK 5.10.0 版本。
KOTLIN_VERSION=1.8.10
SDK_VERSION=5.10.0
注意: gradle.properties 相应的配置项需要修改为以下内容,否则可能会出现编译兼容性问题。
android.useAndroidX=true android.enableJetifier=true android.nonTransitiveRClass=false
至此你已经完成了空白项目的配置。
测试与调试
选择 "Sync Now" 同步工程。
选择界面上的锤子图标,编译你的工程,并进行必要的调试。
由于空白项目的局限性,集成后 build 时偶现
UXSDK
包内容引用不到的报错,这不影响项目的正常运行,可以继续尝试第二步直接连接设备运行,如果在集成过程中发现解决此类报错的方法欢迎通过文档进行反馈。可能出现的报错如下:
Execution failed for task ':android-sdk-v5-uxsdk:kaptGenerateStubsDebugKotlin'.
- 连接 DJI 带屏遥控器或你的移动设备,打开相应的开发人员选择,在 Android Studio 右上角显示你的设备后选择 run'app' 三角图标,测试工程是否可以正常运行。