利用手头的大疆无人机,我们还可以通过二次开发做很多有趣的事情,最重要的是,毕竟是成熟的消费级无人机,安全性比PIX要好得多,在前期用来验证上层算法再合适不过了。
版权声明
原创文章,转载请说明出处:sheng-blog.cn
原文出处
博文结构:
创建一个新工程,解压下载的Mobile_SDK,Import Module选中API Library如下图,提示出现djiSDKLIB,确定,导入配置维持默认。
然后打开Project Structure 给工程添加djiSDKLIB的依赖,如下图,然后SYNC。可能需要修改build.gradle(djiSDKLIB)的buildToolsVersion,将其修改到与app模块一致。最好不要修改它的三个SdkVersion,可能导致莫名其妙的错误(我就被坑了一下),毕竟大疆做这个SDK还没多久,一直处于完善状态,难免有些BUG,只能尽量避开。
下一步就是实现APP注册登记的回调函数,打开MainActivity.java
为了引进注册APP需要的安卓和 DJI SDK类,在import android.os.Bundle;
后加入以下代码:
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import dji.common.error.DJIError;
import dji.common.error.DJISDKError;
import dji.sdk.base.BaseComponent;
import dji.sdk.base.BaseProduct;
import dji.sdk.sdkmanager.DJISDKManager;
MainActivity需要完成APP的注册来获取对飞行器的控制权(这应该是大疆用来记录并追责的一种手段),修改如下:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getName();
public static final String FLAG_CONNECTION_CHANGE = "dji_sdk_connection_change";
private static BaseProduct mProduct;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize DJI SDK Manager
mHandler = new Handler(Looper.getMainLooper());
DJISDKManager.getInstance().registerApp(this, mDJISDKManagerCallback);
}
}
DJISDKManager有两个回调函数接口分别用来监听注册的结果以及无人机和APP的连接状态的改变,代码如下:
private DJISDKManager.SDKManagerCallback mDJISDKManagerCallback = new DJISDKManager.SDKManagerCallback() {
@Override
public void onRegister(DJIError error) {
Log.d(TAG, error == null ? "success" : error.getDescription());
if(error == DJISDKError.REGISTRATION_SUCCESS) {
DJISDKManager.getInstance().startConnectionToProduct();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Register Success", Toast.LENGTH_LONG).show();
}
});
} else {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "register sdk failed, check if network is available", Toast.LENGTH_LONG).show();
}
});
}
Log.e("TAG", error.toString());
}
@Override
public void onProductChange(BaseProduct oldProduct, BaseProduct newProduct) {
mProduct = newProduct;
if(mProduct != null) {
mProduct.setBaseProductListener(mDJIBaseProductListener);
}
notifyStatusChange();
}
};
另需实现以下四个方法:
private BaseProduct.BaseProductListener mDJIBaseProductListener = new BaseProduct.BaseProductListener() {
@Override
public void onComponentChange(BaseProduct.ComponentKey key, BaseComponent oldComponent, BaseComponent newComponent) {
if(newComponent != null) {
newComponent.setComponentListener(mDJIComponentListener);
}
notifyStatusChange();
}
@Override
public void onConnectivityChange(boolean isConnected) {
notifyStatusChange();
}
};
private BaseComponent.ComponentListener mDJIComponentListener = new BaseComponent.ComponentListener() {
@Override
public void onConnectivityChange(boolean isConnected) {
notifyStatusChange();
}
};
private void notifyStatusChange() {
mHandler.removeCallbacks(updateRunnable);
mHandler.postDelayed(updateRunnable, 500);
}
private Runnable updateRunnable = new Runnable() {
@Override
public void run() {
Intent intent = new Intent(FLAG_CONNECTION_CHANGE);
sendBroadcast(intent);
}
};
接下来需要在AndroidManifest.xml里声明需要用到的系统权限:
在package=com.dji.ImportSDKDemo>
和
<uses-sdk />
<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.WAKE_LOCK" />
<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.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false" />
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="true" />
在android:theme="@style/AppTheme">
和
间插入:
<uses-library android:name="com.android.future.usb.accessory" />
<meta-data
android:name="com.dji.sdk.API_KEY"
android:value="Please enter your App Key here." />
<activity
android:name="dji.sdk.sdkmanager.DJIAoaControllerActivity"
android:theme="@android:style/Theme.Translucent" >
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
activity>
<service android:name="dji.sdk.sdkmanager.DJIGlobalService" >
service>
然后在开发者官网注册一个KEY,注意package name一定要和AndroidManifest一致,如图:
用这串KEY替换Please enter your App Key here.
这就完成移植了,运行一下:
Integrate SDK into Application