- 大疆官方开发文档目前没有提供中文的api,所以看起来可能会比较麻烦,尤其对于一些专业名词,基于官方的sdk我们能开发出什么呢?我们基于sdk可以开发出跟DJI go 4一模一样的功能
- 目前的项目就是先把大疆官方支持的功能全部实现一遍
- 然后在此基础上实现自己的功能,无论是全自动执行任务,还是远程控制都没有问题。我会在后面的篇章教大家如何基于大疆的sdk开发出一个完整的应用。
- 不再做过多的解释直接上代码,代码中有相应的注解
在app下的build.gradle中的dependencies下导包
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId ""
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true//这一行加上,否则会运行错误
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
doNotStrip "*/*/libdjivideo.so"
doNotStrip "*/*/libSDKRelativeJNI.so"
doNotStrip "*/*/libFlyForbid.so"
doNotStrip "*/*/libduml_vision_bokeh.so"
doNotStrip "*/*/libyuv2.so"
doNotStrip "*/*/libGroudStation.so"
doNotStrip "*/*/libFRCorkscrew.so"
doNotStrip "*/*/libUpgradeVerify.so"
doNotStrip "*/*/libFR.so"
doNotStrip "*/*/libDJIFlySafeCore.so"
doNotStrip "*/*/libdjifs_jni.so"
doNotStrip "*/*/libsfjni.so"
doNotStrip "*/*/libDJICommonJNI.so"
doNotStrip "*/*/libDJICSDKCommon.so"
doNotStrip "*/*/libDJIUpgradeCore.so"
doNotStrip "*/*/libDJIUpgradeJNI.so"
doNotStrip "*/*/libDJIWaypointV2Core.so"
doNotStrip "*/*/libAMapSDK_MAP_v6_9_2.so"
doNotStrip "*/*/libDJIMOP.so"
doNotStrip "*/*/libDJISDKLOGJNI.so"
exclude 'META-INF/rxjava.properties'
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation('com.dji:dji-sdk:4.15.1', {
/**
* 如果您的应用程序不需要Mavic 2 Pro和Mavic 2 Zoom的反失真功能,请取消对“库反失真”的注释。
* 如果您需要发布数据库,请取消对“飞行安全数据库”的注释,否则我们将在DJISDKManager.getInstance().registerApp时下载它
* 被称为。
* 两者都将大大减小APK的大小。
*/
exclude module: 'library-anti-distortion'
exclude module: 'fly-safe-database'
})
compileOnly 'com.dji:dji-sdk-provided:4.15.1'
}
在AndroidManifest.xml文件下添加对应的权限和配置
在Application中初始化类库
public class DroneApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Helper.install(DroneApplication.this);
}
}
MainActivity的代码如下
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.okq.flydemo.R;
import java.util.ArrayList;
import java.util.List;
import dji.common.error.DJIError;
import dji.common.error.DJISDKError;
import dji.common.realname.AircraftBindingState;
import dji.common.realname.AppActivationState;
import dji.common.useraccount.UserAccountState;
import dji.common.util.CommonCallbacks;
import dji.sdk.base.BaseComponent;
import dji.sdk.base.BaseProduct;
import dji.sdk.realname.AppActivationManager;
import dji.sdk.sdkmanager.DJISDKInitEvent;
import dji.sdk.sdkmanager.DJISDKManager;
import dji.sdk.useraccount.UserAccountManager;
import dji.thirdparty.afinal.core.AsyncTask;
public class MainActivity extends AppCompatActivity {
private static final String[] PERMISSION_LIST = new String[]{
Manifest.permission.VIBRATE, // 程序震动
Manifest.permission.INTERNET, // 访问互联网
Manifest.permission.ACCESS_WIFI_STATE, // 获取 WIFI 状态和 wifi 接入点信息
Manifest.permission.WAKE_LOCK,//关闭屏幕时后台进程仍然进行
Manifest.permission.ACCESS_COARSE_LOCATION, // 获得模糊定位信息
Manifest.permission.ACCESS_NETWORK_STATE, // 获取网络状态信息
Manifest.permission.ACCESS_FINE_LOCATION, // 获取精准定位信息
Manifest.permission.CHANGE_WIFI_STATE, // 改变wifi连接状态
Manifest.permission.WRITE_EXTERNAL_STORAGE, // 写入外部存储信息
Manifest.permission.BLUETOOTH, // 配对蓝牙设备
Manifest.permission.BLUETOOTH_ADMIN, // 配对蓝牙设备(不通知用户)
Manifest.permission.READ_EXTERNAL_STORAGE, // 读取外部存储信息
Manifest.permission.READ_PHONE_STATE, // 访问电话状态
Manifest.permission.RECORD_AUDIO // 录音权限
};
//缺失的用户权限
public static List missingPermission = new ArrayList<>();
private Button btn_login,btn_logout,btn_status_appactivation,btn_status_aircraftbinding;
private TextView tv_status_appactivation,tv_status_aircraftbinding;
//应用程序激活状态监听
private AppActivationState.AppActivationStateListener appActivationStateListener;
//无人机绑定状态监听
private AircraftBindingState.AircraftBindingStateListener aircraftBindingStateListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//检查用户权限
if (!checkPermissions()) {
requestPermissions();
}
if (checkPermissions()) {
//注册应用程序
registerAppLication();
}
initView();
initListener();
}
private void initListener() {
appActivationStateListener = new AppActivationState.AppActivationStateListener() {
@Override
public void onUpdate(AppActivationState appActivationState) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_status_appactivation.setText("当前应用激活状态:"+appActivationState.name());
}
});
}
};
aircraftBindingStateListener = new AircraftBindingState.AircraftBindingStateListener() {
@Override
public void onUpdate(AircraftBindingState aircraftBindingState) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_status_aircraftbinding.setText("当前无人机绑定状态:"+aircraftBindingState.name());
}
});
}
};
//添加应用程序激活监听
AppActivationManager.getInstance().addAppActivationStateListener(appActivationStateListener);
//添加无人机绑定监听
AppActivationManager.getInstance().addAircraftBindingStateListener(aircraftBindingStateListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除应用程序激活监听
AppActivationManager.getInstance().removeAppActivationStateListener(appActivationStateListener);
//移除无人机绑定监听
AppActivationManager.getInstance().removeAircraftBindingStateListener(aircraftBindingStateListener);
}
private void initView() {
tv_status_appactivation = (TextView) findViewById(R.id.tv_status_appactivation);
tv_status_aircraftbinding = (TextView) findViewById(R.id.tv_status_aircraftbinding);
//登录dji账号
btn_login = (Button)findViewById(R.id.btn_login);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UserAccountManager.getInstance().logIntoDJIUserAccount(MainActivity.this, new CommonCallbacks.CompletionCallbackWith() {
@Override
public void onSuccess(UserAccountState userAccountState) {
ShowToas("登录成功");
}
@Override
public void onFailure(DJIError djiError) {
ShowToas("登录失败:"+djiError.getDescription());
}
});
}
});
//退出账号
btn_logout = (Button)findViewById(R.id.btn_logout);
btn_logout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UserAccountManager.getInstance().logoutOfDJIUserAccount(new CommonCallbacks.CompletionCallback() {
@Override
public void onResult(DJIError djiError) {
if (djiError == null){
ShowToas("退出成功");
}else {
ShowToas("退出失败:"+djiError.getDescription());
}
}
});
}
});
//获取应用激活状态
btn_status_appactivation = (Button)findViewById(R.id.btn_status_appactivation);
btn_status_appactivation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AppActivationManager appActivationManager = DJISDKManager.getInstance().getAppActivationManager();
AppActivationState appActivationState = appActivationManager.getAppActivationState();
ShowToas("激活状态:"+appActivationState);
if (!(""+appActivationState).equals("ACTIVATED")){
Intent launchIntentForPackage = getPackageManager().getLaunchIntentForPackage("dji.go.v4");
if (launchIntentForPackage != null){
startActivity(launchIntentForPackage);
}else {
ShowToas("未安装 DJI Go");
}
}
}
});
//获取无人机绑定状态
btn_status_aircraftbinding = (Button)findViewById(R.id.btn_status_aircraftbinding);
btn_status_aircraftbinding.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AppActivationManager appActivationManager = DJISDKManager.getInstance().getAppActivationManager();
AircraftBindingState aircraftBindingState = appActivationManager.getAircraftBindingState();
ShowToas("绑定状态:"+aircraftBindingState);
if (!(""+aircraftBindingState).equals("BOUND")){
Intent launchIntentForPackage = getPackageManager().getLaunchIntentForPackage("dji.go.v4");
if (launchIntentForPackage != null){
startActivity(launchIntentForPackage);
}else {
ShowToas("未安装 DJI Go 4");
}
}
}
});
}
//注册程序
private void registerAppLication() {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
@Override
public void onRegister(DJIError djiError) {//注册应用程序回调方法
if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
ShowToas("onRegister--->应用注册成功:" + djiError.getDescription());
DJISDKManager.getInstance().enableBridgeModeWithBridgeAppIP("192.168.1.189");
} else {
ShowToas("onRegister--->应用注册失败:" + djiError.getDescription());
}
}
@Override
public void onProductDisconnect() {//无人机失去连接回调
ShowToas("onProductDisconnect--->设备断开连接");
}
@Override
public void onProductConnect(BaseProduct baseProduct) {//无人机连接回调
if (baseProduct.getModel() == null){
return;
}
ShowToas("onProductConnect--->设备连接"+baseProduct.getModel().getDisplayName());
}
@Override
public void onProductChanged(BaseProduct baseProduct) {//无人机连接变化回调
if (baseProduct == null){
return;
}
ShowToas("onProductChanged--->设备连接"+baseProduct.getModel().getDisplayName());
}
//无人机组件 变化变化回调
@Override
public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent baseComponent, BaseComponent baseComponent1) {
ShowToas("onComponentChange--->"+String.format("组件变化 键:%s,旧组件:%s,新组件:%s",componentKey,baseComponent,baseComponent1));
}
@Override
public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {//初始化进程回调
ShowToas("onInitProcess--->"+djisdkInitEvent.getInitializationState().toString() + "进度:" + i + "%");
}
@Override
public void onDatabaseDownloadProgress(long l, long l1) {//限飞数据库下载进度回调
// ShowToas("onDatabaseDownloadProgress--->已下载: "+l+"字节,总共:"+l1+"字节");
Log.i("TAG", "onDatabaseDownloadProgress--->已下载: "+l+"字节,总共:"+l1+"字节");
}
});
}
});
}
private void ShowToas(String msg){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
public boolean checkPermissions() {
//判断应用程序编辑的SDK版本是否大于22
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (String string : PERMISSION_LIST) {
if (ContextCompat.checkSelfPermission(MainActivity.this, string) != PackageManager.PERMISSION_GRANTED) {
//没有赋予的权限添加到集合中
missingPermission.add(string);
}
}
return missingPermission.isEmpty();
} else {
return false;
}
}
public void requestPermissions() {
//申请所有没有被赋予的权限
ActivityCompat.requestPermissions(MainActivity.this, missingPermission.toArray(new String[missingPermission.size()]), 1009);
}
}
activity_main.xml布局文件如下
-
至此就能获取对应的设备状态和账号登录等状态,我使用的御2无人机
DJI Go 4下载地址(https://www.dji.com/cn/downloads/djiapp/dji-go-4)
- 参考资料《大疆无人机二次开发教程》