空白项目集成 MSDK

2024-11-18
暂无评分

本指引介绍如何将 MSDK V5 Sample 中的 MSDK 包和 UXSDK 开源框架移植到用户的空白项目中。

推荐环境

  • Android Studio:Android Studio Koala | 2024.1.1
  • Java Runtime:17 or 11
  • 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 的空白工程]open in new window,参考本文档从 测试与调试 处直接开始进行最后一步配置与调试。

新建空白项目

  1. 在 Android Studio 启动页,选择 New Project > Phone and Tablet > Empty Views Activity
  2. 按照下图完成配置。
    • Name:MSDKSample
    • Package name:com.example.msdksample
    • Minimum SDK:24 或者更高
    • Build configuration language:Groovy DSL (build.gradle)
empty project

修改 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) 文件

  1. 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"
        }
  1. 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.xmlopen in new window 文件进行修改,注意代码段与标签之间位置。

  1. 参照添加 SDK 需要的最基础权限。在添加权限前,请确认已了解 MSDK V5 都需要哪些安卓系统权限open in new window权限具体含义open in new window
    <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" />
  1. manifest 标签内添加 USB 相关权限,为了连接遥控器使用。
<uses-feature
    android:name="android.hardware.usb.host"
    android:required="false"/>
<uses-feature
    android:name="android.hardware.usb.accessory"
    android:required="true"/>
  1. application 标签中添加 Myapplication 文件的声明,启动的时候需要加载。
  <application
    android:name=".MyApplication"
    //... (remaining code)

  1. application 标签属性修改为如下代码段,用于配置 app key。

前往 开发者网站open in new window 申请 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"/>
  1. 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 文件

  1. com.example.msdksample 文件夹下新建 MyApplication.kt 文件,与 MainActivity.kt 同级。
  2. 文件内容写为如下代码,作用是引入 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 文件

  1. MainActivity.kt 同级目录下,删除 ui 文件夹。
  2. 修改 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 文件

  1. 在 app > src > main > res 目录下,新建 layout 文件夹,并在文件夹下新建 activity_main.xml 文件。
  2. 修改 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>
  1. 在 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 开源框架

  1. 将 UXSDK 项目(android-sdk-v5-uxsdkopen in new window)整个复制到 SDKSample 项目路径的根目录下,与 app 文件夹同级。

  2. 修改 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 推荐使用的版本
  1. 在与 build.gradle (project) 同级的路径下新建 dependencies.gradle,将 dependencies.gradleopen in new window 内容导入进去。 并将以下代码段加入 build.gradle (Project) 文件顶部。
apply from:rootProject.file('dependencies.gradle')
  1. setting.gradle 文件中调整代码为以下内容。
rootProject.name = "MSDKSample"
include ':app'
include ':android-sdk-v5-uxsdk'
  1. 文件夹目录 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 文件

  1. 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

至此你已经完成了空白项目的配置。

测试与调试

  1. 选择 "Sync Now" 同步工程。

  2. 选择界面上的锤子图标,编译你的工程,并进行必要的调试。

由于空白项目的局限性,集成后 build 时偶现 UXSDK 包内容引用不到的报错,这不影响项目的正常运行,可以继续尝试第二步直接连接设备运行,如果在集成过程中发现解决此类报错的方法欢迎通过文档进行反馈。可能出现的报错如下:

Execution failed for task ':android-sdk-v5-uxsdk:kaptGenerateStubsDebugKotlin'.
  1. 连接 DJI 带屏遥控器或你的移动设备,打开相应的开发人员选择,在 Android Studio 右上角显示你的设备后选择 run'app' 三角图标,测试工程是否可以正常运行。
若您对文档有意见或疑惑,点击可快速反馈,我们会与您联系。