目录:
大疆无人机DJI Mobile SDK(Android)入门(一)
大道无疆,创新无限!
将您的想法变为现实!
未来,无所不能!
小Z码农有幸能接触到这么高逼格的玩具。就将这段爱恨往事作为笔记记录下来......哈哈哈哈!下面开始开车了。。请系好安全带!
准备工作:
1、支持Mobile SDK 的DJI 无人机产品一架(满满的土豪感);
2、DJI Assistant 2 测试PC端模拟器下载安装;
3、android5.0手机一个(Mobile SDK 只支持5.0以上,测试手机型号HUAWEI M5 (版本android 9)和Honor 10 (版本android 10));
可根据DJI网站查看对应SDK 支持产品型号:https://developer.dji.com/products/#!/mobile
DJI Assistant 2下载地址:https://www.dji.com/cn/downloads?site=brandsite&from=footer
DJI Mobile SDK 文档查看地址:https://developer.dji.com/mobile-sdk/
和其它第三方SDK库一样,
1、注册DJI账号
2、创建Mobile SDK 应用
3、AndroidManifest.xml 填写DJI的应用App key
4、app的build.gradle 中依赖DJI库
创建DJI应用得到App key
依赖库如下(最新relase):
implementation('com.dji:dji-sdk:4.11.1', {
exclude module: 'library-anti-distortion'
exclude module: 'fly-safe-database'
})
compileOnly 'com.dji:dji-sdk-provided:4.11.1
一、注册SDK使用
1)registerApp必须先成功使用SDK注册,然后才能将DJI产品与SDK一起使用。
文档中registerApp属于DJISDKManager下的功能,所以调用如下注册方法
2)权限申请:
<!-- SDK permission requirement -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false"/>
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="true"/>
DJISampleApplication
public class DJISampleApplication extends Application {
public static final String TAG = DJISampleApplication.class.getName();
private static BaseProduct product;
private static BluetoothProductConnector bluetoothConnector = null;
private static Bus bus = new Bus(ThreadEnforcer.ANY);
private static Application app = null;
/**
* Gets instance of the specific product connected after the
* API KEY is successfully validated. Please make sure the
* API_KEY has been added in the Manifest
*/
public static synchronized BaseProduct getProductInstance() {
product = DJISDKManager.getInstance().getProduct();
return product;
}
public static synchronized BluetoothProductConnector getBluetoothProductConnector() {
bluetoothConnector = DJISDKManager.getInstance().getBluetoothProductConnector();
return bluetoothConnector;
}
public static boolean isAircraftConnected() {
return getProductInstance() != null && getProductInstance() instanceof Aircraft;
}
public static boolean isHandHeldConnected() {
return getProductInstance() != null && getProductInstance() instanceof HandHeld;
}
public static synchronized Aircraft getAircraftInstance() {
if (!isAircraftConnected()) {
return null;
}
return (Aircraft) getProductInstance();
}
public static synchronized HandHeld getHandHeldInstance() {
if (!isHandHeldConnected()) {
return null;
}
return (HandHeld) getProductInstance();
}
public static Application getInstance() {
return DJISampleApplication.app;
}
public static Bus getEventBus() {
return bus;
}
@Override
protected void attachBaseContext(Context paramContext) {
super.attachBaseContext(paramContext);
MultiDex.install(this);
com.secneo.sdk.Helper.install(this);
app = this;
}
}
MainActivity
private static final String[] REQUIRED_PERMISSION_LIST = new String[] {
Manifest.permission.VIBRATE, // Gimbal rotation
Manifest.permission.INTERNET, // API requests
Manifest.permission.ACCESS_WIFI_STATE, // WIFI connected products
Manifest.permission.ACCESS_COARSE_LOCATION, // Maps
Manifest.permission.ACCESS_NETWORK_STATE, // WIFI connected products
Manifest.permission.ACCESS_FINE_LOCATION, // Maps
Manifest.permission.CHANGE_WIFI_STATE, // Changing between WIFI and USB connection
Manifest.permission.WRITE_EXTERNAL_STORAGE, // Log files
Manifest.permission.BLUETOOTH, // Bluetooth connected products
Manifest.permission.BLUETOOTH_ADMIN, // Bluetooth connected products
Manifest.permission.READ_EXTERNAL_STORAGE, // Log files
Manifest.permission.READ_PHONE_STATE, // Device UUID accessed upon registration
Manifest.permission.RECORD_AUDIO // Speaker accessory
};
private static final int REQUEST_PERMISSION_CODE = 12345;
//region Life-cycle
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkAndRequestPermissions();
DJISampleApplication.getEventBus().register(this);
setContentView(R.layout.activity_main);
}
/**
* Result of runtime permission request
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Check for granted permission and remove from missing list
if (requestCode == REQUEST_PERMISSION_CODE) {
for (int i = grantResults.length - 1; i >= 0; i--) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
missingPermission.remove(permissions[i]);
}
}
}
// If there is enough permission, we will start the registration
if (missingPermission.isEmpty()) {
startSDKRegistration();
} else {
Toast.makeText(getApplicationContext(), "Missing permissions!!!", Toast.LENGTH_LONG).show();
}
}
/**
* Checks if there is any missing permissions, and
* requests runtime permission if needed.
*/
private void checkAndRequestPermissions() {
// Check for permissions
for (String eachPermission : REQUIRED_PERMISSION_LIST) {
if (ContextCompat.checkSelfPermission(this, eachPermission) != PackageManager.PERMISSION_GRANTED) {
missingPermission.add(eachPermission);
}
}
// Request for missing permissions
if (missingPermission.isEmpty()) {
startSDKRegistration();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this,
missingPermission.toArray(new String[missingPermission.size()]),
REQUEST_PERMISSION_CODE);
}
}
private void startSDKRegistration() {
if (isRegistrationInProgress.compareAndSet(false, true)) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_doing_message));
DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
@Override
public void onRegister(DJIError djiError) {
if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
DJILog.e("App registration", DJISDKError.REGISTRATION_SUCCESS.getDescription());
DJISDKManager.getInstance().startConnectionToProduct();
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_success_message));
showDBVersion();
} else {
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_message) + djiError.getDescription());
}
Log.v(TAG, djiError.getDescription());
}
@Override
public void onProductDisconnect() {
Log.d(TAG, "onProductDisconnect");
//断开
}
@Override
public void onProductConnect(BaseProduct baseProduct) {
Log.d(TAG, String.format("onProductConnect newProduct:%s", baseProduct));
//连上
}
@Override
public void onComponentChange(BaseProduct.ComponentKey componentKey,
BaseComponent oldComponent,
BaseComponent newComponent) {
if (newComponent != null) {
newComponent.setComponentListener(mDJIComponentListener);
}
Log.d(TAG,
String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s",
componentKey,
oldComponent,
newComponent));
notifyStatusChange();
}
@Override
public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {
}
@Override
public void onDatabaseDownloadProgress(long current, long total) {
//首次注册使用联网下载基础数据
}
});
}
});
}
}
@Override
protected void onDestroy() {
DJISampleApplication.getEventBus().unregister(this);
super.onDestroy();
}
由于涉及某些制度隐私问题,所以就只晒下应用的一些截图结果,欢迎各位留言交流学习!!