为了方便移动开发初学者的学习,本节将从创建一个Android项目开始,详细介绍整合Mobile SDK到Android项目的方法。但是,如果读者手中已经有一个Android项目需要使用Mobile SDK,那么在设置该项目的最低SDK版本选项为5.0或以上版本的基础上,跳过下面的“1. 创建Android应用程序”部分进行配置即可。
打开Android Studio(本书使用4.0.1版本进行演示),并在Android Studio欢迎页面中单击“+ Start a new Android Studio project”(见图3-2)选项创建一个新的项目,并弹出“Create New Project”对话框。
图3-2 Android Studio欢迎页面
在“Select a Project Template”标题页中选择所创建的项目模板“Phone and Tablet”选项卡下的“Empty Activity”选项,并单击【Next】按钮进入下一步,如图3-3所示。
图3-3 “Select a Project Template”标题页
在“Configure Your Project”标题页中输入项目的基本信息:在“Name”选项中输入项目名称“DroneFly”;在“Package name”选项中输入包名“cas.igsnrr.dronefly”;在“Save location”选项中输入项目的保存位置;在“Language”选项中选择使用的编程语言“Java”。由于Mobile SDK所支持的最低Android SDK版本为5.0,因此在“MinimumSDK”选项中选择项目的最低SDK版本“API 21: Android 5.0 (Lollipop)”,如图3-4所示。设置完成后,单击【Finish】按钮确认。
图3-4 “Configure Your Project”标题页
❀ 这里设置的项目包名用于申请应用程序密钥(详见“2.3.3申请应用程序密钥”节内容)。
此时,Android Studio已经根据所选项目模板创建了一个名为“DroneFly”的项目,并自动创建了一个空的Activity,即MainActivity,如图3-5所示。
图3-5 DroneFly项目中的MainActivity
Android Mobile SDK 4.2之前的版本需要导入本地的SDK类库文件到应用程序项目中,但是在最新版本的Android Mobile SDK中只需要使用Maven或Gradle等构建工具,通过代码仓库的方式下载即可。具体的操作方法如下。
(1)在项目资源管理器中,打开“Gradle Scripts”下的“build.gradle (Module: app)”文件,如图3-6所示。
图3-6 DroneFly项目中的build.gradle (Module: app)文件
(2)在该Gradle配置文件的dependencies部分加入Mobile SDK的相关依赖,具体实现如代码3-1所示。注意,本书中所有的代码框均统一使用加粗文字标注新增代码。
代码3-1
由此可见,Android Mobile SDK分为“dji-sdk”和“dji-sdk-provided”两个部分:
① 通过implementation指令依赖的“dji-sdk”包括dji-sdk-4.13.1.aar文件(包含运行时所需要的各种资源与类库)和dji-sdk-4.13.1.pom文件(项目对象模型)。Android Studio会将其编译并打包到最终的应用程序中。
② 通过compileOnly指令依赖的“dji-sdk-provided”包含有dji-sdk-provided-4.13.1sources.jar、dji-sdk-provided-4.13.1.jar、dji-sdk-provided-4.13.1-javadoc.jar、dji-sdk-provided 4.13.1.pom四个文件,仅在代码编辑和编译时支持使用。
❀ 在使用Android Mobile SDK时,必须要加入“lifecycle-extensions”依赖,否则在注册应用程序时会出现“闪退”,并报出“ java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/lifecycle/ProcessLifecycleOwner;”错误。
另外,对于“dji-sdk”依赖部分,可通过“exclude module”代码去除部分Module以降低移动应用程序安装包的大小。例如,通过“exclude module: 'library-anti-distortion'”代码可去除抗畸变(Anti Distortion)模块,通过“exclude module: 'fly-safe-database'”代码可去除限飞数据库模块,这两个模块在编译后的应用程序中会占用很大的存储空间,具体实现如代码3-2所示。
代码3-2
抗畸变(Anti Distortion)模块是对御2 Pro、御2 Zoom和御2 Enterprise Zoom三款无人机特别设计的用于原始视频流的解码与失真校正类库,去除该模块后将不支持上述无人机的图传视频解码。当从“dji-sdk”依赖中去除限飞数据库模块后,在应用程序注册(调用SDK管理器的registerApp方法)时会自动下载最新的限飞数据库。
(3)在Gradle配置文件的android部分添加动态链接库的打包选项,以避免编译错误,具体实现如代码3-3所示。
代码3-3
此时,选择Android Studio菜单栏中的【File】-【Sync Project with Gradle Files】菜单更新Gradle配置,并通过仓库下载依赖项。稍等片刻后,当Android Studio状态栏出现“Gradle sync finished in …”提示时说明Gradle配置完成。
❀ 由于Android Mobile SDK的类库体积很大,因此可能会在编译时出现“Error: Cannot fit requested classes in a single dex file (# methods: 72725 > 65536)”错误。此时,可以在上述Gradle配置文件中,在android部分的defaultConfig部分内添加“multiDexEnabled true”代码解决这个问题。
通过以下方法可以检查是否通过Gradle成功下载Mobile SDK的相关依赖:单击Android Studio菜单栏中的【File】-【Project Structure…】菜单(快捷键:Ctrl+Alt+Shift+S)打开“ Project Structure ”对话框,如图3-7所示。在该对话框中,选择左侧的“Dependencies”选项,并在Modules列表中选择“app”。此时,如果在右侧的依赖声明列表中找到“dji-sdk:4.13.1”与“dji-sdk-provided:4.13.1”依赖,则说明Gradle配置成功。
图3-7 “Project Structure”对话框
打开DroneFly项目的AndroidManifest.xml文件,在manifest根标签内添加以下权限、特征等XML声明语句,具体实现如代码3-4所示。
代码3-4
在代码3-4中,需要通过应用程序包名(已在代码3-4中用下画线标注)在大疆开发者网站申请的应用程序密钥(详见“2.3.3申请应用程序密钥”节内容),并将密钥填入“<输入应用程序密钥>”位置。
另外,uses-permission标签表示应用程序所需要使用的用户权限;uses-feature标签表示应用程序的软硬件需求特征(一般用于应用上线商店);uses-library标签表示应用程序所需要连接的共享库;名为“DJIAoaControllerActivity”的activity标签用于通过USB设备连接无人机遥控器;名为“DJIGlobalService”的service标签为应用程序提供Mobile SDK的全局服务。
初始化类库,即在应用程序的Application对象中,通过com.secneo.sdk.Helper类的install(Application app)方法注册Mobile SDK,具体的方法如下。
(1)在“cas.igsnrr.dronefly”类库中单击鼠标右键,选择【New】-【Java Class】创建Java类,弹出如图3-8所示的“New Java Class”对话框。
图3-8 “New Java Class”对话框
(2)在“New Java Class”对话框中,在“Name”选项中输入类名“DroneApplication”;在“Superclass”选项中输入其父类“android.app.Application”;确认“Package”选项的内容为“cas.igsnrr.dronefly”;其他选项保持默认值,单击【OK】按钮创建DroneApplication类。
(3)在DroneApplication类中复写attachBaseContent(Context paramContext)方法,并调用Helper的install(Application app)方法,具体实现如代码3-5所示。
代码3-5
(4)在AndroidManifest.xml中注册DroneApplication对象,具体实现如代码3-6所示。
代码3-6
此时,初始化类库的代码已经完成。在每次启动DroneFly应用程序时,都会实例化一个DroneApplication对象,并调用attachBaseContent方法的代码。
值得注意的是,Helper的install(Application app)方法不能在MainActivity中执行。如果错误地将该代码添加到了MainActivity的OnCreate(Bundle savedInstanceState)方法中或者直接缺失上述代码,则当使用Mobile SDK的类库时会报“java.lang.NoClassDefFoundError:Failed resolution of: Ldji/sdk/sdkmanager/DJISDKManager;”错误。
在MainActivity.java中申请用户权限,如代码3-7所示。
代码3-7
通过上述代码,在MainActivity被创建时会检查PERMISSION_LIST列表中的权限是否被正确授权。如果存在没有被授权的权限,则会将其放置在missingPermission列表对象中。最后,如果missingPermission列表不为空,则调用requestPermissions()方法申请缺失的权限。
此时调试运行程序,会在应用程序启动时弹出权限确认提示框(界面会依Android发行版类型的不同而有所不同),如图3-9所示。
图3-9 权限确认提示框
此时,用户需要全部单击【允许】按钮后才可正常使用Mobile SDK。