DJI Android SDK 开发笔记(入门篇)

大疆SDK开发笔记##

1.文档相关

2.飞行模拟器下载地址

Mavic 系列模拟器下载地址

Phantom 系列模拟器下载地址

Assistant 系列模拟器下载地址

3.Android SDK

预览大图

4.Android UX SDK

预览大图

5.Android Studio接入DIJ SDK步骤

5.1.app的build.gradle添加

implementation 'com.dji:dji-sdk:4.10'
implementation 'com.dji:dji-uxsdk:4.10'
compileOnly 'com.dji:dji-sdk-provided:4.10'

5.2.app的build.gradle的android中

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"

    pickFirst 'lib/*/libstlport_shared.so'
    pickFirst 'lib/*/libRoadLineRebuildAPI.so'
    pickFirst 'lib/*/libGNaviUtils.so'
    pickFirst 'lib/*/libGNaviMapex.so'
    pickFirst 'lib/*/libGNaviData.so'
    pickFirst 'lib/*/libGNaviMap.so'
    pickFirst 'lib/*/libGNaviSearch.so'
    pickFirst 'lib/*/libDJIFlySafeCore.so'
    pickFirst 'lib/*/libdjifs_jni.so'
    pickFirst 'lib/*/libsfjni.so'
    exclude 'META-INF/rxjava.properties'
}

5.3 AndroidManifest.xml添加权限

<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"
    tools:ignore="ProtectedPermissions" />
<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" />

application里面

<uses-library android:name="com.android.future.usb.accessory" />
    <meta-data
        android:name="com.dji.sdk.API_KEY"
        android:value="9a13028ed03500ad035980f9" />
    <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" />

6.SDK初始化以及接口相关

*注:DJI的相关回调都在子线程里面!请勿在操作UI。

6.1初始化SDK

 DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
                    @Override
                    public void onRegister(DJIError djiError) {
                        //子线程的回调
                        if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
                            //SDK 注册成功  启动连接到飞机
                            DJISDKManager.getInstance().startConnectionToProduct();
                        } else {
                            //SDK 注册失败 需要在子线程操作UI
                        }
                        Log.v(TAG, djiError.getDescription());
                    }

                    @Override
                    public void onProductDisconnect() {
                        Log.d(TAG, "onProductDisconnect");
                        notifyStatusChange();
                    }

                    @Override
                    public void onProductConnect(BaseProduct baseProduct) {
                        Log.d(TAG, String.format("onProductConnect newProduct:%s", baseProduct));
                        notifyStatusChange();
                    }

                    @Override
                    public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent,
                                                  BaseComponent newComponent) {
                        //DJI SDK 连接发生改变
                        if (newComponent != null) {
                            newComponent.setComponentListener(new BaseComponent.ComponentListener() {

                                @Override
                                public void onConnectivityChange(boolean isConnected) {
                                    Log.d(TAG, "onComponentConnectivityChanged: " + isConnected);
                                  //DJI SDK 连接发生改变
                                    notifyStatusChange();
                                }
                            });
                        }
                        Log.d(TAG, String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s",
                                componentKey,
                                oldComponent,
                                newComponent));
                    }
                    @Override
                    public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {
                    }
                });

private void notifyStatusChange() {
    if (mHandler == null) {
        mHandler = new Handler(getMainLooper());
    }
    mHandler.removeCallbacks(updateRunnable);
    mHandler.postDelayed(updateRunnable, 500);
}

6.2登录DJI账号

private void DJIUserLogin() {
    UserAccountManager.getInstance().logIntoDJIUserAccount(MainActivity.this, new CommonCallbacks.CompletionCallbackWith<UserAccountState>() {
        @Override
        public void onSuccess(final UserAccountState userAccountState) {
        //登录成功的回调 子线程回调
        }
        @Override
        public void onFailure(final DJIError djiError) {
        //登录失败的错误回调
        }
    });
}

6.3获取登录DJI账号相关的信息

private void getDjiLoginUserName() {
    UserAccountManager.getInstance().getLoggedInDJIUserAccountName(new CommonCallbacks.CompletionCallbackWith<String>() {
        @Override
        public void onSuccess(final String s) {
           //s为登录的用户名
        }

        @Override
        public void onFailure(final DJIError djiError) {
             //获取失败 错误详情请查看djierror类
        }
    });
}

*注:完成以上的注册SDK、和登录用户名后,就能进入到正式DJI SDK开发了。

6.4 XML布局文件

<dji.ux.widget.FPVWidget
        android:id="@+id/fpvwidget"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        custom:sourceCameraNameVisibility="false" />

<dji.ux.widget.FPVOverlayWidget
        android:id="@+id/fPVOverlayWidget"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
  • dji.ux.widget.FPVWidget

    这个控件用户显示飞控的相机的画面,DJI已经绑定,直接用即可。

    custom:sourceCameraNameVisibility="false"

    此属性用设置 画面中间不显示视频来源的名称。
  • <dji.ux.widget.FPVOverlayWidget

    这个控件用于在画面中操作相机的移动等。

6.5获取无人机的飞行状态

*注:只有在SDK与与无人机连接成功,并且飞行的时候 才能有相应的高度经纬度信息。

//设置监听
MApplication.getAircraftInstance().getFlightController().setStateCallback(new FlightControllerState.Callback() {
        @Override
        public void onUpdate(@NonNull final FlightControllerState flightControllerState) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    OnUpdateDJIView(flightControllerState);
                }
            });
        }
    });


private void OnUpdateDJIView(FlightControllerState flightControllerState) {
    LocationCoordinate3D locationCoordinate3D = flightControllerState.getAircraftLocation();//飞机的3D位置
    if (locationCoordinate3D == null) {
        printLOG("locationCoordinate3D==null");
        return;
    }
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append("经度:" + locationCoordinate3D.getLongitude()).append("\n");
    stringBuffer.append("纬度:" + locationCoordinate3D.getLatitude()).append("\n");
    stringBuffer.append("高度:" + locationCoordinate3D.getAltitude()).append(" m\n");
    //tv_feiji_infos.setText(stringBuffer.toString());
}

未完待续..

posted @ 2019-07-17 12:26  蒋团圆  阅读(3100)  评论(0编辑  收藏  举报