更新到4.4.1后,DJI SDK无法识别RC

时间:2018-02-09 10:46:33

标签: java android dji-sdk

我在过去几天将DJI SDK从4.3.2更新到4.4.1。我正试图让它工作,但它在某种程度上无法识别我何时连接无人机的遥控器。 使用的硬件/软件:
智能手机: Google Pixel XL
智能手机操作系统: Android 8.1.0
无人机:DJI Phantom 4 Pro
DJI SDK: 4.4.1
请注意,我不需要使用API​​级别> = 26,因为其他依赖项,我不能低于此。

  

的build.gradle

apply plugin: 'com.android.application'

repositories {
    maven { url 'https://maven.google.com' }
}

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        applicationId "com.test.droneapp"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 9
        versionName "1.0"
        //Enabling multidex support
        multiDexEnabled true
        vectorDrawables.useSupportLibrary = true
        useLibrary  'org.apache.http.legacy'

        ndk {
            abiFilters 'armeabi-v7a', 'x86', 'arm64-v8a'
        }
    }

    lintOptions {
        disable 'MissingTranslation'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dexOptions {
        preDexLibraries = false
        javaMaxHeapSize "4g"
    }

    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"
    }
}

repositories {
    flatDir {
        dirs 'libs'
    }
    google()
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')

    // Support Library
    compile "com.android.support:support-v4:26.1.0"
    compile "com.android.support:recyclerview-v7:26.1.0"
    compile "com.android.support:appcompat-v7:26.1.0"
    compile "com.android.support:design:26.1.0"

    // Google Play Services
    compile "com.google.android.gms:play-services-maps:11.6.2"
    compile "com.google.android.gms:play-services-auth:11.6.2"
    compile "com.google.android.gms:play-services-gcm:11.6.2"
    compile "com.google.android.gms:play-services-location:11.6.2"

    // MultiDex
    compile 'com.android.support:multidex:1.0.1'

    // DJI SDK
//    compile ('com.dji:dji-sdk:4.3.2')
    compile 'com.dji:dji-sdk:4.4.1'
    provided 'com.dji:dji-sdk-provided:4.4.1'
}
  

LauncherApplication.java

package com.test.droneapp;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.support.multidex.MultiDex;

import com.crashlytics.android.Crashlytics;
import com.secneo.sdk.Helper;

import java.io.File;

import io.fabric.sdk.android.Fabric;

public class LauncherApplication extends Application {
private DJIApplication mDJIApplication;

@Override
protected void attachBaseContext(Context paramContext) {
    super.attachBaseContext(paramContext);
    MultiDex.install(this);
    Helper.install(this);

    if (mDJIApplication == null) {
        mDJIApplication = new DJIApplication();
        mDJIApplication.setContext(this);
    }
}

@Override
public void onCreate() {
    super.onCreate();
    mDJIApplication.onCreate();

    // Initialize Fabric
    Fabric.with(this, new Crashlytics());
}
}
  

DJIApplication.java

package com.test.droneapp;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.ContextCompat;
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.camera.Camera;
import dji.sdk.products.Aircraft;
import dji.sdk.products.HandHeld;
import dji.sdk.sdkmanager.DJISDKManager;

public class DJIApplication extends Application {

private static final String TAG = "DroneApp";

public static final String FLAG_CONNECTION_CHANGE = "dji_sdk_connection_change";

private DJISDKManager.SDKManagerCallback mDJISDKManagerCallback;
private BaseProduct.BaseProductListener mDJIBaseProductListener;
private BaseComponent.ComponentListener mDJIComponentListener;
private static BaseProduct mProduct;
public Handler mHandler;

private Application instance;

public void setContext(Application application) {
    instance = application;
}

@Override
public Context getApplicationContext() {
    return instance;
}

public DJIApplication() {

}

public static synchronized BaseProduct getProductInstance() {
    if (null == mProduct) {
        mProduct = DJISDKManager.getInstance().getProduct();
    }
    return mProduct;
}

public static synchronized Aircraft getAircraftInstance() {
    if (!isAircraftConnected()) return null;
    return (Aircraft) getProductInstance();
}

public static synchronized Camera getCameraInstance() {

    if (getProductInstance() == null) return null;

    Camera camera = null;

    if (getProductInstance() instanceof Aircraft) {
        camera = ((Aircraft) getProductInstance()).getCamera();

    } else if (getProductInstance() instanceof HandHeld) {
        camera = ((HandHeld) getProductInstance()).getCamera();
    }

    return camera;
}

public static boolean isAircraftConnected() {
    return getProductInstance() != null && getProductInstance() instanceof Aircraft;
}

public static boolean isProductModuleAvailable() {
    return (null != DJIApplication.getProductInstance());
}

public static boolean isCameraModuleAvailable() {
    return isProductModuleAvailable() &&
            (null != DJIApplication.getProductInstance().getCamera());
}

public static boolean isPlaybackAvailable() {
    return isCameraModuleAvailable() &&
            (null != DJIApplication.getProductInstance().getCamera().getPlaybackManager());
}

@Override
public void onCreate() {
    super.onCreate();
    mHandler = new Handler(Looper.getMainLooper());
    mDJIComponentListener = new BaseComponent.ComponentListener() {

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

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

    };

    /**
     * When starting SDK services, an instance of interface DJISDKManager.DJISDKManagerCallback will be used to listen to
     * the SDK Registration result and the product changing.
     */
    mDJISDKManagerCallback = new DJISDKManager.SDKManagerCallback() {

        //Listens to the SDK registration result
        @Override
        public void onRegister(DJIError error) {
            if (error == DJISDKError.REGISTRATION_SUCCESS) {

                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                            Toast.makeText(getApplicationContext(), "Register Success", Toast.LENGTH_LONG).show();
                    }
                });

                DJISDKManager.getInstance().startConnectionToProduct();

            } else {

                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "Register sdk fails, check network is available", Toast.LENGTH_LONG).show();
                    }
                });

            }
            Log.e("TAG", error.toString());
        }

        //Listens to the connected product changing, including two parts, component changing or product connection changing.
        @Override
        public void onProductChange(BaseProduct oldProduct, BaseProduct newProduct) {

            mProduct = newProduct;
            if (mProduct != null) {
                mProduct.setBaseProductListener(mDJIBaseProductListener);
            }

            notifyStatusChange();
        }
    };
    //Check the permissions before registering the application for android system 6.0 above.
    int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int permissionCheck2 = ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.READ_PHONE_STATE);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (permissionCheck == 0 && permissionCheck2 == 0)) {
        //This is used to start SDK services and initiate SDK.
        DJISDKManager.getInstance().registerApp(getApplicationContext(), mDJISDKManagerCallback);
            Toast.makeText(getApplicationContext(), "registering, pls wait...", Toast.LENGTH_LONG).show();

    } else {
        Toast.makeText(getApplicationContext(), "Please check if the permission is granted.", Toast.LENGTH_LONG).show();
    }
}

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);
        getApplicationContext().sendBroadcast(intent);
    }
};
}
  

ConnectionActivity.java(只是重要部分......)

package com.test.droneapp;

import android.Manifest;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.SimpleColorFilter;
import com.geniusforapp.fancydialog.FancyAlertDialog;
import com.securepreferences.SecurePreferences;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import com.test.droneapp.utils.NetworkUtils;
import com.test.droneapp.utils.SystemUtils;
import com.test.droneapp.utils.UIUtils;
import dji.common.error.DJIError;
import dji.common.error.DJISDKError;
import dji.log.DJILog;
import dji.sdk.base.BaseProduct;
import dji.sdk.sdkmanager.DJISDKManager;

public class ConnectionActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "droneapp";

    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 List<String> missingPermission = new ArrayList<>();
    private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);
    private static final int REQUEST_PERMISSION_CODE = 12345;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        checkAndRequestPermissions();

        setContentView(R.layout.activity_connection);

        initUI();

        // Register the broadcast receiver for receiving the device connection's changes.
        IntentFilter filter = new IntentFilter();
        filter.addAction(DJIApplication.FLAG_CONNECTION_CHANGE);
        registerReceiver(mReceiver, filter);
    }

    @Override
    public void onResume() {
        Log.e(TAG, "onResume");
        super.onResume();
    }

    @Override
    public void onPause() {
        Log.e(TAG, "onPause");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.e(TAG, "onStop");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy");
        unregisterReceiver(mReceiver);
        super.onDestroy();
    }`

    /**
     * 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() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(this,
                    missingPermission.toArray(new String[missingPermission.size()]),
                    REQUEST_PERMISSION_CODE);
        } else {
            startSDKRegistration();
        }
    }

    /**
     * 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 {
            UIUtils.errorSnacky("Missing permissions!!!");
        }
    }

    protected BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            refreshSDKRelativeUI();
        }
    };

    private void startSDKRegistration() {
        if (isRegistrationInProgress.compareAndSet(false, true)) {
            AsyncTask.execute(new Runnable() {
                @Override
                public void run() {
                    showToast( "registering, pls wait...");
                    DJISDKManager.getInstance().registerApp(getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
                        @Override
                        public void onRegister(DJIError djiError) {
                            if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
                                DJILog.e("App registration", DJISDKError.REGISTRATION_SUCCESS.getDescription());
                                DJISDKManager.getInstance().startConnectionToProduct();
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        UIUtils.successSnacky("Register Success");
                                    }
                                });
                            } else {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        UIUtils.errorSnacky( "Register sdk fails, check network is available");
                                    }
                                });
                            }
                            Log.v(TAG, djiError.getDescription());
                        }

                        @Override
                        public void onProductChange(BaseProduct oldProduct, BaseProduct newProduct) {
                            Log.d(TAG, String.format("onProductChanged oldProduct:%s, newProduct:%s", oldProduct, newProduct));
                        }
                    });
                }
            });
        }
    }
}
  

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.test.droneapp">

    <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_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

    <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
        android:name=".LauncherApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:icon">

        <!-- DJI SDK -->
        <uses-library android:name="com.android.future.usb.accessory" />
        <meta-data
            android:name="com.dji.sdk.API_KEY"
            android:value="XXXXXXXXXXXXXXXXXXXXXX" />

        <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>
        <!-- DJI SDK -->

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".ConnectionActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4.3.2一切都运行良好,更新后我跟着DJI网站上的指南,让它工作但我无法弄清楚我做错了什么。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

您可以使用RemoteController

上的以下代码获取Application个对象
   /**
     * This method is used for getting RemoteController instance.
     *
     * @return
     */
    public static synchronized RemoteController getRemoteControllerInstance() {
        if (!isAircraftConnected()) return null;
        return getAircraftInstance().getRemoteController();
    }