您的位置:首页 > 其它

大疆无人机二次开发简介-引入DJI mobile SDK 4.4.1

2018-02-03 11:27 513 查看
基于android studio 2.3.3

1、引入DJI mobile SDK 4.4.1和DJI Uilibrary 4.4.1

部分build.gradle如下

apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "25.0.3"
defaultConfig {
multiDexEnabled true
ndk {
abiFilters 'armeabi-v7a', 'x86', 'arm64-v8a'
}
}
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"
}
}
dependencies {
compile 'com.dji:dji-uilibrary:4.4.1'
provided 'com.dji:dji-sdk-provided:4.4.1'
}


2、AndroidManifest配置

<!-- DJI SDK need permission -->
<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.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_ALER
d4a0
T_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" />

<!-- SDK requirement permission end -->
<application
android:name=".YourApplication"
android:allowBackup="true"
android:icon="@mipmap/applogo"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:replace="android:icon,android:theme">

<!-- DJI SDK -->
<uses-library android:name="com.android.future.usb.accessory" />

<meta-data
android:name="com.dji.sdk.API_KEY"
android:value="Your Key" /> <!-- KEY去大疆开发者网页去申请android mobile SDK -->
<!-- DJI SDK -->

<activity
android:name=".UI.StartActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:launchMode="standard"
android:theme="@style/WelcomeTheme">

<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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>
</application>


3、注册帮助类,从4.4之后
在Applicatiom中加入如下代码:

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
Helper.install(YourApplication.this);//引入大疆帮助类
}

4、MainActivity连接飞机

FlightController mFlightController = null;
FlightController.OnboardSDKDeviceDataCallback receiveCallback;
private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);
private DJISDKManager.SDKManagerCallback registrationCallback = new DJISDKManager.SDKManagerCallback() {

@Override
public void onRegister(DJIError error) {
isRegistrationInProgress.set(false);
if (error == DJISDKError.REGISTRATION_SUCCESS) {
DJISDKManager.getInstance().setCallbackRunInUIThread(true);
DJISDKManager.getInstance().startConnectionToProduct();
//Toast.makeText(getApplicationContext(), "SDK registration succeeded!", Toast.LENGTH_LONG).show();
myHandler.sendEmptyMessage(3);//检查登陆
} else {

Toast.makeText(getApplicationContext(),
//"SDK registration failed, check network and retry!",
"DJI SDK 注册失败, 请检查网络后重试!",
Toast.LENGTH_LONG).show();
}
}

@Override
public void onProductChange(BaseProduct baseProduct, BaseProduct baseProduct1) {
Log.v(TAG, String.format("onProductChanged oldProduct:%s, newProduct:%s", baseProduct, baseProduct1));
mProduct = baseProduct1;
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);
}
Log.v(TAG, String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s", key, oldComponent, newComponent));

notifyStatusChange();
}

@Override
public void onConnectivityChange(boolean b) {
Log.v(TAG, "onProductConnectivityChanged: " + b);
notifyStatusChange();
}
};

private BaseComponent.ComponentListener mDJIComponentListener = new BaseComponent.ComponentListener() {

@Override
public void onConnectivityChange(boolean b) {
notifyStatusChange();
}

};

private void notifyStatusChange() {
myHandler.sendEmptyMessage(2);
}

};
private static final String[] REQUIRED_PERMISSION_LIST = new String[]{
Manifest.permission.VIBRATE,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.WAKE_LOCK,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
};
private static final int REQUEST_PERMISSION_CODE = 12345;
private List<String> missingPermission = new ArrayList<>();

/**
* 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);
}
}

/**
* 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();
}
}

private void startSDKRegistration() {
if (isRegistrationInProgress.compareAndSet(false, true)) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
DJISDKManager.getInstance()
.registerApp(MainActivity.this, registrationCallback);
}
});
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkAndRequestPermissions();
}

private void refreshSDKRelativeUI() {//此方法sendEmptyMessege 2的调用
mProduct = SearchApplication.getProductInstance();
if (null != mProduct && mProduct.isConnected()) {
if (mFlightController == null) {
Aircraft mAircraft1 = (Aircraft) DJISDKManager.getInstance().getProduct();
if (mAircraft1 != null)
mFlightController = mAircraft1.getFlightController();//获取飞控类
}
if (mFlightController != null) {
if (mFlightController.isOnboardSDKDeviceAvailable() && bFirst && actimer == null)//检查板载SDK
}
imgproduct.setImageResource(R.mipmap.v2_m600_pro_connect_icon);
String str = mProduct instanceof Aircraft ? "DJIAircraft" : "DJIHandHeld";
mTextConnectionStatus.setText("状态: " + str + " 连接成功");
if (null != mProduct.getModel()) {
mTextProduct.setText("" + mProduct.getModel().getDisplayName());
} else {
mTextProduct.setText(R.string.product_information);
}

if (receiveCallback == null) {
receiveCallback = new FlightController.OnboardSDKDeviceDataCallback() {//板载SDK回复的数据,如果要用到的话
@Override
public void onReceive(byte[] bytes) {

}
};
mFlightController.setOnboardSDKDeviceDataCallback(receiveCallback);
}
}
}


5、高版本SDK必须要登录帐号,下面是检查登录和登录操作

private void loginAccount() {//检查登录

UserAccountState userAccountState = UserAccountManager.getInstance().getUserAccountState();
//如果用户 NOT_LOGGED_IN TOKEN_OUT_OF_DATE INVALID_TOKEN UNKNOWN 则弹出对话框重新登陆
if (userAccountState == UserAccountState.NOT_LOGGED_IN ||
userAccountState == UserAccountState.TOKEN_OUT_OF_DATE ||
userAccountState == UserAccountState.INVALID_TOKEN ||
userAccountState == UserAccountState.UNKNOWN) {
login();
} else {//否则显示用户名
UserAccountManager.getInstance().getLoggedInDJIUserAccountName(new CommonCallbacks.CompletionCallbackWith<String>() {
@Override
public void onSuccess(String s) {
csUser = s;
myHandler.sendEmptyMessage(0);
}

@Override
public void onFailure(DJIError djiError) {
login();
}
});
}
}
private void login() {
if (UserAccountManager.getInstance() == null)
return;
UserAccountManager.getInstance().logIntoDJIUserAccount(MainActivity.this,
new CommonCallbacks.CompletionCallbackWith<UserAccountState>() {
@Override
public void onSuccess(final UserAccountState userAccountState) {
if (userAccountState == UserAccountState.NOT_AUTHORIZED ||
userAccountState == UserAccountState.AUTHORIZED) {
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_LONG).show();
UserAccountManager.getInstance().getLoggedInDJIUserAccountName(new CommonCallbacks.CompletionCallbackWith<String>() {
@Override
public void onSuccess(String s) {
csUser = s;
myHandler.sendEmptyMessage(0);
}

@Override
public void onFailure(DJIError djiError) {

}
});
}
}

@Override
public void onFailure(DJIError error) {
Toast.makeText(MainActivity.this, "登陆错误:" + error.getDescription(), Toast.LENGTH_LONG).show();
}
});
}


6、可以FlightController 获取飞控信息,或者直接用UI库里面的控件会自动刷新飞行器信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: