大疆无人机二次开发简介-引入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如下
2、AndroidManifest配置
3、注册帮助类,从4.4之后
在Applicatiom中加入如下代码:
4、MainActivity连接飞机
5、高版本SDK必须要登录帐号,下面是检查登录和登录操作
6、可以FlightController 获取飞控信息,或者直接用UI库里面的控件会自动刷新飞行器信息
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库里面的控件会自动刷新飞行器信息
相关文章推荐
- 大疆无人机二次开发进阶-DJI mobile SDK和DJI onboard SDK联合开发行业应用项目
- App开发日报 2015-05-15 大疆无人机IOS开发之搭建DJI Phantom和iOS视觉平台
- 大疆无人机二次开发之百度离线地图下载
- Android DJI Mobile-SDK 开发
- ArcSDE SDK For Java二次开发介绍、演示样例
- java微信开发引入jssdk一直报invalid url domain错的其他原因
- 无人机地面站二次开发、深度开发
- 基于VLC SDK的二次开发
- Android NDK开发简介 NDK和SDK以及JNI有什么关系?
- 大疆无人机 Android 开发总结——视频解码
- 使用C#调用PI-SDK进行基于PI的开发(一)——PI-SDK简介
- Android NDK开发简介 NDK和SDK以及JNI有什么关系?
- 软件二次开发平台简介
- 工业相机SDK之opencv二次开发
- DJI SDK iOS 开发之二:搭建基本的开发环境
- 海康威视 DVR IPC, IOS系统的SDK包。用于二次开发
- VB6.0环境下的CATIA二次开发简介
- Dji Mobile SDK 基础实现(一)
- TeamTalk消息服务器原理及二次开发简介
- WSS3SDK之:Mobile开发中的省略号与渲染限制