本文共 36635 字,大约阅读时间需要 122 分钟。
先看效果图吧:
1.大疆无人机官方文档地址:,我们做这个无人机开发1,需要先去大疆官网看文档,然后申请一个大疆账号,然后去申请appkey,注意这个appkey很重要。不申请的无法运行
2.配置环境,添加依赖,在app下面的builder.gradle
apply plugin: 'com.android.application'android { compileSdkVersion 28 buildToolsVersion "28.0.1" defaultConfig { applicationId "com.example.administrator.testz" minSdkVersion 19 targetSdkVersion 28 versionCode 1 versionName "1.0" multiDexEnabled true testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk { abiFilters 'armeabi-v7a' } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } packagingOptions { exclude 'META-INF/rxjava.properties' } 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 { implementation fileTree(dir: 'libs', include: ['*.jar']) androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) implementation 'com.android.support:appcompat-v7:26.0.0-alpha1' testImplementation 'junit:junit:4.12' //====dividing implementation 'com.android.support:multidex:1.0.1' // dividing implementation 'com.dji:dji-sdk:4.8.1' implementation 'com.dji:dji-uxsdk:4.8.1' compileOnly 'com.dji:dji-sdk-provided:4.8.1'}
2.清单文件,注意清单文件我写注释的地方,那个很重要,还有就是appkey,你们需要自己去注册
3.验证无人机环境
package com.example.administrator.testz;import android.app.Application;import android.content.Context;import com.secneo.sdk.Helper;/** * Created by wrs on 2019/6/4,10:47 * projectName: Testz * packageName: com.example.administrator.testz */public class MApplication extends Application { private FPVDemoApplication fpvDemoApplication; @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); Helper.install(MApplication.this); if (fpvDemoApplication == null) { fpvDemoApplication = new FPVDemoApplication(); fpvDemoApplication.setContext(this); } } @Override public void onCreate() { super.onCreate(); fpvDemoApplication.onCreate(); }}
4.无人机绑定注册
package com.example.administrator.testz;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.battery.Battery;import dji.sdk.camera.Camera;import dji.sdk.products.Aircraft;import dji.sdk.products.HandHeld;import dji.sdk.sdkmanager.DJISDKManager;/** * Created by wrs on 2019/6/4,10:49 * projectName: Testz * packageName: com.example.administrator.testz */public class FPVDemoApplication extends Application { public static final String FLAG_CONNECTION_CHANGE = "fpv_tutorial_connection_change"; private DJISDKManager.SDKManagerCallback mDJISDKManagerCallback; private static BaseProduct mProduct; public Handler mHandler; private Application instance; public void setContext(Application application) { instance = application; } @Override public Context getApplicationContext() { return instance; } public FPVDemoApplication() { } /** * 此函数用于获取DJIBaseProduct的实例。 * 如果没有连接产品,则返回null。 */ public static synchronized BaseProduct getProductInstance() { if (null == mProduct) { mProduct = DJISDKManager.getInstance().getProduct(); } return mProduct; } //电池 public static synchronized Battery getBatteryInstance(){ if (getProductInstance() == null){ return null; } Battery battery = null; BaseProduct productInstance = getProductInstance(); if (productInstance instanceof Aircraft){ battery = ((Aircraft)productInstance).getBattery(); //手持云台 }else if (productInstance instanceof HandHeld){ } return battery; } //相机 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; } @Override public void onCreate() { super.onCreate(); mHandler = new Handler(Looper.getMainLooper()); /** * 启动SDK服务时,将使用接口DJISDKManager.DJISDKManagerCallback的实例进行监听 SDK注册结果和产品更改。 */ mDJISDKManagerCallback = new DJISDKManager.SDKManagerCallback() { //Listens to the SDK registration result @Override public void onRegister(DJIError djiError) { if (djiError== 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", djiError.toString()); } @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(new BaseComponent.ComponentListener() { @Override public void onConnectivityChange(boolean isConnected) { Log.d("TAG", "onComponentConnectivityChanged: " + isConnected); notifyStatusChange(); } }); } Log.d("TAG", String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s", componentKey, oldComponent, newComponent)); } }; //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); } };}
5.动态权限申请,广播注册
package com.example.administrator.testz;import android.Manifest;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.pm.PackageManager;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.widget.Button;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicBoolean;import dji.common.error.DJIError;import dji.common.error.DJISDKError;import dji.log.DJILog;import dji.sdk.base.BaseComponent;import dji.sdk.base.BaseProduct;import dji.sdk.products.Aircraft;import dji.sdk.sdkmanager.DJISDKManager;/** * Created by wrs on 2019/6/4,10:46 * projectName: Testz * packageName: com.example.administrator.testz */public class ConnectionActivity extends Activity implements View.OnClickListener { private static final String TAG = ConnectionActivity.class.getName(); private TextView mTextConnectionStatus; private TextView mTextProduct; private TextView mVersionTv; private Button mBtnOpen; 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 ListmissingPermission = new ArrayList<>(); private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false); private static final int REQUEST_PERMISSION_CODE = 12345; private Boolean isConnected = false; //true表示已连接 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkAndRequestPermissions(); setContentView(R.layout.activity_connection); initUI(); //广播接收器 IntentFilter filter = new IntentFilter(); filter.addAction(FPVDemoApplication.FLAG_CONNECTION_CHANGE); registerReceiver(mReceiver, filter); } //动态权限申请 private void checkAndRequestPermissions() { 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); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); 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 (missingPermission.isEmpty()) { startSDKRegistration(); } else { showToast("Missing permissions!"); } } 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(); showToast("Register Success"); } else { showToast("Register sdk fails,check network is available"); } Log.e(TAG, djiError.getDescription()); } @Override public void onProductDisconnect() { Log.e(TAG, "onProductDisconnect"); showToast("Produce DisConnected"); } @Override public void onProductConnect(BaseProduct baseProduct) { Log.e(TAG, String.format("onProductConnect newProduce:%s", baseProduct)); showToast("Produce Connected"); } @Override public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent, BaseComponent newComponent) { if (newComponent != null) { newComponent.setComponentListener(new BaseComponent.ComponentListener() { @Override public void onConnectivityChange(boolean isConnected) { Log.d(TAG, "onComponentConnectivityChanged: " + isConnected); } }); } Log.d(TAG, String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s", componentKey, oldComponent, newComponent)); } }); } }); } } private void showToast(final String toastMsg) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "" + toastMsg, Toast.LENGTH_LONG).show(); } }); } private void initUI() { mTextConnectionStatus = (TextView) findViewById(R.id.text_connection_status); mTextProduct = (TextView) findViewById(R.id.text_product_info); mBtnOpen = (Button) findViewById(R.id.btn_open); mBtnOpen.setOnClickListener(this); mBtnOpen.setEnabled(false); mVersionTv = (TextView) findViewById(R.id.textView2); mVersionTv.setText(getResources().getString(R.string.sdk_version, DJISDKManager.getInstance().getSDKVersion())); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_open: Intent intent = new Intent(ConnectionActivity.this, MainActivity.class); startActivity(intent); break; } } protected BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //广播 refreshSDKRelativeUI(); } }; private void refreshSDKRelativeUI() { BaseProduct mProduct = FPVDemoApplication.getProductInstance(); // mProduct.isConnected() true表示已连接 false 表示未连接 if (null != mProduct && mProduct.isConnected()) { // FileUtil.CONNECT = true; // OttoBus.getInstance().post(new BusData(mProduct.isConnected())); Intent intent = new Intent(ConnectionActivity.this, MainActivity.class); startActivity(intent); } else { showToast("无人机绑定失败"); } } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); }}
6.ConnectionActivity布局
7.拍照
package com.example.administrator.testz;import android.app.Activity;import android.content.Intent;import android.graphics.SurfaceTexture;import android.os.Handler;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.TextureView;import android.view.View;import android.widget.Button;import android.widget.CompoundButton;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import android.widget.ToggleButton;import dji.common.camera.SettingsDefinitions;import dji.common.camera.SystemState;import dji.common.error.DJIError;import dji.common.product.Model;import dji.common.useraccount.UserAccountState;import dji.common.util.CommonCallbacks;import dji.log.IFileFormat;import dji.sdk.base.BaseProduct;import dji.sdk.camera.Camera;import dji.sdk.camera.VideoFeeder;import dji.sdk.codec.DJICodecManager;import dji.sdk.useraccount.UserAccountManager;public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, View.OnClickListener { private static final String TAG = MainActivity.class.getName(); protected VideoFeeder.VideoDataListener mReceivedVideoDataListener = null; protected DJICodecManager mCodecManager = null; protected TextureView mVideoSurface = null; private Button mCaptureBtn, mShootPhotoModeBtn, mRecordVideoModeBtn,btn_battery; private ToggleButton mRecordBtn; private TextView recordingTime; private ImageView iv_connected; private Handler handler; //otto同样需要注册和取消注册、订阅事件 private boolean isConnect; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler = new Handler(); initUI(); //用于接收摄像机实时视图的原始H264视频数据的回调 mReceivedVideoDataListener = new VideoFeeder.VideoDataListener() { @Override public void onReceive(byte[] videoBuffer, int size) { if (mCodecManager != null) { mCodecManager.sendDataToDecoder(videoBuffer, size); } } }; final Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { camera.setSystemStateCallback(new SystemState.Callback() { @Override public void onUpdate(@NonNull SystemState cameraSystemState) { if (null != cameraSystemState) { final int recordTime = cameraSystemState.getCurrentVideoRecordingTimeInSeconds(); int minutes = (recordTime % 3600) / 60; int seconds = recordTime % 60; final String timeString = String.format("%02d:%02d", minutes, seconds); final boolean isVideorecording = cameraSystemState.isRecording(); MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { recordingTime.setText(timeString); if (isVideorecording) { recordingTime.setVisibility(View.VISIBLE); } else { recordingTime.setVisibility(View.INVISIBLE); } } }); } } }); } } protected void onProductChange() { initPreviewer(); loginAccount(); } private void loginAccount() { UserAccountManager.getInstance().logIntoDJIUserAccount(this, new CommonCallbacks.CompletionCallbackWith() { @Override public void onSuccess(UserAccountState userAccountState) { Log.e(TAG, "Login success"); } @Override public void onFailure(DJIError djiError) { showToast("Login Error" + djiError.getDescription()); } }); } @Override protected void onResume() { super.onResume(); initPreviewer(); onProductChange(); if (mVideoSurface == null) { Log.e(TAG, "mVideosurface is nnull"); } } @Override protected void onPause() { super.onPause(); uninitPreviewer(); } @Override protected void onStop() { super.onStop(); } public void onReturn(View view) { this.finish(); } @Override protected void onDestroy() { super.onDestroy(); uninitPreviewer(); } private void initUI() { mVideoSurface = (TextureView) findViewById(R.id.video_previewer_surface); iv_connected = (ImageView) findViewById(R.id.iv_connected); recordingTime = (TextView) findViewById(R.id.timer); mCaptureBtn = (Button) findViewById(R.id.btn_capture); btn_battery = (Button) findViewById(R.id.btn_battery); mRecordBtn = (ToggleButton) findViewById(R.id.btn_record); mShootPhotoModeBtn = (Button) findViewById(R.id.btn_shoot_photo_mode); mRecordVideoModeBtn = (Button) findViewById(R.id.btn_record_video_mode); if (null != mVideoSurface) { mVideoSurface.setSurfaceTextureListener(this); } mCaptureBtn.setOnClickListener(this); mRecordBtn.setOnClickListener(this); mShootPhotoModeBtn.setOnClickListener(this); mRecordVideoModeBtn.setOnClickListener(this); recordingTime.setVisibility(View.INVISIBLE); mRecordBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { startRecord(); } else { stopRecord(); } } }); btn_battery.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,BattryActivity.class); startActivity(intent); } }); } private void initPreviewer() { BaseProduct product = FPVDemoApplication.getProductInstance(); if (product == null || !product.isConnected()) { showToast(getString(R.string.disconnected)); } else { if (null != mVideoSurface) { mVideoSurface.setSurfaceTextureListener(this); } if (!product.getModel().equals(Model.UNKNOWN_AIRCRAFT)) { VideoFeeder.getInstance().getPrimaryVideoFeed().addVideoDataListener(mReceivedVideoDataListener); } } } private void uninitPreviewer() { Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { VideoFeeder.getInstance().getPrimaryVideoFeed().addVideoDataListener(null); } } public void showToast(final String msg) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); } }); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { if (mCodecManager == null) { mCodecManager = new DJICodecManager(this, surface, width, height); } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { if (mCodecManager != null) { mCodecManager.cleanSurface(); mCodecManager = null; } return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_capture: { captureAction(); break; } case R.id.btn_shoot_photo_mode: { switchCameraMode(SettingsDefinitions.CameraMode.SHOOT_PHOTO); break; } case R.id.btn_record_video_mode: { switchCameraMode(SettingsDefinitions.CameraMode.RECORD_VIDEO); break; } default: break; } } private void switchCameraMode(SettingsDefinitions.CameraMode cameraMode) { Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { camera.setMode(cameraMode, new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (djiError == null) { showToast("Switch Camera Mode Succeeded"); } else { showToast(djiError.getDescription()); } } }); } } private void captureAction() { final Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { SettingsDefinitions.ShootPhotoMode photoMode = SettingsDefinitions.ShootPhotoMode.SINGLE; camera.setShootPhotoMode(photoMode, new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (null == djiError) { handler.postDelayed(new Runnable() { @Override public void run() { //延时2s执行 camera.startShootPhoto(new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (djiError == null) { showToast("take photo :success"); } else { showToast(djiError.getDescription()); } } }); } }, 2000); } } }); } } private void startRecord() { final Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { camera.startRecordVideo(new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (djiError == null) { showToast("Record video success"); } else { showToast(djiError.getDescription()); } } }); } } private void stopRecord() { Camera camera = FPVDemoApplication.getCameraInstance(); if (camera != null) { camera.stopRecordVideo(new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (djiError == null) { showToast("Stop recording success"); } else { showToast(djiError.getDescription()); } } }); } }}
8.MainActivity布局
9.电池
package com.example.administrator.testz;import android.app.Activity;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import android.widget.Toast;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import dji.common.battery.BatteryState;import dji.common.error.DJIError;import dji.common.util.CommonCallbacks;import dji.sdk.battery.Battery;import dji.sdk.camera.Camera;public class BattryActivity extends AppCompatActivity implements BatteryState.Callback{ /* * view */ private TextView createTimeTv; private TextView createFreTv; private TextView batteryFullChargeCapacityTv; private TextView batteryChargeRemainingTv; private TextView batteryChargeRemainingInPercentTv; private TextView batteryIsBeingChargedTv; private TextView batterySelfHeatingStateTv; private TextView batteryVoltageTv; private TextView batteryCurrentTv; private TextView batteryLifetimeRemainingTv; private TextView batteryTemperatureTv; private TextView batteryNumberOfDischargesTv; private TextView batterySnTv; /* 流程参数 */ private Date createTime = new Date();//当前更新时间 //读取电池信息状态 private Timer timer = new Timer(); private Battery mBattery; private TimerTask task = new TimerTask() { @Override public void run() { BattryActivity.this.mBattery = FPVDemoApplication.getBatteryInstance(); if(mBattery != null){ mBattery.setStateCallback(BattryActivity.this); mBattery.getSerialNumber(new CommonCallbacks.CompletionCallbackWith() { @Override public void onSuccess(final String s) { runOnUiThread(new Runnable() { @Override public void run() { batterySnTv.setText("SN:"+s); } }); } @Override public void onFailure(DJIError djiError) { } }); task.cancel(); timer.cancel(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_showbattery); createFreTv = findViewById(R.id.tv_create_fre); createTimeTv = findViewById(R.id.tv_create_time); batteryFullChargeCapacityTv = findViewById(R.id.bfcctv); batteryChargeRemainingTv = findViewById(R.id.bcrtv); batteryChargeRemainingInPercentTv = findViewById(R.id.bcriptv); batteryIsBeingChargedTv = findViewById(R.id.bibctv); batterySelfHeatingStateTv = findViewById(R.id.bshstv); batteryVoltageTv = findViewById(R.id.bvtv); batteryCurrentTv = findViewById(R.id.bctv); batteryLifetimeRemainingTv = findViewById(R.id.blrtv); batteryTemperatureTv = findViewById(R.id.bttv); batteryNumberOfDischargesTv = findViewById(R.id.bnodtv); batterySnTv = findViewById(R.id.tv_sn); //获取时间 timer.schedule(task,100,1000); } @Override public void onUpdate(final BatteryState batteryState) { if(batteryState == null){ return; } runOnUiThread(new Runnable() { @Override public void run() { //刷新当前更新时间 Date nowDate= new Date(); createTimeTv.setText("更新时间: "+ android.text.format.DateFormat.format("yyyy年MM月dd日,kk:mm:ss",nowDate)); long fre = nowDate.getTime() - createTime.getTime(); createFreTv.setText("刷新频率:"+(fre/1000)+"s/次"); createTime = nowDate; //更新状态 try { //总能量 batteryFullChargeCapacityTv.setText("总电量:"+batteryState.getFullChargeCapacity()+" mAh"); //剩余能量 batteryChargeRemainingTv.setText("剩余电量:"+batteryState.getChargeRemaining()+" mAh"); //剩余电量百分比 batteryChargeRemainingInPercentTv.setText("剩余电量百分比:"+batteryState.getChargeRemainingInPercent()+" %"); //是否正在充电 batteryIsBeingChargedTv.setText("是否正在充电:"+(batteryState.isBeingCharged()?"是":"否")); //自发热状态 if (batteryState.getSelfHeatingState() != null) { batterySelfHeatingStateTv.setText("自发热状态:"+batteryState.getSelfHeatingState().value()); } //电压 batteryVoltageTv.setText("当前电压:"+batteryState.getVoltage()+" mV"); //当前状态 batteryCurrentTv.setText("当前状态:"+(batteryState.getCurrent() >0?"正在充电":"正在放电")); //剩余寿命 batteryLifetimeRemainingTv.setText("剩余寿命:"+batteryState.getLifetimeRemaining()+"%"); //电池温度 batteryTemperatureTv.setText("电池温度:"+batteryState.getTemperature()+" ℃"); //总放电次数 batteryNumberOfDischargesTv.setText("总放电次数:"+batteryState.getNumberOfDischarges()); }catch (Exception e){ Toast.makeText(BattryActivity.this,e.getMessage(),Toast.LENGTH_LONG).show(); } } }); } }
10.电池布局
写到这里结束了,这里只是两个简单的使用,大疆无人机的官方demo更加的详细,大家可以参考官方的程序,我这个程序是精简化的代码,但是看起来稍微简化了一些,详细的还是建议看官方的代码,
遇到的坑!:
1.appkey没注册
2.清单文件,有一个intent广播意图是用于启动应用界面的,官方的那个activity什么都没有,你必须修改一下,不然就点击什么反应都没有,无法启动
3.连接状态,包括已连接和未连接,在refreshSDKRelativeUI里面,我想把这个状态弄出来,死活不行,大家如果想要这个状态,可以把这个activity作为主Activity,然后其他界面用fragment的方式进行,本例子没做这个功能,
4.拍照的时候,必须插入SD卡,不然无法返回scuess ,就是拍照失败的意思,然后,插入SD卡后,本例子必须设置一下拍照的模式,才可以成功,但是官方demo可以直接拍照,。这一点以后有机会研究一下,这个地方还没有优化,
5.有了sd卡,并且拍照成功后,其实在SD里面就已经存储了照片,在/根目录/DCIM/100MEDIA 这个目录里面
其他的 也没啥了 把这些代码复制一下,连上飞机,就可以控制了,但是在没这做这个之前,觉得还是很麻烦的,现在看很简单,最后联系方式qq:2494075190
转载地址:http://jxpdz.baihongyu.com/