DJI Android SDK 开发笔记

大疆SDK开发笔记

1.文档相关

2.飞行模拟器下载地址

Mavic 系列模拟器下载地址

Phantom 系列模拟器下载地址

Assistant 系列模拟器下载地址

3.Android SDK

DJI Android SDK 开发笔记

预览大图

4.Android UX SDK

DJI Android 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());
}

未完待续..

DJI Android SDK 开发笔记

上一篇:ubuntu使用scrcpy手机投屏-免费神器scrcpy【介绍、安装、使用】


下一篇:Date() 及其 如何验证用户输入的日期是合法的