博客
关于我
大疆无人机连接拍照和电池
阅读量:478 次
发布时间:2019-03-06

本文共 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 List
missingPermission = 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/

你可能感兴趣的文章
logstash mysql 准实时同步到 elasticsearch
查看>>
Luogu2973:[USACO10HOL]赶小猪
查看>>
mabatis 中出现&lt; 以及&gt; 代表什么意思?
查看>>
Mac book pro打开docker出现The data couldn’t be read because it is missing
查看>>
MAC M1大数据0-1成神篇-25 hadoop高可用搭建
查看>>
mac mysql 进程_Mac平台下启动MySQL到完全终止MySQL----终端八步走
查看>>
Mac OS 12.0.1 如何安装柯美287打印机驱动,刷卡打印
查看>>
MangoDB4.0版本的安装与配置
查看>>
Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
查看>>
mapping文件目录生成修改
查看>>
MapReduce程序依赖的jar包
查看>>
mariadb multi-source replication(mariadb多主复制)
查看>>
MariaDB的简单使用
查看>>
MaterialForm对tab页进行隐藏
查看>>
Member var and Static var.
查看>>
memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
查看>>
memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
查看>>
Memcached:Node.js 高性能缓存解决方案
查看>>
memcache、redis原理对比
查看>>
memset初始化高维数组为-1/0
查看>>