Dajiang UAV Android Mobile Sdk Development (a) brief
Dajiang UAV Android Mobile Sdk Development (iii) the development of waypoints task WaypointMission
qq505057618
I mainly said core part, first of all suggest that you first download an official mobile sdk run the Demo to see, study and then to try to develop their own research.
Develop, then you need to register a Dajiang developer account, and then register an application based on official assignment mobilesdk will give you a App Key
AndroidMnifest then you need to fill this key, the key is the name of your bag and bound, in addition to declare
<uses-feature android:name="android.hardware.usb.host" android:required="false"/>
<uses-feature android:name="android.hardware.usb.accessory" android:required="true"/>
Also note that your main activity of <intent-filter> Formulation, USB_ACCESSORY_ATTACHED do not understand can go to google it, mainly to ensure communication between Andrews and peripherals, here, is to ensure that your remote drone Andrews and can be provided on the connector.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dji.sdk.sample">
<!-- SDK permission requirement -->
<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.RECORD_AUDIO"/>
<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-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=".internal.controller.DJISampleApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/sample_app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
ADD API_KEY HERE and make sure you
are connected to the Internet before
the app is launched
-->
<meta-data
android:name="com.dji.sdk.API_KEY"
android:value="Please enter your App Key here."/>
<!-- Required for receiving accessory attachment events.
This is necessary for product when connecting over USB. -->
<activity
android:name="com.dji.sdk.sample.internal.controller.MainActivity"
android:label="@string/sample_app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/AppTheme">
<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>
</manifest>
Then gradle file, you need to add a large dependence on Xinjiang
dependencies {
implementation 'com.android.support:multidex:1.0.2'
implementation 'com.squareup:otto:1.3.8'
implementation ('com.dji:dji-sdk:4.10', {
// Uncomment the following line if your app does not need Anti Distortion for
// Mavic 2 Pro and Mavic 2 Zoom. It will greatly reducing the size of the APK:
exclude module: 'library-anti-distortion'
// Uncomment the following line if your APP does not need network RTK
exclude module: 'library-networkrtk-helper'
})
compileOnly 'com.dji:dji-sdk-provided:4.10'
}
Analysis of the main activity code analysis below, posted only the core code. First you have to apply for permission specified, then called after permission allows registerApp way to register the application after receiving the callback successful registration, call the DJISDKManager.getInstance (). StartConnectionToProduct () to connect the drone, the connection is successful will go onProductConnect to the callback function, this time you can get the information you want the drone.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
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,
Manifest.permission.RECORD_AUDIO
};
private static final int REQUEST_PERMISSION_CODE = 12345;
private FrameLayout contentFrameLayout;
private Stack<ViewWrapper> stack;
private TextView titleTextView;
private List<String> missingPermission = new ArrayList<>();
private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);
private BaseComponent.ComponentListener mDJIComponentListener = new BaseComponent.ComponentListener() {
@Override
public void onConnectivityChange(boolean isConnected) {
Log.d(TAG, "onComponentConnectivityChanged: " + isConnected);
notifyStatusChange();
}
};
//region Life-cycle
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkAndRequestPermissions();
DJISampleApplication.getEventBus().register(this);
setContentView(R.layout.activity_main);
}
/**
* 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();
}
}
@Override
protected void onDestroy() {
DJISampleApplication.getEventBus().unregister(this);
super.onDestroy();
}
@Override
protected void onNewIntent(@NonNull Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
Intent attachedIntent = new Intent();
attachedIntent.setAction(DJISDKManager.USB_ACCESSORY_ATTACHED);
sendBroadcast(attachedIntent);
}
}
//region Registration n' Permissions Helpers
/**
* 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);
}
}
private void startSDKRegistration() {
if (isRegistrationInProgress.compareAndSet(false, true)) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_doing_message));
DJISDKManager.getInstance().registerApp(MainActivity.this.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();
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_success_message));
} else {
ToastUtils.setResultToToast(MainActivity.this.getString(R.string.sdk_registration_message) + djiError.getDescription());
}
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) {
if (newComponent != null) {
newComponent.setComponentListener(mDJIComponentListener);
}
Log.d(TAG,
String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s",
componentKey,
oldComponent,
newComponent));
notifyStatusChange();
}
@Override
public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {
}
});
}
});
}
}
private void notifyStatusChange() {
DJISampleApplication.getEventBus().post(new ConnectivityChangeEvent());
}
//endregion
private void refreshTitle() {
if (stack.size() > 1) {
ViewWrapper wrapper = stack.peek();
titleTextView.setText(wrapper.getTitleId());
} else if (stack.size() == 1) {
BaseProduct product = DJISampleApplication.getProductInstance();
if (product != null && product.getModel() != null) {
titleTextView.setText("" + product.getModel().getDisplayName());
} else {
titleTextView.setText(R.string.sample_app_name);
}
}
}
@Subscribe
public void onConnectivityChange(ConnectivityChangeEvent event) {
runOnUiThread(new Runnable() {
@Override
public void run() {
refreshTitle();
}
});
}
}