|
omqaxwaojye64015955823.gif
5 C: C9 n j3 K# z8 r
点击上方蓝色字体,关注我们& {) I- U, t: C& J
! K( R/ w2 G1 I% @7 ]9 n
上一篇文章(基于Mobile SDK V4版固件开发大疆无人机手机端遥控器(1))因为时间原因介绍了一部分内容,如果已经完成上一篇内容的操作就可以进行下面功能方面的制作了。自己开发的APP功能不是很多,但是已经将大疆无人机的常用功能进行了结合,同大家一起进行学习~+ U! h( D: v1 C/ g3 N4 |( ~
1
8 i6 C; x7 o8 A应用程序激活与绑定
/ U3 D) ~4 f2 ]9 ~ l9 H如果在中国使用DJI飞行器固件,则需要使用该用户的DJI帐户激活控制DJI飞行器的移动应用程序。这将确保大疆能根据飞行器的地理位置和用户个人资料,为飞行器配置正确的地理空间信息和飞行功能集。激活系统的主要是:
/ L* g! y( q: @9 [中国用户必须在每三个月至少登录一次DJI帐户以遍激活应用程序。激活信息将存储在应用程序中,直到用户注销为止。登录DJI帐号需要连接互联网。在中国境外,SDK会自动激活应用程序,无需用户登录。另外,中国用户必须将飞机绑定到DJI官方app中的用户帐户。这仅需要一次。如果未激活应用程序,未绑定飞机(如果需要)或使用旧版SDK(* [8 \* q- e" z8 N( [
4 z% j6 [( _( H2 C1 q
2! ^7 H- m- N$ E: g" L3 r" v
为应用程序创建UI编写MApplication、ReceiverApplication和RegistrationActivity文件(此处粘贴部分代码)。
+ s% x' @/ \# U7 K) a: lpublic class MApplication extends MultiDexApplication {& u9 A7 S4 f8 L/ t3 Y
private ReceiverApplication receiverApplication;1 r( J' S% Q" c+ M* B. H1 A
@Override
5 @' l3 m! p; a1 _( S' h8 z5 @( Z& n* p protected void attachBaseContext(Context paramContext) {2 {' X' ]9 Q* \0 s! v! V. k7 k
super.attachBaseContext(paramContext);3 Q0 Q0 q& c% g
CrashHandler.getInstance().init(this);
( a* |! t H- O% [7 J Helper.install(MApplication.this);
4 n! y2 @% `7 G, j if (receiverApplication == null) {1 L L L1 L3 X$ ?5 t ^6 F: H
receiverApplication = new ReceiverApplication();* z8 [! R1 S0 ]; @8 {$ i6 M
receiverApplication.setContext(this);3 z" {8 y* b( U% `) Z( D7 [% E
}$ s3 B5 T1 F( `0 m+ y2 a' O
}
8 Z" S d: Q) D/ q @Override& z. R4 ?8 n# Q6 c; L4 k4 p
public void onCreate() {9 p- F6 o6 h' P
super.onCreate();
# G- B p2 E% A6 h2 m- y receiverApplication.onCreate();
$ Y8 ^' }( _7 C6 n& ?* B: t }
% P3 k3 B% F$ F1 ~2 q}
" a9 s" @* j8 l/ }6 i7 g$ j K上面的代码实现了绑定当前APP,将后续需要用到的类函数封装到ReceiverApplication 中,在ReceiverApplication 中也能够进行账户登录的操作。5 }! r1 h* g+ q* C! D8 }
public class ReceiverApplication extends MultiDexApplication {* w# F2 W$ [9 @! t6 P: u' F
public static final String FLAG_CONNECTION_CHANGE = "activation_connection_change";; K6 k1 g4 R0 K9 a- M
private static BaseProduct mProduct;
( ?- W( S& L) ^8 j, l1 J public Handler mHandler;4 D& D/ T- q& i
private Application instance;/ H4 g7 o" v& L- f+ T2 X, G R* C. K
public void setContext(Application application) {
; K) O0 |( E7 x/ {/ ?' M instance = application;( h( {. \: {6 d! p6 T
}
3 j8 }/ l' `) S" e9 R! g @Override, i, n; `- t h* T# E- x
protected void attachBaseContext(Context base) {. S$ T/ _8 y1 _5 n3 m/ i
super.attachBaseContext(base);
: z& W. D" W0 i- S% d+ d9 X; [' S Helper.install(this);) t' J' `, C) W
}
$ `2 o/ d$ C" m4 Z2 ] y9 f @Override
" q4 h% B; A; H& T4 } public Context getApplicationContext() {
, e+ V: _4 O% }) Z! T1 X return instance;7 u( Q( P9 W1 `( \4 Y
}
* @6 z5 K% b% Z9 c public ReceiverApplication() {
& N6 D- t9 g3 Z7 x: g }
: G( V6 L3 G) b /**
0 E5 b4 L4 l) V* X" G8 X% e3 j * This function is used to get the instance of DJIBaseProduct.* O& s/ U' Y: ^% e6 \0 w6 l
* If no product is connected, it returns null.1 p7 ]; o# |& {% z6 Y! u/ D
*/
$ t, L7 D% r$ B6 | public static synchronized BaseProduct getProductInstance() {1 n% _7 f, p1 g* S; r( F" q
if (null == mProduct) {9 ^# w, T- e# h
mProduct = DJISDKManager.getInstance().getProduct();
9 X4 X4 D- ~" y" s! O# o }
8 @1 a5 |* _/ D return mProduct;
5 v8 j5 P; G6 Z# v }
2 T$ t1 A6 X8 V7 m! M5 } public static synchronized Aircraft getAircraftInstance() { X$ O+ j# g! u
if (!isAircraftConnected()) return null;' t4 ?2 R( ?3 X/ }/ e# n
return (Aircraft) getProductInstance();
& G l7 c5 ^) H- f6 p s }& x7 O* f: z" V
public static synchronized Camera getCameraInstance() {! ]% B7 J c( B* q$ Q
if (getProductInstance() == null) return null;/ i5 F5 b* w& H
Camera camera = null;: \# M4 q$ l G) `6 C+ |* M% f# c
if (getProductInstance() instanceof Aircraft){) Y) q9 Z/ K. p {% t
camera = ((Aircraft) getProductInstance()).getCamera();/ Q" H) [5 @- t& Y7 B& e6 w
} else if (getProductInstance() instanceof HandHeld) {, E" K* c9 F5 t& d3 e- d
camera = ((HandHeld) getProductInstance()).getCamera();8 R& Z6 ], ~0 c3 ?: i* A7 q
}) N+ B. q/ C! J
return camera;7 D6 R% Z1 ]) W/ o2 G
}
7 u: H" `9 m7 v( Z public static boolean isAircraftConnected() {
8 R' T" P% \: j4 `# s return getProductInstance() != null && getProductInstance() instanceof Aircraft;- t. k( z& Y9 c7 K8 c5 T. }( l S
}3 s3 \5 b- b' g( O
public static boolean isHandHeldConnected() {, Y3 c; {! ?+ ]) q1 a$ e' r
return getProductInstance() != null && getProductInstance() instanceof HandHeld;% d' u$ u3 j2 _* ]/ D6 h
}
% p* j5 n0 L7 _7 e1 G# @- }$ A; o2 S! L* K" S public static boolean isProductModuleAvailable() {
$ K3 e$ w) z8 F7 T$ j, B1 e return (null != ReceiverApplication.getProductInstance());
. U& K+ Z4 ^) c }
( M0 ~6 F9 N$ y! E. d; t public static boolean isCameraModuleAvailable() {
4 V- c6 ~2 ^9 M* Y. s/ B( B: E return isProductModuleAvailable() && A0 j9 g8 I/ [) A& \9 W
(null != ReceiverApplication.getProductInstance().getCamera());
+ E/ _4 r; _# D& V& }# A5 s, P/ Z }
4 H, Q1 l1 y f public static boolean isPlaybackAvailable() {
) `: Z' O- N: O5 n3 P) g: e. h return isCameraModuleAvailable() &&
' V9 I4 r7 f3 f. z2 ~9 v( F (null != ReceiverApplication.getProductInstance().getCamera().getPlaybackManager()); X: S) s# p# `; `2 z f
}
4 {: [: w& r7 X# y% N' s @Override4 x' `2 N7 V; g% e- @
public void onCreate() {6 n" q4 p2 }6 x9 ^/ o. o
super.onCreate();
; Q9 p: C' A% D mHandler = new Handler(Looper.getMainLooper());3 R4 I% w P$ {" B i: B: W b: m
/**
. o0 g. e' o5 K, k! D * When starting SDK services, an instance of interface DJISDKManager.DJISDKManagerCallback will be used to listen to: y7 G3 W# X, s' D' p4 w
* the SDK Registration result and the product changing.0 W, @* l- Z+ K) E; t% X
*/
- `" z* P, U* C3 I/ ]* G9 {" j //Listens to the SDK registration result
+ X- s0 Z5 N9 J$ Q( J8 N0 k! p DJISDKManager.SDKManagerCallback mDJISDKManagerCallback = new DJISDKManager.SDKManagerCallback() {
+ g5 P% N% m: n0 m# w8 ]2 Y //Listens to the SDK registration result
^2 `' _: b- T# J @Override
2 M3 w8 A F9 I" A' I public void onRegister(DJIError error) {! v) H. Q- |- n5 I9 H
if (error == DJISDKError.REGISTRATION_SUCCESS) {9 C. J. J. g$ ]( P
Handler handler = new Handler(Looper.getMainLooper());! D# I. J4 ?4 B( K/ h
handler.post(new Runnable() {$ M) h! O/ O/ y3 f( l0 X
@Override# F* X( l1 J- A& Z& T1 h. @2 H2 w5 S
public void run() {, s( s- F% w& ?0 q$ V1 q; F# C- r
// ToastUtils.showToast(getApplicationContext(), "注册成功");3 U" A: h' [8 E" e" c$ Z# @
// Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_LONG).show();: E) g) `* s* a" K! e
// loginAccount();
+ W) m5 Q) q- y. M' m }
0 C" \' O8 |, {# { });3 F7 ]+ I5 k8 j% M. |' M: R% @/ L
DJISDKManager.getInstance().startConnectionToProduct();# m$ O0 a3 F3 w3 ?1 i
} else {7 T- a' r5 S- g3 M
Handler handler = new Handler(Looper.getMainLooper());/ o: R3 f' A \4 P
handler.post(new Runnable() {
9 n8 f2 y9 @+ S @Override' e+ ?; i& D/ m2 T! {
public void run() {
* G' ~ t6 ] C3 ]2 ~) I; D// ToastUtils.showToast(getApplicationContext(), "注册sdk失败,请检查网络是否可用");, D3 `/ ~' y$ Q7 V; Z- H& C5 G
// Toast.makeText(getApplicationContext(), "注册sdk失败,请检查网络是否可用", Toast.LENGTH_LONG).show();
+ I" ~5 h, q: n+ i; V$ H: q }$ k) ^& b- L3 A5 Y, G- R: h
});- b" k/ [- l# B0 X* j
}
0 R+ _# w' i7 T0 W4 j Log.e("TAG", error.toString());
L+ Z) b) l) ?+ M' Q* L0 K9 J! g% Z! d }" `: \5 ]! x9 g, `
@Override
# Z9 {1 z" H2 J8 k3 \. ^) a public void onProductDisconnect() {
' M" R7 h7 P) b: {4 ^' j Log.d("TAG", "设备连接");
o/ e! V. y9 O. X/ @" k% M notifyStatusChange();
. X% i+ x, y' R" v& q" L }1 O% S4 H( b( t# G6 G; R
@Override
* t1 P9 j0 ]1 p: i- R public void onProductConnect(BaseProduct baseProduct) {
* B+ Y1 L5 |& y Log.d("TAG", String.format("新设备连接:%s", baseProduct));
6 s7 Q$ e6 _1 V notifyStatusChange();
$ C" v# g9 ]0 n1 ~& j+ b6 ?# c }
4 g ]* x/ r1 H- @4 Q' O( Y: W; g @Override* d* \1 E: ]6 I/ U$ k
public void onProductChanged(BaseProduct baseProduct) {
" F% A' m" K' c/ V% }" b }+ {& ^3 C% Q. ^+ l& K7 i
@Override7 v6 b( C! @( s
public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent,7 W4 N9 p1 t( _; B/ `
BaseComponent newComponent) {/ b7 O- @+ E. _- ^' A8 F, \( r
if (newComponent != null) {2 X, r( @+ D; G" L2 e
newComponent.setComponentListener(new BaseComponent.ComponentListener() {
& P5 u3 q- e" e6 W @Override% A+ S' m9 B0 U& M( _
public void onConnectivityChange(boolean isConnected) { J& x7 E5 h7 I7 ^! @' [* m1 E( a
Log.d("TAG", "设备连接已更改: " + isConnected);
% g) y1 j! x4 U' a# o* l$ B notifyStatusChange();
) F: O3 A1 C* F% S6 j% x0 z8 s9 _ }
) N( a$ Z0 O- m: ^6 ? });1 S* }! S. H3 [& W8 v. }* c7 I
}
, i- O- N7 F* n Log.d("TAG",' V' Y/ E$ a! G! X8 s5 a/ k! I
String.format("设备改变 key:%s, 旧设备:%s, 新设备:%s",
( x( P& }" }. L1 x* m componentKey,
/ g0 d+ ?+ N4 t% H. `* J( d0 B# e oldComponent,
1 M- v) e' e! f$ _! q newComponent));
* U8 N4 e! V' S5 c4 o& r/ ?+ C }* F# j! A) v( `/ Q
@Override0 w) {0 l; d3 x, k k
public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {3 W# w3 ~! X! q) `
}
8 z! }, H2 S% G* i% T @Override e5 I$ F! ]% n: i! i- v# j% K7 c
public void onDatabaseDownloadProgress(long l, long l1) {
; P: z' t4 J+ m }- Z* q2 n& S4 m4 m, y
};2 E/ Z2 p3 i* b9 Q, ^
//Check the permissions before registering the application for android system 6.0 above." Z9 L6 F) `5 h- x4 |& X7 x
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE); `; N; T. h7 j! J
int permissionCheck2 = ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.READ_PHONE_STATE);
. T2 `- c9 d3 B- _ if (Build.VERSION.SDK_INT 0 && permissionCheck2 == 0)) {( l/ U* c/ H/ W! S- f: p* e
//This is used to start SDK services and initiate SDK.8 ~+ y" D9 ?; f2 @ _
DJISDKManager.getInstance().registerApp(getApplicationContext(), mDJISDKManagerCallback);
+ _3 C; v$ ]/ G: u2 S2 X8 } i// ToastUtils.showToast(getApplicationContext(), "正在注册,请等待...");7 b5 R% _' ] }) M* T
// Toast.makeText(getApplicationContext(), "正在注册,请等待...", Toast.LENGTH_LONG).show();* [1 C8 C3 a# e; b+ G# p
} else {9 m: c. ]8 }& H
// ToastUtils.showToast(getApplicationContext(), "请检查是否授予了权限");
' b: \5 }3 N; K& G& ]5 q// Toast.makeText(getApplicationContext(), "请检查是否授予了权限。", Toast.LENGTH_LONG).show();
: k( X+ `/ a. S5 ]( r }& X0 v( ]/ s/ u; _4 U" t8 N
}- \4 G' A1 J+ T( k$ Y
private void notifyStatusChange() {
8 z2 b7 P1 d' |* O& L: ~ Y7 [/ M2 k) ] mHandler.removeCallbacks(updateRunnable);7 W) K' T _' v5 \9 `7 ]' k
mHandler.postDelayed(updateRunnable, 500);
: n% C; k* ]$ s- o }
! s4 u5 Y' f% k% z private Runnable updateRunnable = new Runnable() {
& {+ @" l& ^/ Z) e+ P @Override
0 m' ^# e k+ Y+ n6 u: |- K public void run() {2 r. ~; E o9 _* ^
Intent intent = new Intent(FLAG_CONNECTION_CHANGE);
# I, J: w! G, r! O; s1 t getApplicationContext().sendBroadcast(intent);8 w- _4 W+ \/ ~' @: y3 {8 \0 F
}5 A- | W9 ~: h* D, @% K2 k
};2 I" O5 c- F; j) S6 G
}. k6 \4 q) r( l
上面的代码是对BaseProduct、Aircraft和Camera类进行实例化,在后续使用中不用再去进行重复的实例化工作,减少内存的消耗。
0 {3 o) e# Y1 M% O D3 u: S@layout(R.layout.activity_registration)0 _! K$ l* c0 n: H, J% u
public class RegistrationActivity extends BaseActivity implements View.OnClickListener{" Y; D) B$ N' \
private static final String TAG = RegistrationActivity.class.getName();! y/ T3 _0 _" }& I- R
private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);/ p; M( D; ~+ X3 j2 n7 H
private static final String[] permissions = new String[]{
! E4 [9 q1 f# P Manifest.permission.BLUETOOTH,7 g6 t8 ]. ~; O
Manifest.permission.BLUETOOTH_ADMIN, N, M f* |# M& U
Manifest.permission.VIBRATE,4 `5 `- k& Y/ a0 R T
Manifest.permission.INTERNET,
5 L2 R0 D- _- W) W4 T+ V6 {/ O Manifest.permission.ACCESS_WIFI_STATE,
. K; W- F5 I+ E5 z9 q$ {: v& x Manifest.permission.ACCESS_COARSE_LOCATION,
0 k. V2 y# I# t( H" Y Manifest.permission.ACCESS_NETWORK_STATE,, J' F/ V+ B( U6 B# K
Manifest.permission.ACCESS_FINE_LOCATION,5 x7 `4 t# r, ~* [: q: F/ W
Manifest.permission.CHANGE_WIFI_STATE,. s: ]* X( Y6 G
Manifest.permission.RECORD_AUDIO,+ B; X8 f3 E4 s. K, Y4 {8 p i
Manifest.permission.WRITE_EXTERNAL_STORAGE,$ S# b, ?5 H1 e( v
Manifest.permission.READ_EXTERNAL_STORAGE,
) [* T6 @$ ~/ C Manifest.permission.READ_PHONE_STATE,& n" D7 g6 G. D7 h. x/ v$ ~
};
+ i. C; t, p/ I' d. T' @( d8 E
3 G) x% F" T" |7 |/ E @Override4 d+ Y/ i( m5 `, q. T# A
public void initViews() {. O4 D* w( n2 N: m/ L: J
isPermission();( \( V& u6 |1 ]; }" t
IntentFilter filter = new IntentFilter();$ F/ s) m- ], b( d0 t
filter.addAction(ReceiverApplication.FLAG_CONNECTION_CHANGE);! P% V# O% s3 W9 E$ c4 k
registerReceiver(mReceiver, filter);
/ L0 f; X6 ~9 K/ M1 Q6 ? }
: Q h% {/ X) ]! s7 U8 q @Override
) |) z/ z( X3 q7 a) o( N) o/ [ public void initDatas() { q7 D0 _2 i8 I9 j+ q! p, r
startSDKRegistration();* I; y9 _; r, t% N# @
}
`& d9 N8 e; `" _4 B$ x: L) } @Override( M/ b, m- h4 o ?& p
protected void requestData() {
8 M8 O$ i& ^+ F; R
) [4 z+ V% y. Y+ c }( [' u& ]" @2 O; P
9 z1 w2 k$ u& j" p9 u @Override- Y# {2 N! ?2 n+ M) C. b2 p
protected void onResume() {+ Q7 I R6 \5 F9 z5 \0 g$ [
super.onResume();' ` c/ j) u( D4 E4 o0 Q
}+ \% K+ Z" I# y1 [9 h r. K
9 j. C6 d+ d3 J" R' H4 c- U
private void isPermission() {7 ]& o# ]; y) G
requestRunTimePermission(permissions, new IPermission() {6 s6 Z* \- I( r: a7 |
@Override
- c) j' ?* |0 l/ a- I public void onGranted() {& ^& `9 } ?- J0 P8 o9 @
}& M G R8 k9 ^1 D
@Override
: R1 \& z! |2 c+ R: a public void onDenied(List deniedPermissions) {
- B8 T7 x8 h$ w1 G& S }3 ~8 m6 G f I! u, ^0 S
});
6 c1 [. [2 o5 P8 S# n& l f8 g! W+ } }
5 p& ]6 P% N d ' B; o0 G Y+ ]% ~7 R7 [3 _' b
//无人机首次注册
8 g$ \3 P, h @; q d* z private void startSDKRegistration() {
. g. }2 G/ T/ z1 k4 s; `! F/ ^) { if (isRegistrationInProgress.compareAndSet(false, true)) {% H+ B' @+ ~ I. ~. F0 C! W( I
AsyncTask.execute(new Runnable() {7 v0 W: ^" o) [' J
@Override d8 b! G- k: d# |. R5 w+ ^) o
public void run() {9 D0 |9 Z/ B9 q/ h4 e
// showToasts("注册中,请等待...");
8 X2 X: W! G3 O1 u DJISDKManager.getInstance().registerApp(getApplicationContext(), new DJISDKManager.SDKManagerCallback() { u1 h) X# u4 {5 V
@Override$ @) D6 T+ J' X; ~5 u
public void onRegister(DJIError djiError) {
. O& L' g5 g' W+ t if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
/ u/ T% v! v: H% m- y# i, E% H2 s( O DJILog.e("App 注册", DJISDKError.REGISTRATION_SUCCESS.getDescription());
% f+ i' B# e& X) w DJISDKManager.getInstance().startConnectionToProduct();, N r& c$ o9 L
// showToasts("注册成功");
' w# s) Y" {2 q: r loginAccount();
2 V( I+ I- {7 v u7 A7 I } else {
6 ^* R* e( t. o showToasts("注册sdk失败,请检查网络是否可用");
: M1 ]0 T; z/ Z: o }
& e- V4 O/ t: n/ @ Log.v(TAG, djiError.getDescription());* L! C: w; a; b4 Y- U
}4 E3 ^% e. Y- ]
@Override
5 \) M" X |' C: H public void onProductDisconnect() {, @* g; D0 r; R( ], @1 K$ W
Log.d(TAG, "产品断开连接");: ]- C0 X3 Q- O8 @ F
// showToasts("产品断开连接");' q9 y9 ]. t( ~. U, Z
}& I) o0 M6 B! \4 j. J) }) ?* T
@Override
) o6 N3 l$ O/ F* d) a public void onProductConnect(BaseProduct baseProduct) {8 i/ B! e4 O! C, Q' p, C% o
Log.d(TAG, String.format("新产品连接:%s", baseProduct));
. d7 v' w3 i7 w* L* y' @# ~1 w // showToasts("产品连接");9 A) x2 V3 s3 R7 l4 \1 y2 ]
}
' ]; g" C1 M2 X# i; E m @Override! K2 e# r. T0 t4 n5 g/ N0 _7 b
public void onProductChanged(BaseProduct baseProduct) {1 D/ _* S. |6 m7 _& p, g
}" _, X9 V, ^( s
@Override
6 A9 e9 J$ ]2 m$ j- w' Z public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent,
, x5 R; i- s' Q7 v# [1 ~ BaseComponent newComponent) {
2 U L8 O N; n# d, j if (newComponent != null) {$ O) w+ C) V4 @/ i( j
newComponent.setComponentListener(new BaseComponent.ComponentListener() {4 a- ~: N5 [: d! S" V" y
@Override
% Q- B* v8 d+ f4 u* K, @6 z# H public void onConnectivityChange(boolean isConnected) {6 [- a1 p. z/ Y0 {
Log.d(TAG, "组件连接已更改: " + isConnected);
2 l; E- T) j8 Y" S% ?! k: { }& l* t* g5 b ]+ |
});
" U+ O) {+ t) G: p3 F }% J' w. I2 i8 \, ?8 D. e/ z& C# l
Log.d(TAG, String.format("改变设备Key:%s, " + "旧设备:%s, " + "新设备:%s",
" _/ o, z2 I" T6 P% k componentKey, oldComponent, newComponent));
) H0 i( r7 M& k* p: z }3 Z. l( K) @8 ]! E1 G! O& Y
@Override# |: d9 W" n8 N5 L" z1 [+ {9 d: P
public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {
+ N( y- ~, H Z' d0 z6 p; F }
% c+ g* T$ F3 n+ C @Override
/ T7 K" L- T3 x5 u4 ? public void onDatabaseDownloadProgress(long l, long l1) {
1 E$ Y. C1 I: l) J }8 l. P8 V9 S4 g% r$ P
});: l6 s$ c! e' [9 F
}
5 C. s5 M' q/ o1 t7 M. K! T5 B });" V1 @) ^" {8 a% K) G! Q
}
! W0 ?/ ^# |4 o' I- C" t- A- I }6 f; j- C% t/ p" c" k+ Z: J
protected BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ Y6 c! A4 g s0 { @Override
$ d5 n/ a2 T% G7 w public void onReceive(Context context, Intent intent) {. _) R5 G: g7 E% f; z7 R% i
refreshSDKRelativeUI();
( A. Q: N5 }% x$ g, \ }
/ R) z- [8 t/ C% @& W' _ };, R+ [3 S+ L0 R; o/ N, X
private void refreshSDKRelativeUI() {; w- f1 R3 X! L1 k+ y$ h) Q! Z
BaseProduct mProduct = ReceiverApplication.getProductInstance();/ D( X/ O6 G4 y0 S- O2 X% _
if (null != mProduct && mProduct.isConnected()) {9 e% V* s. B9 z3 j1 f
Log.v(TAG, "刷新SDK: True");) S- n+ H, w0 ~! j. ?' U; L
mButtonFlightTask.setEnabled(true);6 M* o P5 r& i
mButtonSettingRoute.setEnabled(true);
) y' ~1 y" r6 z0 o# E7 w mButtonFileManagement.setEnabled(true);! Z( a2 a8 F! o+ j
} else {& a' y) `0 M! O; t" X% Q9 m
Log.v(TAG, "刷新SDK: False");
+ o( U4 B3 j& C8 G( F// mButtonOpen.setEnabled(false);% i# M9 ]% [5 j" Y; \( e( G1 r8 ]
// mButtonSettingRoute.setEnabled(false);
5 g' |: n8 }# C, @& u& C// mButtonFileManagement.setEnabled(false);
. ^- B; W; @5 I* \& c4 o// startSDKRegistration();$ A0 n7 U4 t0 ?, X
}
! T$ W% w1 m. o4 i# S) p- p, V9 d }0 n) _9 u; K1 O" i
protected long exitTime; //记录第一次点击时的时间2 I- K/ M3 v6 ~$ N
@Override$ T' Y5 u. }& S! X% D* R9 B% l
public boolean onKeyDown(int keyCode, KeyEvent event) {0 R# u/ V9 x7 b& G- s# B2 H
if (keyCode == KeyEvent.KEYCODE_BACK) ?( ?! P% `' x3 u- C2 i& u
&& event.getAction() == KeyEvent.ACTION_DOWN) {
' Z3 z/ V" U* C U1 g c if ((System.currentTimeMillis() - exitTime) > 2000) {* N' T' D+ n+ y$ I) h2 h4 _2 T
showToast("再按一次退出程序");
( Y z* i+ n, {2 j exitTime = System.currentTimeMillis();
( F" q" n: O8 @) {/ _ } else {
4 V( s" A1 w% K8 [% C' B RegistrationActivity.this.finish();4 }$ w9 H: [' w1 |
System.exit(0);
/ @# z* h" S1 h- q+ _ }
, G9 G' ~ J6 d9 ^ return true;
7 j G1 i. O# E; J5 M }
2 V3 T( [; [. { return super.onKeyDown(keyCode, event);/ ~9 x* Q" G. x
}
7 ~& {+ c& @* |( c* R% C, v' r" e2 v
private void loginAccount() {0 r1 a: k9 K+ p3 f/ F& V% O) V* b* H/ }. T
UserAccountManager.getInstance().logIntoDJIUserAccount(this, new CommonCallbacks.CompletionCallbackWith[U]() {( `: J) m" s5 k/ Q h
@Override& n. x/ Q- l; x. a
public void onSuccess(UserAccountState userAccountState) {: C8 g7 I' p& R# q3 B
runOnUiThread(new Runnable() {6 W ^* y+ c8 F
@Override
4 V/ ~' d( W, K' E; [. x public void run() {
" O5 C5 w6 q$ R: @# o$ r% I mButtonFlightTask.setEnabled(true);
9 y, G3 J. T {( M0 h mButtonSettingRoute.setEnabled(true);
1 k4 y7 v5 |; c; y7 H- E; J/ ~' T" w mButtonFileManagement.setEnabled(true);
* j/ _. J C. Y0 u! Q- l0 ~" u# } }
% w: l3 s7 L. A4 S& s$ J8 C });
( O. q- U! C" Y0 L9 @ }
5 [# O9 h2 P1 k' f @Override
1 [; @; c' F. }3 e9 C' E6 k public void onFailure(DJIError djiError) {
8 G( M6 Y) |% I; z( Q/ U }, W- d7 i2 l5 \+ e" J
});
! T# p8 {8 j3 F& c. [: w) s( }! \ }
8 g* M' D/ P1 o$ \; D}: l+ I& h" ?$ x7 r4 b) |" c, a" u H: A
上面的代码就要进行第一次注册登录了,当然你不需要自己去设计登录注册页面,大疆会调取自己的登录注册页面供你使用。3 K$ L" o7 z( ]
mk1fg5zkzzj64015955923.png
- M& B! g) d/ W+ V& A* T* m安装提示注册登录即可。. ?' q( r5 ^5 C7 T- {8 F. V+ ], w
上面的这些做完后,恭喜你!现在,您的移动应用程序和飞机可以在中国使用而没有任何问题。换句话说,您的应用程序现在可以看到飞机的视频流,并且飞行将不仅限于直径为100m和高度为30m的圆柱体区域。
8 [4 F0 n7 `- {# f( D3
3 \, U! {* L: g- x) W飞行界面使用0 y8 f9 T: F) p. b
虽然说可以正常飞行了,但是飞行需要设计飞行界面。那么创建一下飞行界面的UI及逻辑处理文件。逻辑处理文件中包含了获取飞机的实时姿态信息,代码中有注释内容,描述的内容就不多说了。' t: |. v2 s/ q7 ?
) _4 `% I' V" p- O
导入UX SDK依赖
9 V8 s3 d* S2 n上一节有说过集成部分,其中内容有导入UxSDk 的操作,这里再顺便提一下。再build.gradle文件中加入implementation "com.dji:dji-uxsdk:4.16"依赖,等待安装即可。
1 z/ i- P2 p& ~* x! Y( l) H8 o/ O: Q. e
设计界面UI+ |7 C* A3 M9 d7 e# w
创建MainActivity文件及activity_main.xml。
! g+ y: a. _. t! i: LRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"' P$ H1 t6 Y' E% @
xmlns:tools="http://schemas.android.com/tools"
. @- h: |0 K- O& W xmlns:custom="http://schemas.android.com/apk/res-auto"
) D1 U1 u: \- X. k+ @# C android:layout_width="match_parent"
/ x5 s# ?! u4 q6 b# H android:layout_height="match_parent"
: {" L, [! c3 w* m' k( I- o android:background="@color/background_blue"
9 g: F. K' _6 `1 {5 G R" g# v! N android:id="@+id/root_view"9 \/ Q. W! A5 c+ s7 W
tools:context=".ui.MainActivity">
) i# n& g, u3 U: x
. ~/ A9 K J9 v; y RelativeLayout
8 _0 [8 D. K; H% j/ T( _ android:id="@+id/fpv_container"
: J/ A t, v9 L' G$ b7 S; ~: I8 x! d android:layout_width="match_parent"
: z! i8 k5 C# z8 z% W. g android:layout_height="match_parent">( _, y; p2 R: l* @
dji.ux.widget.FPVWidget' c5 `; }- ]6 k' I5 c) F
android:id="@+id/fpv_widget"% e2 |# }0 Z1 _
android:layout_width="match_parent"4 l/ Q7 m7 ?/ {$ f u+ L7 x
android:layout_height="match_parent"/ r7 G4 j+ @6 I5 a4 Z" J z8 U! T
android:layout_centerInParent="true"$ m" C( h. l9 D, f
custom:sourceCameraNameVisibility="false" />
# ?* G- D- E9 [" j RelativeLayout>
8 U. p) i+ ?+ J3 F; f6 ^# e' b9 B; f dji.ux.widget.FPVOverlayWidget% \0 m: x, d- [& m, R0 D; C5 R
android:id="@+id/fpv_overlay_widget"8 i0 C5 v! _: V/ U! Z) A
android:layout_width="match_parent"6 b; F2 m0 C6 h- T
android:layout_height="match_parent"/>6 a' T, N" a$ P% B! a
RelativeLayout
0 C2 [' l. Q3 g, Q3 X- E- S' Y' W android:layout_width="match_parent". x; p {0 @" x$ N- [
android:layout_height="match_parent"
2 x u1 s2 ]# S4 Y: `& e, E* F android:layout_marginBottom="40dp"
. N8 p9 E1 u+ T& k" o android:layout_toRightOf="@+id/TakeOffReturnPanel"+ J9 g Y8 N! s" K1 p" ]) Q1 u
android:layout_toLeftOf="@+id/CameraCapturePanel"
. }3 m) g; n: D- O" J android:layout_below="@+id/camera"3 [# S+ W: c; a) K: K" K2 F; P) z5 p
tools:ignore="RtlHardcoded">
* m9 t( y1 z- u% z6 c- c& |) L2 U dji.ux.widget.RadarWidget
8 e/ ]% P% _2 W& U) ? android:layout_width="wrap_content") l. y, k% S" P6 X
android:layout_height="wrap_content"0 t+ `5 E9 k7 c6 f/ M
android:layout_centerInParent="true"/>
- C; z6 [5 p. e) M/ Y- y7 d RelativeLayout>2 i5 e% F/ n- u) n& U% c
9 U2 M6 q# |% O; T, j$ C4 i LinearLayout) H2 K# A6 ^2 ]( F
android:id="@+id/TakeOffReturnPanel"
& z3 o" v, I, P% t2 | android:layout_width="40dp"
( c, D! K. o5 r4 g' Y$ Z android:layout_height="wrap_content"
- T8 a" H# [' G3 k! q) \ android:layout_marginLeft="12dp"+ h) a* Y* C$ R# l% T
android:layout_marginBottom="4dp"
K5 n, p# J" x android:layout_marginTop="50dp"
% D$ |, I- K* X9 y* @/ p3 N! K android:orientation="vertical"' h& m3 E# s \ g
android:gravity="center">1 C# u6 _% X( o
ImageView/ R5 h5 K$ M" v( D b
android:id="@+id/img_show_back"
8 F: ~& v9 h% U! v4 q1 o android:layout_width="match_parent"
! _! [7 N$ K7 W7 o% g4 Q android:layout_height="38dp"
3 {3 K7 L& K# o7 f' y1 c+ N android:src="@mipmap/ic_back_36dp"/ U* U# h6 F/ L k' u& J
android:layout_marginBottom="10dp">ImageView>
! a& @* }- N: [' [) C- W2 P dji.ux.widget.TakeOffWidget) O' K; P& {) e+ u! J. S5 m9 ?
android:layout_width="40dp", p$ `% z* ?: k( f! H
android:layout_height="40dp", m% n' f& h6 E" K$ J. W% m
android:layout_marginBottom="5dp" />1 C ^5 L* w* i4 S4 i2 [
dji.ux.widget.ReturnHomeWidget
' D% r- p/ E: Y, w9 i android:layout_width="40dp"/ S( h/ I5 b2 T# V0 H6 G
android:layout_height="40dp"# N, Z$ ]8 u& i
android:layout_marginTop="5dp"8 H* {0 J6 ~) |1 p6 Q! b: i
android:layout_marginBottom="5dp"/>) k8 B9 ]9 ?5 g5 v/ U9 H
ImageView& o; S2 R: y' s% \- ~: p" r
android:id="@+id/img_live"
/ ^; w% U6 I0 g! }; o0 k android:layout_width="35dp"% ]/ v. P! W0 ]* |. o9 f& k0 E
android:layout_height="35dp"5 u% U3 C8 Y5 J" t5 ?6 Q
android:layout_marginTop="5dp"
! L2 x! D- K3 q! G! o8 [' R9 i2 c android:layout_marginBottom="5dp"
' A- t4 O& \5 H# L1 `8 g android:src="@mipmap/ic_live_write_36dp">ImageView>
+ Y; {7 D+ N' Q# r LinearLayout>' s" @/ K' E% J* K4 l9 r& y
FrameLayout
0 _% {" b! H1 g android:layout_width="150dp"6 m: ~" j, V, t/ x) U
android:layout_height="100dp"$ ]6 ?, K7 Q0 Q
android:id="@+id/secondary_video_view"
' B, ]& Y* o0 D3 B' l r android:layout_marginLeft="12dp"" i/ |* Q& Q0 ?( R5 b. z7 R
android:layout_marginBottom="7dp"
+ R; ^; z9 N0 J0 ]# { android:layout_marginTop="50dp"
6 I7 h w# M. k7 Z android:layout_alignParentLeft="true", Z! X p0 b7 a0 S A0 b
android:layout_below="@+id/TakeOffReturnPanel". V; `/ v0 g2 c/ {
android:background="@color/black">; b& ]5 O1 q, r7 ?( P3 h
dji.ux.widget.FPVWidget
! B5 u9 v- ]; ^& A2 E+ S$ P android:id="@+id/secondary_fpv_widget"4 p! e1 ~5 s2 z& ^
android:layout_width="match_parent"2 g% e. P R4 H- |5 ~% Y
android:layout_height="match_parent"
- o: m! S. `* B( H custom:sourceCameraNameVisibility="false"5 {" i5 j# P9 e% E; p. c, p
custom:videoSource="secondary"/>
F$ P( ~4 f2 v" a4 L FrameLayout># w- a7 V! L- z u6 l' s5 o; j5 D: y
dji.ux.workflow.CompassCalibratingWorkFlow
8 T# D. H5 ?" y& J& \+ y& R$ ~2 U# n android:layout_width="match_parent"9 }/ k' j2 Q5 Y5 q" K4 j
android:layout_height="match_parent"/>
0 f. A. N4 R! g9 n- e. l c" }( O) C; Z dji.ux.workflow.CameraSensorCleaningWorkFlow* O) e' F4 O( m1 X0 o# C: ^
android:layout_width="match_parent") f9 _' {( f9 o( d
android:layout_height="match_parent"/>
; R+ d" J6 |: S dji.ux.widget.RemainingFlightTimeWidget
, N" k6 v! h3 o4 f, e: ?8 V android:layout_alignParentTop="true"
1 L/ _& a# k" M0 P android:layout_marginTop="18dp"
3 \& z; y5 y P& K2 { android:layout_width="match_parent"
' E) j. `* Z6 a( d android:id="@+id/remaining_flight_time"
2 d4 A9 \1 n+ z android:background="@color/transparent"
1 B6 S+ Z; S9 |' J android:layout_height="20dp"/>
, c" e& O [ q: f8 M9 F3 c LinearLayout9 v8 F6 F9 ]. X1 E
android:id="@+id/camera"
; R4 D4 h; w1 ^% D3 M android:layout_alignParentRight="true"
0 j) _8 P& v* e, w6 Q. ] android:layout_width="wrap_content"3 |- Y }- Y5 `! w7 N
android:layout_height="wrap_content"
5 }2 [5 {* T4 C$ b# Q9 v android:layout_below="@+id/signal". s6 Z" J1 U: a6 l3 t$ {
android:layout_marginTop="15dp"+ o9 x* L) ~, s+ v
android:background="@color/dark_gray"
. [0 K( J2 N, q) ~0 { android:orientation="horizontal">% G" Q6 ^4 ]1 @: y7 l8 ^( |: { h
dji.ux.widget.config.CameraConfigISOAndEIWidget
% j" r! b* R {& t: D5 m android:layout_width="50dp"
& ^; p! `' C: Q android:layout_height="25dp"/>) z2 W5 s# b- {/ {) r: B
dji.ux.widget.config.CameraConfigShutterWidget
, d; g; e" F/ f/ g android:layout_width="50dp"
: N! F; }) K* @# W+ | android:layout_height="25dp"/>1 {! C5 k0 Q( U k
dji.ux.widget.config.CameraConfigApertureWidget
0 [/ n2 p1 G9 [- a3 z- M android:layout_width="50dp"
- ~. r" H( D, }( z android:layout_height="25dp"/>
* v3 s4 S4 N/ f. ]( j1 P0 H# I2 o dji.ux.widget.config.CameraConfigEVWidget
& Q( D$ i, E8 p# A android:layout_width="50dp", R( K' W- Z' T8 c9 W, ]
android:layout_height="25dp"/>
' B9 ~4 x' x" W5 \+ `8 `! ~ dji.ux.widget.config.CameraConfigWBWidget
& d; o0 P/ R' L- I: C android:layout_width="60dp"
1 }1 l. |& a. X android:layout_height="25dp"/>8 r( O( H& I& Y- M2 b# g# g7 Q# ~) f
dji.ux.widget.config.CameraConfigStorageWidget
7 N3 ^2 |+ ]+ e! E: x android:layout_width="108dp"
6 i( S3 T, K8 @/ }& N; S android:layout_height="25dp"/>
. o. f: e4 F& N" u dji.ux.widget.config.CameraConfigSSDWidget
& ^. J: ^' @9 R8 J& p android:layout_width="125dp"3 }" ?' Z5 ~" D8 o5 X# @7 y* y/ J, c
android:layout_height="25dp"/>0 ]6 ^% ~, H% P5 J
LinearLayout>/ l! j8 [( W3 M9 L# d4 u/ ~' p
LinearLayout
4 g) i3 M' ]8 Q0 ?* Y P% n android:id="@+id/camera2"' P9 [4 g1 w3 t3 N
android:layout_width="wrap_content"; b2 Z5 k2 {, N
android:layout_height="wrap_content"7 h% M c" ]& v6 q$ `% F- z/ R" _
android:layout_marginTop="5dp"
' Q3 n% z1 K: r4 T, C android:layout_below="@id/camera"
) m: ^5 L8 E8 e* r% ? android:layout_toLeftOf="@+id/CameraCapturePanel"
0 {' j/ u8 ~4 A0 a2 F8 Y% B android:background="@color/dark_gray"
* N" o- ^8 A8 H$ V& o; t5 f% S+ e! w android:orientation="horizontal">& c% [) D8 B2 ?& f& U
dji.ux.widget.SpeakerWidget3 }; v1 j0 N4 S( X. L8 d! i0 ^. {
android:layout_width="35dp"
% J* M H! P0 h% m5 b android:layout_height="35dp"/>
$ |: S ?* w4 I' e dji.ux.widget.AutoExposureLockWidget0 a& x2 _7 k, n I+ \
android:layout_width="35dp"
4 ?$ G/ T) u: \) a5 [ android:layout_height="35dp"/>8 s$ Q f V6 {& o
dji.ux.widget.FocusModeWidget: N- ]3 h3 K# d9 i+ G, k6 j; S: c
android:layout_width="35dp"9 ?1 E5 r; T' h- o
android:layout_height="35dp"/>
2 `( g* F2 s K) j8 u dji.ux.widget.FocusExposureSwitchWidget* E, W( _8 H) J- W: o2 D
android:layout_width="35dp"" b3 }2 P: a. e- v( T9 \
android:layout_height="35dp"/>& c: [- ~6 p6 ~: }
dji.ux.widget.BeaconWidget) }' {6 h! Q4 v% q) T% W
android:layout_width="35dp"( p6 y: Z3 @0 Z$ D8 y
android:layout_height="35dp"/>* I; y! R- E, I+ l; f
dji.ux.widget.SpotlightWidget3 [( M8 n2 E8 a- e% ?; R/ j
android:layout_width="35dp"
! R) ^) Y' W; _# [$ G android:layout_height="35dp"/>
5 b) M! A* f0 [6 ^- } dji.ux.widget.AccessLockerWidget
6 e7 i) e! C' n android:layout_width="35dp") f7 V0 w9 j9 o9 o& u, r' }& P
android:layout_height="35dp"/>
: p& A4 q- w0 ]' ^ LinearLayout>
7 b5 J, B( @& t3 `+ L) i dji.ux.widget.ManualFocusWidget* Z4 C0 x0 h9 a* L, Z5 T! ?' D8 L1 _
android:layout_alignTop="@+id/camera2"8 L& f5 s5 J' t3 Y6 m
android:layout_toLeftOf="@+id/camera2", ^+ ^2 D' V; F% `
android:layout_width="50dp" |- n# N( H T |+ @: b. d: _: _
android:layout_height="210dp"4 E9 a3 Q0 Z4 W3 z
tools:ignore="RtlHardcoded"/>
7 u' @+ ?2 w6 o, G5 Z4 Y! ~ dji.ux.widget.MapWidget2 [8 R# s0 a( _0 s) @8 ^
android:id="@+id/map_widget"" T! n. }9 T& G6 y
android:layout_width="150dp"
+ k0 d$ l. y) W0 L android:layout_height="100dp"% P8 y% F9 c( h" T
android:layout_marginRight="12dp"
2 n) B8 X/ ~, Z% y5 e/ t2 {4 u+ H android:layout_marginBottom="12dp"
n0 P% w7 O- m5 L& V I, j* F( i android:layout_alignParentRight="true"
& r0 a% @" V: l- T# C$ ~ android:layout_alignParentBottom="true"/>: o. q& l7 }, a
0 F- G: d5 Z+ G% I dji.ux.widget.controls.CameraControlsWidget
, S! C- \3 `/ H6 } @& } android:id="@+id/CameraCapturePanel"$ P8 ?2 D* B9 h: Z. L6 \2 l. ~
android:layout_alignParentRight="true"
; J% J; Y+ L+ d. J android:layout_below="@id/camera"
/ Y6 ~5 U# M* h android:layout_width="50dp"
6 u7 T/ w8 z" p5 _* Q android:layout_height="213dp"
" S0 ^# R$ J. M- t, [6 K android:layout_marginTop="5dp"& C2 A* w. V+ j) g: N6 u
tools:ignore="RtlHardcoded"/>
4 H5 V* u9 `' C" a1 ?+ n
5 i+ J; m0 \1 |: F2 N' l, Z LinearLayout
: D. \. Z$ m; T) ~; {/ X$ D android:id="@+id/signal"3 F, P: m h! T. q
android:layout_width="match_parent"
1 x2 O: \5 j0 q( m android:layout_height="25dp"
( F; e4 h( b3 n android:background="@color/dark_gray"
1 ]0 a2 e$ }: S0 k6 \ android:orientation="horizontal"> v+ E* g G! N
dji.ux.widget.PreFlightStatusWidget
m3 @% @: ?; O3 V4 J& P& ~ android:layout_width="180dp"
# z M! t. H% e& O" j, o' ]1 S android:layout_height="25dp"/>! J7 g }) k5 h4 z& K V
dji.ux.widget.FlightModeWidget% o6 X2 Z: `3 V+ J3 G3 S: `1 {. A6 M
android:layout_width="103dp"# B$ `0 c1 b6 i" d
android:layout_height="22dp"/>' }! R7 h ~: i ?- d- N- G
dji.ux.widget.GPSSignalWidget
9 A' w! l: J/ l% z! M } android:layout_width="44dp"( ^2 H0 {: s: |7 Q( u- i
android:layout_height="22dp"/>( e# Y" U/ _" P
dji.ux.widget.VisionWidget
/ a8 y, L. q, W# U# A9 g& K android:layout_width="22dp"
& ^. X4 j) |7 i android:layout_height="22dp"/>
. U- z+ x2 O2 p, a1 ^. v% T1 u. G dji.ux.widget.RemoteControlSignalWidget" R$ ]" q4 T2 K6 X: B/ B; R, Z: y
android:layout_width="38dp"
! D9 B% K, g( I& P1 R" z: D' I0 L t) ^( r android:layout_height="22dp"/>3 B3 y) ^- S. A" h1 t* c
dji.ux.widget.VideoSignalWidget1 p$ Z9 @: m3 ]2 U& D
android:layout_width="38dp"# g% W9 |4 G. b- m/ p% R
android:layout_height="22dp"/>6 J/ q/ h y1 c. G5 ^
dji.ux.widget.WiFiSignalWidget9 e. Y2 D1 J( h! C- X6 I W
android:layout_width="32dp"1 i5 G; ~; P+ Z! L! m# z* K* |
android:layout_height="25dp"/>4 k% _ B8 }9 x+ S+ n' C) A2 m
dji.ux.widget.BatteryWidget7 u. R9 i: D7 i7 U' k
android:layout_width="96dp"' K9 P' o+ G* N6 f% Z5 j/ v! I
android:layout_height="22dp"6 ~1 `1 h6 X- j8 N. D. z. M
custom:excludeView="singleVoltage"/>! R3 g( f; \' t7 Y- A+ I L
dji.ux.widget.ConnectionWidget; f$ |9 X: b( @0 | _6 j% L
android:layout_marginTop="3dp"2 T9 W0 U, u& {0 ]
android:layout_width="18dp"( d$ Z0 K% T$ V9 k0 C
android:layout_height="18dp"/>, e/ Z) P' c: O1 D2 B3 p) n7 d
LinearLayout>
2 q; b+ r$ K8 w: k* Y LinearLayout! a7 q }1 {1 ?
android:id="@+id/dashboard_widget"
5 x' S9 a/ Q, i* u! W android:layout_width="match_parent"6 G: H- `3 Q3 x1 v% P1 b6 y/ T
android:layout_height="wrap_content"6 i& y. L! g3 p- _
android:layout_alignParentBottom="true"
q+ H8 ]/ V/ Z" j( w- x, D android:orientation="horizontal"
/ V( f& S2 C6 F2 W Z/ l+ I! \ android:padding="12dp">
2 j% B5 J6 [ k: ~2 d2 h dji.ux.widget.dashboard.DashboardWidget
) K5 p6 s' d1 j/ @! ~ android:id="@+id/Compass"
( J K* g" `( |5 B' \ android:layout_width="405dp"
* B5 c [4 T9 e android:layout_height="91dp", R( Q+ H2 y& S
android:layout_marginRight="12dp"4 U/ K, n- |% c$ p; H4 J' x* [
tools:ignore="RtlHardcoded" />
) w) E* ~0 d6 d" h, d LinearLayout>5 O& o; Y6 m4 [! O
$ N. y; F; c7 a$ d2 \4 }( t) L4 N
% B# M/ R7 z! L$ h5 \: x
+ @. j6 f; b3 |
dji.ux.widget.HistogramWidget
6 t6 p" h+ I+ M# O' z android:layout_width="150dp"
1 `6 E& E# y, p+ @6 |5 y: Q$ s android:layout_height="75dp"* v: X3 k" ]; w
android:layout_centerVertical="true"; w0 y" `) H3 n; k: b* F0 t1 s, f
android:layout_toRightOf="@+id/TakeOffReturnPanel"
S, k) T3 N6 _ tools:ignore="RtlHardcoded" />
$ Z5 ` J# D$ q8 K dji.ux.panel.CameraSettingExposurePanel. i& H( S. B; X- t) P
android:layout_width="180dp"
u( n( k6 r+ @ android:layout_below="@id/camera"- ^$ E8 y7 M' u. i" y! j3 q7 [
android:layout_toLeftOf="@+id/CameraCapturePanel"
0 F- t; o" A; w& U% J0 j android:gravity="center"5 @/ q! l) {7 c8 r
android:layout_height="263dp"" e7 }1 Z. R( R: @4 ^! f0 r, i
android:visibility="gone"
9 \4 q9 |& W3 R8 ]/ \1 A tools:ignore="RtlHardcoded"/>: w# h1 b5 L8 ^7 u* D' L& D7 K' d
dji.ux.panel.CameraSettingAdvancedPanel
& e. c8 p( h& c0 U7 R" u, Z3 M+ A* z android:layout_width="180dp"! l* W2 i; S5 N- L2 ]7 P
android:layout_height="263dp"
4 D9 [8 V4 a2 g( x) B! F) ] android:layout_below="@id/camera"; m4 @" d N* U: ?, V2 G1 U7 Z9 ~
android:layout_toLeftOf="@+id/CameraCapturePanel"
; f8 R7 i' V: N7 V- e5 y9 O7 l android:gravity="center"
; y5 v; Y7 F5 L k android:visibility="gone", b+ \2 H# U' q& [ {
tools:ignore="RtlHardcoded"/>
8 y4 d/ p/ ?, W0 B* j& s dji.ux.panel.RTKStatusPanel a( f, g7 H# t& U
android:id="@+id/rtk_panel"7 G# K7 c! c& A7 B0 Z
android:layout_width="500dp"/ o6 _, p8 ^* [, H7 o: ?& R, c
android:layout_height="350dp"
p8 z( ]3 P- s1 q+ V android:layout_below="@id/signal"
/ x+ i. S2 l: o3 J3 K9 k4 |; f android:gravity="center"% V4 Z2 B' E! l. U/ A( {1 \
android:layout_centerInParent="true"
* l$ \/ w/ \$ I8 F, N4 o4 o android:visibility="gone"/>) \9 f! c7 Z- C
dji.ux.widget.ColorWaveformWidget
, Y, d: x% }' s3 @3 j; a3 ? android:layout_width="394dp"4 e; X$ B, V' N- j6 f4 H+ k
android:layout_height="300dp"1 B7 j4 n& }% B2 x8 q
android:layout_below="@+id/camera"
7 G$ D7 o! U/ ~- F android:gravity="center"
- L2 e, G& V9 u# M2 e# o, ] android:layout_centerInParent="true"+ z$ q4 C# O r4 f0 D+ N& L
android:visibility="gone"/>4 A1 y1 H3 N8 I* _" Y9 [! U
9 B1 I* m& b8 g( X2 W# i( h; \: u" `
dji.ux.panel.PreFlightCheckListPanel
, b/ @- C/ Z/ B android:id="@+id/pre_flight_check_list" y- T5 ?. M4 g
android:layout_width="400dp"- S" f, r+ K% c% {* o5 {- N
android:layout_height="wrap_content". o- R5 v8 s: M3 Z5 E' p, X" {
android:layout_below="@id/signal"
& R: n- O* W* Z6 Y custom:excludeItem="ESCStatus". f9 N/ k2 s$ L) i+ ]8 x
android:visibility="gone"/>
' Z9 w* I4 M9 v. A' t, v2 l dji.ux.panel.SpotlightPanel
0 d6 N1 W! u# Q* N android:id="@+id/spotlight_panel"* T; y6 o8 Q6 ]3 ]4 w; W
android:layout_width="300dp"7 t: k& ?9 K; |7 G9 ~: y+ l/ N2 p
android:layout_height="wrap_content". A& }1 r& ^/ B) n- `
android:layout_below="@id/camera2"
( c% h! W! @ N: U8 f% @ android:layout_alignRight="@+id/camera2"" ^8 \" y9 g3 ^. m/ ]
android:visibility="gone"4 i3 p% H% B2 S4 r) O
android:gravity="center" />7 Y% R: P- k j7 F6 |+ q* y
dji.ux.panel.SpeakerPanel
7 f3 N8 T+ @" n X8 F android:id="@+id/speaker_panel"
e0 K& R1 i( ]6 \3 J android:layout_width="300dp"7 ~# u6 R7 T5 }; L' e
android:layout_height="match_parent"
& a; a. j" t# x2 c0 E9 j android:layout_alignParentLeft="true"
/ v' T/ B3 f- p0 Q android:layout_below="@+id/signal"
4 T0 g% j1 d$ J android:visibility="gone"/ F2 X, v8 \2 P! y! z) T
android:gravity="center" />7 C; T1 E$ _9 P) o. T
RelativeLayout>- Z/ ^5 R( ], m" a; L+ u
@Layout(R.layout.activity_main)
5 V+ A5 c' Z' gpublic class MainActivity extends BaseActivity implements View.OnClickListener {
$ [$ \6 F! N6 w4 S( w @BindView(R.id.img_live)
" m3 h3 W4 Y% Y0 I' B0 B ImageView mImageViewLive;( d0 V1 t( Y! R! {" C1 u8 M
private MapWidget mapWidget;! b% c9 X% ]& v r- l
private DJIMap aMap;- i8 z% j6 L3 @2 w
private ViewGroup parentView;. J$ [6 S5 ?3 u6 f* h- n% P
private FPVWidget fpvWidget;. q" ^! f% U/ f: l5 L
private FPVWidget secondaryFPVWidget;
0 U! N: Q: r* r$ Y2 C1 r8 Y% W8 z private RelativeLayout primaryVideoView;
4 D6 i) f }' u' I9 V# j private FrameLayout secondaryVideoView;+ x6 f% Q: s5 u
private boolean isMapMini = true;
$ `' W" V7 M+ w6 } private String liveShowUrl = "";
' ]$ S3 ]9 s$ c$ y Y private int height;# w8 _$ h; ^ K
private int width;
6 ~& N. X, H6 m# E private int margin;
- O% m4 w j& r% \/ Q% {) |3 Q private int deviceWidth;
" w) e% h, w9 e S7 y private int deviceHeight;
3 O: V3 [4 g0 w( v. _( s+ B private SharedPreUtils mSharedPreUtils;
8 {3 W4 ^+ Q$ C- D, P! n. U0 ~3 o: C5 Q //unix时间戳( ~2 g2 J# A+ K
private String dateStr = "";% M8 N# r3 n0 [" `! i" R: |
//飞行器管理器& O4 x2 ~! I9 b0 x( Y% X: X
private FlightController controller;
" x" l! F/ v1 V( z- i //经纬度& o& u2 @4 G( `' V- b8 j
private double lat = 0, lon = 0;" h6 D" s& g2 W# l. g/ e' M& x0 I
//高度! X0 S" d+ ]' T! v/ \2 t/ f) @- }8 X
private float high = 0;# Z& o/ f* Y) d4 G( L8 ?
//飞机的姿态
# O- n# l* U8 S& W8 D private Attitude attitude;
4 f2 I1 A/ ]4 P' k* w* Q4 T //俯仰角、滚转、偏航值: o8 p+ J2 {5 ^+ i
private double pitch = 0, roll = 0, yaw = 0;
- h$ `1 F! M5 [- u. J //飞机的速度' o7 b% _2 E; g6 A
private float velocity_X = 0, velocity_Y = 0, velocity_Z = 0;, I4 i+ a/ i; a3 j- x; Q3 Q% q
//飞机/控制器电池管理器
, f# e! |+ s; D, E private Battery battery;
# |; b ?( M7 c' z3 v9 f7 e //电池电量、温度! K% q C- \/ O w U6 S& P8 l
private int power = 0;7 Z+ \' m+ b4 `9 q
private float temperature = 0;3 E; G( w6 T: `0 b9 h+ N
//云台管理器" j6 I% d+ }* @) Z s
private Gimbal gimbal;% F; ]) V& F% c0 q) Z1 O( c
//云台的姿态1 V+ i5 o: @/ w* \$ ?$ S$ l
private dji.common.gimbal.Attitude g_attitude;
9 l1 v4 ?0 ]" V' P/ S* r2 t //俯仰角、滚转、偏航值
! L1 y' S$ J5 l- @( \7 N. _ private double g_pitch = 0, g_roll = 0, g_yaw = 0;
$ X" i1 U# E3 j& }1 ~, k+ Z5 Y private Camera camera;+ Q* ~1 E/ U* G( j
private List lens = new ArrayList();/ h% ~/ i7 W7 R
private List djiList = new ArrayList();% v( h$ m8 w$ X+ B! z/ \
//手柄控制器
& Q2 E0 J& F- D, o' o* ?- j private HandheldController handheldController;& y: k5 C9 r$ m8 n
//手柄电量* Y- z N; f4 ?& { W' P7 y$ H
private int h_power = 0;; V# {# }5 R J3 x( B% L0 j; V1 ]( g
private static List list = new ArrayList();2 M2 q- ?/ {* O. J: W6 l
private static List getList = new ArrayList();
; \% m' ?" E8 |" C private MediaManager mMediaManager;
7 T* x0 x2 p. c5 |9 f# H; I) w private MediaManager.FileListState currentFileListState = MediaManager.FileListState.UNKNOWN;
2 I: [; F. H' s$ K$ j) K* d, ~ private List arrayList = new ArrayList();' ]2 W3 ?$ q x% n
private List startList = new ArrayList();
# S0 d7 i z5 a3 s private List endList = new ArrayList();2 {7 _: D" G7 U" @! _8 K
private boolean isStartLive = false;
, u6 M. v/ h+ y3 g5 v% x private boolean isFlying = false;
9 V: o5 X, d1 K1 D private boolean start = false;; ^/ F) U& J9 o/ X b
private BaseProduct mProduct;( t# k4 D) I3 H: u J- _
private String posName = "";
1 u. [( c3 c/ N //webSocket
9 _/ }' b/ F, d1 f% r private JWebSocketClient client;. `( }5 D3 T) b$ d) ^4 z
private Map params = new HashMap();
% y$ _9 n! z& p3 { Map mapData = new HashMap();, T O8 b# b2 N7 p" q) S: h: ^
@Override1 c; r: c" l( n3 z7 X
protected void onCreate(Bundle savedInstanceState) {8 f+ Z+ Q6 H/ F% G3 M' d3 D" k
super.onCreate(savedInstanceState);/ S& u% ~7 ?9 Q% V# M1 w8 \ [ f
height = ToolKit.dip2px(this, 100);0 `# ~7 ?( M! v! [/ }- m
width = ToolKit.dip2px(this, 150);. T, ?! w5 A0 c$ a2 _ T* [' d
margin = ToolKit.dip2px(this, 12);
' N1 F" E- z7 J WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
5 ^, C- @ f0 Z9 p final Display display = windowManager.getDefaultDisplay();
`7 R# I% }4 ~, E- J; i% w' G4 k Point outPoint = new Point();
' B7 Y3 E1 R9 k+ M display.getRealSize(outPoint);) q- c) u! [! f% p
deviceHeight = outPoint.y;: E, k L! t8 k0 \6 m
deviceWidth = outPoint.x;
9 G* _) v! b8 z ?8 ? parentView = (ViewGroup) findViewById(R.id.root_view);
" n0 x3 D; X) r) Y+ E fpvWidget = findViewById(R.id.fpv_widget);: v% J0 z3 x, q- Q- ?
fpvWidget.setOnClickListener(new View.OnClickListener() {- D& a* U- J; J) _: Z7 Z- R
@Override; J( a. v/ l4 Y! q# }9 p; n% K
public void onClick(View view) {
) U# u3 k+ B3 ` onViewClick(fpvWidget);' _0 S; K2 X% R0 S" T" m" ^
}- d U& w% V; U! R) K
});
t: I+ V6 n, j2 e primaryVideoView = (RelativeLayout) findViewById(R.id.fpv_container);
3 S0 `7 p; E X. ~& z secondaryVideoView = (FrameLayout) findViewById(R.id.secondary_video_view);/ D/ z: V- N* t8 P
secondaryFPVWidget = findViewById(R.id.secondary_fpv_widget);
( p% u+ @# }7 L1 a, K. ? secondaryFPVWidget.setOnClickListener(new View.OnClickListener() {; U: T2 E' a! a4 F7 w8 h
@Override
; |$ [- v; P( ]8 u2 Z public void onClick(View view) {) E: Q, Y, P1 [ b; C$ Y3 I
swapVideoSource();% [# o5 m8 ^0 B9 p2 |" J
}
, c, ~/ z( j8 c" z! n& ` });$ B8 U6 L& Z% ?) O" [$ Z
if (VideoFeeder.getInstance() != null) {3 F) N* ^. N* X5 q% @, ^
//If secondary video feed is already initialized, get video source# n) w# q% o. I7 X5 }3 g# q
updateSecondaryVideoVisibility(VideoFeeder.getInstance().getSecondaryVideoFeed().getVideoSource() != PhysicalSource.UNKNOWN);
2 f" |; o) f' k. D8 C4 W //If secondary video feed is not yet initialized, wait for active status
3 h5 Z% e# S* p VideoFeeder.getInstance().getSecondaryVideoFeed()
O$ E( @( x( `. x4 Y .addVideoActiveStatusListener(isActive ->. q; T/ D8 n( V- O+ ?; C) ^
runOnUiThread(() -> updateSecondaryVideoVisibility(isActive)));
% E/ k" b+ R/ I8 y$ [8 N }
2 \+ b i. j6 f7 X" x mSharedPreUtils = SharedPreUtils.getInStance(this);& X; Q; A2 R8 X; H" {3 U) `- I
this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
( p- \0 a7 P" q2 g! y$ g mapWidget = findViewById(R.id.map_widget);
7 M" B7 U: \. P5 s- d' D mapWidget.setFlightPathColor(Color.parseColor("#2fa8e7")); J9 S. o5 u. v! p- U$ l
mapWidget.setFlightPathWidth(15);
" B+ i9 C% L" J3 v mapWidget.setDirectionToHomeVisible(false);+ N T4 B+ {# c( J' z! b2 r
mapWidget.initAMap(new MapWidget.OnMapReadyListener() {, r+ e- I4 P; @; H
@Override
, o4 g" e% h$ s" ]( Q5 z public void onMapReady(@NonNull DJIMap djiMap) {
8 |* c" ]5 D! n+ N1 M djiMap.setOnMapClickListener(new DJIMap.OnMapClickListener() {
# L4 I- N& ^2 q$ @1 L @Override
- Z, W$ b0 `9 A# M/ d; E public void onMapClick(DJILatLng latLng) {
# g4 K. I. i+ h E1 y onViewClick(mapWidget);
2 O) I" A& \; L }
, L+ R' I& w! d# f1 E; L9 y( O8 t3 W7 i });
W* {9 d9 ~$ A; W djiMap.getUiSettings().setZoomControlsEnabled(false);
* ~$ ^; o. h' d+ C }5 _8 a3 D" a, b6 m* V
});, a* y& }% V) d# d
if (aMap == null) {" F6 Q/ t1 a, H& m( m
aMap = mapWidget.getMap();
- g) s/ m( `6 L0 X0 Q }
" z: ^% n1 i6 G' h6 | mapWidget.onCreate(savedInstanceState);- Z2 a. l% N1 ]7 \* T8 d z7 y
mProduct = ReceiverApplication.getProductInstance();
' l6 S. W* X' X8 ?7 O K9 b5 T if (null != mProduct && mProduct.isConnected()) {" q* H6 v' L& T* h
flyInformation(mProduct);8 x7 l7 N) g) B8 g. k& I5 }8 e# Z
batteryInformation(mProduct);
4 `" {4 r5 A: y, x9 w cameraInformation(mProduct);! E% e$ Q; K( @% Z$ k5 v8 r
camera(mProduct);2 a5 [4 B6 h- B. Q9 v
}0 w1 |+ ?$ G2 l$ }
Timer timer = new Timer();4 _* u4 u. C) y9 V+ O; t0 ~
timer.schedule(new TimerTask() {: B1 t3 R# M- @/ R9 D9 e
@Override
6 ^2 D: ?! Y: h& a- F j/ B- r public void run() {
1 F2 }( B* w" w+ I: s; O4 P9 G! A Message msg = new Message();* c/ l0 h% g4 I+ ]7 {/ U
if (isFlying && !start) {4 |4 f7 V' F: o/ v/ ?3 y
start = true;
' ^% j; g4 z, q
$ w6 R2 ~1 g. c6 `! @ + i. k! Z% B) f5 i& r: H& V
}& o5 n/ i: M X4 J8 m" P' [6 D
if (!isFlying && start) {& T- } [, y8 h' s) u# h
start = false;9 u- k+ l7 n! N' @
) Q5 v/ R* n2 z }3 J2 e
}2 Q# A5 C) J0 I- A/ l+ l# r0 L
if (isFlying && high >= 0) {
( d6 e0 O1 V2 s. T0 n u" b; o& S0 @ msg.what = 1;# G5 T+ ?2 N1 x4 y2 n: G
}& |; l g0 w( G2 }
mHandler.sendMessage(msg);
; B! v3 T/ V9 F' L }7 Z2 v2 q8 X0 x, |5 v, {8 {: e7 r
}, 200, 200);
& D$ y" m5 p* ?4 p) q, j; Y- { }
9 X; `( Y, z( Y5 ]: f; D1 i$ P Handler mHandler = new Handler() {$ S# `$ x7 a' q) }7 @$ ^/ a% g, [
@RequiresApi(api = Build.VERSION_CODES.O)* T U+ ~( a4 D( S
@Override
& h1 L+ D& _5 k6 e2 i public void handleMessage(@NonNull Message msg) {
& @, g& d7 g& f2 ^/ x switch (msg.what) {
* x; q; T; i4 a( f7 P" }" D case 1:- o: ^8 S9 m) \4 J5 Q0 ?, i: Z
Long time = System.currentTimeMillis();
2 d$ L5 g, N+ {$ @1 a' F// MyLog.d("时间:"+time);6 b: |6 m: e5 y
RecordModule module = new RecordModule(String.valueOf(projectId), String.valueOf(planeId),
0 J X( M6 a, r$ I$ Y trajectoryId, time, String.valueOf(lon), String.valueOf(lat),
9 m9 E" x( F, T$ i9 j: I1 @, w String.valueOf(high), String.valueOf(yaw), String.valueOf(pitch), String.valueOf(roll),- ~- P# s( ?" u5 h
String.valueOf(""), String.valueOf(velocity_X), String.valueOf(velocity_Y), E) Z! {" i# b& \: [ e
String.valueOf(velocity_Z), String.valueOf(g_yaw), String.valueOf(g_roll), String.valueOf(g_pitch));
! M4 q8 S$ O8 w; B/ W http.getHttp(INSERT_DATA, GsonUtil.GsonString(module));
4 _ q4 P9 }7 T( I3 p& h, b, S b break;
& ~% _. c6 X% y. d6 r" h2 | case 2:
1 @4 J; ~* x% O6 `( J" _ MyLog.d("飞机移动的数据:"+msg.obj.toString());
, M5 S# S" R, B$ D0 t4 _ ControlModule control = GsonUtil.GsonToBean(msg.obj.toString(),ControlModule.class);
% H+ h k3 w: f2 q- f if (controller!=null&&isFlying){
- V! N7 m# K/ z! D4 f' y if (control.getContent().isBack()){
- Z* q9 U9 W8 f& v. v4 N controller.sendVirtualStickFlightControlData(new FlightControlData(-10,0,0,0),null);
! p8 a7 n% P; x* w* E$ Q }' G8 H( N! u5 n1 j* X
if (control.getContent().isFront()){
7 {* }* K5 ~, I; J controller.sendVirtualStickFlightControlData(new FlightControlData(10,0,0,0),null);
) Z7 z& S) b* G" B$ ]: n }; k/ M0 z: v: x/ F" Q8 Z
if (control.getContent().isDown()){
3 `' @& ]+ _5 e$ D: ^ controller.sendVirtualStickFlightControlData(new FlightControlData(0,0,0,-4),null);
4 T( G+ @9 o- k9 @( k }
" o7 l3 n3 _1 W: [; M if (control.getContent().isUp()){8 F Z8 M) V# v2 u5 d
controller.sendVirtualStickFlightControlData(new FlightControlData(0,0,0,4),null);* {5 _, r) v+ X2 ?% C) m( {
}
4 a4 X) k+ h {7 y, p t4 Z if (control.getContent().isLeft()){0 }- R, {4 F; L9 \9 f
controller.sendVirtualStickFlightControlData(new FlightControlData(0,-10,0,0),null);7 Q* N0 c" V2 R5 W5 g/ z7 z+ S0 W
}2 F/ q( r! ` v- h6 y( p' o
if (control.getContent().isRight()){
* p3 B0 W1 T1 z, F: {+ v controller.sendVirtualStickFlightControlData(new FlightControlData(0,10,0,0),null);5 d1 @$ { F2 Y, G" ?5 t2 M
}
2 ]% _5 d1 F3 W9 Z* q }else {( D( ?& |3 D" T1 i# b
MyLog.d("controller控制器为空");
0 ?+ |+ H0 m K& r% a }
% E) n' G; \6 F1 e break;, \$ i) k: J( j
}
0 Y* ?1 t4 y3 G6 A f2 ~ }$ y" J( e1 i4 q7 p
}; G9 b7 B/ u1 N
@Override* f. F u: Q* P5 K
public void initViews() {6 Z+ {, k$ h$ [1 P% h0 \
mMediaManager = ReceiverApplication.getCameraInstance().getMediaManager();6 `1 r5 @$ M' b+ T: R6 u# `/ q
getFileList("start");
$ X* {7 x9 K/ V% W2 q+ W0 d }+ A+ W+ ~0 p9 t0 ~1 `
@Override" K+ _9 ]. H. \
public void onComplete(String url, String jsonStr) {
: Q9 F, `1 U a3 x9 ^ super.onComplete(url, jsonStr);# F% r/ J6 r6 _0 R, \8 r
; m8 w, V5 q, {% s. E4 I
}
. G& v/ Z% A. {3 j" ] ?( s% m! W% l @Override
+ C. e( `7 T' f# s; Y public void initDatas() {
/ ^7 t" h6 j# K }! X8 o; ?' O: v
private void onViewClick(View view) {# C W7 u3 z2 k0 v$ Y0 `
if (view == fpvWidget && !isMapMini) {. H) D ?+ L0 H0 [6 e& V
resizeFPVWidget(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT, 0, 0); E: |" i( [7 i$ a# U# R+ q( Q$ P
reorderCameraCapturePanel();
- r0 Q5 O' v4 e; p% g: n. r ResizeAnimation mapViewAnimation = new ResizeAnimation(mapWidget, deviceWidth, deviceHeight, width, height, margin);7 p! J( b$ r' i( R$ B. r
mapWidget.startAnimation(mapViewAnimation);
: V. }# G) x6 e isMapMini = true;4 k( R& L/ Z0 V, C& X$ c6 m
} else if (view == mapWidget && isMapMini) {
: N. Q& d/ q2 g6 C2 s, c4 i" M hidePanels();# b' _$ \$ k) f2 x
resizeFPVWidget(width, height, margin, 12);$ |0 e- B6 n0 M
reorderCameraCapturePanel(); j7 }/ s0 S! p; x. [( Q
ResizeAnimation mapViewAnimation = new ResizeAnimation(mapWidget, width, height, deviceWidth, deviceHeight, 0);
/ q o% A2 y% m, v" [% S mapWidget.startAnimation(mapViewAnimation);
, ^, S# C8 U4 H# a p4 c isMapMini = false;9 t: C% [+ N8 n1 H5 Z1 ]' o2 u
}
) B5 d1 l( a0 L5 l* K# g# p }
- W) r5 ^8 y3 }/ j- `4 N$ b1 s private void resizeFPVWidget(int width, int height, int margin, int fpvInsertPosition) {; X: L* N6 E" J6 N& _1 l/ s, @3 j
RelativeLayout.LayoutParams fpvParams = (RelativeLayout.LayoutParams) primaryVideoView.getLayoutParams();) g' k7 T# r; U H9 n
fpvParams.height = height;
! _& j( ~& ]5 K {; x5 M fpvParams.width = width;
4 m: h# K/ j6 {' |' N( ^3 o9 L fpvParams.rightMargin = margin;( p E) V1 A2 N
fpvParams.bottomMargin = margin;& U+ O8 N, b; w- ?
if (isMapMini) {
+ g* y" G7 L$ M3 c. e, T fpvParams.addRule(RelativeLayout.CENTER_IN_PARENT, 0);
; I" W& }$ e2 q ]7 }6 k fpvParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
% Z" m, l6 \/ U$ |' Q; o/ V fpvParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);' X- _+ Z. v) a, ?" j# t' l" y" o3 f
} else {
8 S6 b |* F6 ~* K9 I5 W fpvParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);- J% Y, Z2 S+ Z' B- _
fpvParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
' t( u+ _+ d a fpvParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
( P0 K: p s9 l' J& T }
8 E$ ]$ e+ P% F- s1 N) e. B& o primaryVideoView.setLayoutParams(fpvParams);
4 m9 R }$ v/ { parentView.removeView(primaryVideoView);; V6 E; n2 X' i7 m( H. L
parentView.addView(primaryVideoView, fpvInsertPosition);/ \# O% \2 ^8 u8 b& g
}: z5 M: e, G: Q( Q" T! P$ j" Y0 K
private void reorderCameraCapturePanel() {# F* p6 V* J! m! U% G! R
View cameraCapturePanel = findViewById(R.id.CameraCapturePanel);; G) ~) f @4 q5 w0 o3 g/ Q
parentView.removeView(cameraCapturePanel);
8 M( _" y6 v d( V6 X2 p- B4 I parentView.addView(cameraCapturePanel, isMapMini ? 9 : 13);
2 Y! _( B: a, E$ F5 r9 X) ` }
, S& s6 l5 ?) w! v: g1 J private void swapVideoSource() {
! Y2 t/ Y4 c/ p5 @* E if (secondaryFPVWidget.getVideoSource() == FPVWidget.VideoSource.SECONDARY) {' s% I. y: ~' E
fpvWidget.setVideoSource(FPVWidget.VideoSource.SECONDARY);
$ B6 p/ M3 ^: k2 c5 w# n* t secondaryFPVWidget.setVideoSource(FPVWidget.VideoSource.PRIMARY);2 q7 r+ Q- t/ U8 Z4 @7 x
} else {
# M/ C4 V J) {: D( {4 b- b8 u- O: z fpvWidget.setVideoSource(FPVWidget.VideoSource.PRIMARY);) @; k& R% I8 _$ A
secondaryFPVWidget.setVideoSource(FPVWidget.VideoSource.SECONDARY);
0 Y& x6 ], e' G- ?3 O. { }
( M# l( `/ Z7 ^* C& p' B }
1 Z) Q9 z# i7 T% _- Q3 S$ t$ O private void updateSecondaryVideoVisibility(boolean isActive) {
& K0 D1 u3 S [" g* v if (isActive) {- E: B+ V8 E; _% T$ T% T
secondaryVideoView.setVisibility(View.VISIBLE);
' Y8 O4 V. `- X8 j: E2 ^9 ? } else {' b/ C. x i* {$ ^. ^, {) v/ A
secondaryVideoView.setVisibility(View.GONE);
# z# \6 p; k: T8 D4 n }
! Q- g1 O7 Y. E$ W2 F8 M }9 v8 Z! i) T$ J' e# n: g
private void hidePanels() {8 O$ [ t6 @- s1 T2 u
//These panels appear based on keys from the drone itself.& X) Z5 j7 q. _' O7 U2 y1 P
if (KeyManager.getInstance() != null) {3 {( o) y* ]& O% S3 `& E
KeyManager.getInstance().setValue(CameraKey.create(CameraKey.HISTOGRAM_ENABLED), false, null);
) J; `+ s/ t) g0 m KeyManager.getInstance().setValue(CameraKey.create(CameraKey.COLOR_WAVEFORM_ENABLED), false, null);6 x8 a4 B: ?& q) M: A L
}
3 Z/ d U/ t- T) K //These panels have buttons that toggle them, so call the methods to make sure the button state is correct.
2 H- p% W8 |, g CameraControlsWidget controlsWidget = findViewById(R.id.CameraCapturePanel);; @7 A# L- n3 _2 ]$ h2 t
controlsWidget.setAdvancedPanelVisibility(false);5 J7 W4 j) o9 A
controlsWidget.setExposurePanelVisibility(false);! r* i6 f! b/ X1 f- B2 E! W( Z
//These panels don't have a button state, so we can just hide them.
, s& B% _* j2 j2 | findViewById(R.id.pre_flight_check_list).setVisibility(View.GONE);$ x! n2 A9 }4 |' q0 P
findViewById(R.id.rtk_panel).setVisibility(View.GONE);7 ]5 ^( y7 G$ b9 u6 {9 `! S! C
findViewById(R.id.spotlight_panel).setVisibility(View.GONE);
8 X6 @8 r9 l$ b2 I" N1 Y+ @# l. E findViewById(R.id.speaker_panel).setVisibility(View.GONE);
W$ h) j4 e# n! H }
5 [# k$ g) J$ j* i& {( p @Override9 G j0 A/ L# O, y
protected void onResume() {
+ d) K! i5 d; p/ w3 b% @- n super.onResume();% F. ]. e, C: v X$ o) ~ q$ c( ~( s
// Hide both the navigation bar and the status bar.' l" u' V2 m% F! v ~% Y
View decorView = getWindow().getDecorView();6 \# b, K$ B# b2 q
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
7 }# a2 V+ _/ V2 H | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
# F+ N7 z& N3 p; H" U5 g) S | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN+ B0 }& n0 q c: z
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION2 \, t' m# M. i$ R |8 v! S) _
| View.SYSTEM_UI_FLAG_FULLSCREEN
+ G1 c8 N+ G! H$ B, E4 { | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);. P+ b. q2 c+ z! R% X7 f) g
mapWidget.onResume();1 w. x! N8 I& z0 C" X
if (client == null) {
. x# @, K, l h2 N+ \' W& I, y- g MyLog.e("``````````````````````onResume"); p7 H$ C# Z3 Q, \! v) G
// initWebSocket();
: _& `0 N' l/ N( T3 I" X! z) ^, M } else if (!client.isOpen()) {1 |6 z: s7 H+ J4 P0 `2 D; q! S
reconnectWs();//进入页面发现断开开启重连, `5 ]5 V' b- l# F4 e
}
1 I9 S% t6 B, }% ~8 ^* Q }
4 e9 D. p8 i1 R @Override% F: P7 S }8 ], }/ E1 p* z, }* C
protected void onStop() {# X; u# ~* B9 ?; Z
super.onStop();4 D1 O& s3 N$ [/ v
MyLog.e("``````````````````````````````onStop");
0 V# z' n. _- E- f }3 [; L5 i( d8 M1 m# U8 C# V, @2 m
@Override
. G" S) [. a; O protected void onPause() {
$ S: z6 B6 d9 N" k! O mapWidget.onPause();
7 `9 U$ p! J5 e& W9 [; K% Y" D super.onPause();
) J8 i( P; @, |$ } e( W T }8 P( j' x5 N9 J. D
@Override, r6 r% O) U: r' t7 J# n
protected void onDestroy() {
$ s7 W' ^ s/ l# H+ Q b$ S mapWidget.onDestroy();/ x m- H* t: s: Y" E% r
super.onDestroy();8 j0 j' u* K t* n! x* p# h6 H
MyLog.e( "`````````````````````````onDestroy");
! \: \8 | }6 l2 g, \ closeConnect();. k3 v2 S# f$ t( F1 l7 O
}6 s6 H7 g! Y0 I# J2 P
@Override ]) R/ @% b2 _! ?: S9 h
protected void requestData() {
6 a: o- Y% f; p }
) R, [) D# o" l9 d% l2 s @Override
* w7 v' r# J: @5 C7 W, Y' w; P protected void onSaveInstanceState(Bundle outState) {
: T# ]: Q9 l, M4 }6 W* T2 n super.onSaveInstanceState(outState);
, T5 S% z5 u b# x9 J mapWidget.onSaveInstanceState(outState);! L1 }7 f, q# N' D, m" z2 g
}
, D7 A1 k$ h' l9 S& k% ]( H @Override+ J2 q9 L. }- |- O. x: L0 w0 Q3 g$ w8 ]; c
public void onLowMemory() {
5 s4 x R+ ?! `; R' f% s& u4 z. D super.onLowMemory();) T; `& m3 c3 ^( B
mapWidget.onLowMemory();
3 q/ m- w, D9 z* Q: m }
" [- j3 o8 p" N2 r+ t- G private class ResizeAnimation extends Animation {- D. v4 G2 ~" ~" v. {3 ^5 l
private View mView;3 I5 ] F/ i% j
private int mToHeight;
- T' _9 R+ I1 @/ k" ? private int mFromHeight;- H! ?8 B, x: K) D n D V
private int mToWidth;0 J- A# L7 p$ g% V
private int mFromWidth;0 c0 V& L% p# q3 X1 n
private int mMargin;1 e( l/ N$ j, V: `3 l* U
private ResizeAnimation(View v, int fromWidth, int fromHeight, int toWidth, int toHeight, int margin) {
6 u7 \0 i& K( b! a! S t6 [ mToHeight = toHeight;* @8 R; f3 y5 C" I# K: `
mToWidth = toWidth;
6 i1 i% B, P+ A; d6 Q& i- B mFromHeight = fromHeight;
% e+ L, g3 j# x mFromWidth = fromWidth;
6 M t- }" r" e& T mView = v;
. G9 ^. w. \. l J3 J) } mMargin = margin;6 r0 d) a# L, d, t1 A' i, |& `) E1 L
setDuration(300);
/ s5 p( I' R& z' ?0 D# t+ M8 V1 w }
. i3 ^/ t7 k( O! n" o @Override6 Z5 ]2 ]/ s% w
protected void applyTransformation(float interpolatedTime, Transformation t) {
2 ]* ?. ^+ ~, k2 e8 o float height = (mToHeight - mFromHeight) * interpolatedTime + mFromHeight;7 z. K6 a+ C+ e; Q
float width = (mToWidth - mFromWidth) * interpolatedTime + mFromWidth;" K+ @+ h; n7 h- @0 |( d
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) mView.getLayoutParams();. `" n2 ]: m# n1 ]: j6 ?) h
p.height = (int) height;" Y- v L) p d0 i5 k
p.width = (int) width;$ M1 R, M( Y# f1 X+ u) J; q' N
p.rightMargin = mMargin;; x9 }% _3 G) N* q$ L2 |. m% Q
p.bottomMargin = mMargin;
+ C% `, u9 k9 W( S- ^: T mView.requestLayout(); y5 W# ~6 v1 O! J9 E( f$ {/ I
}
' J' e P* y7 o }7 j; S! J( P* S: o& O
3 E6 X) x3 ~9 m! E- ~6 b
//直播流推送
4 p3 K# X ?4 x @RequiresApi(api = Build.VERSION_CODES.O)
h. z- G0 p, V/ K6 t @OnClick({R.id.img_live, R.id.img_show_back}). }. y+ \: Z8 k3 ^- \- Q& R) @ a
@Override
: L% c2 |0 A& D; ] public void onClick(View v) {8 x: A0 D7 _/ ?
switch (v.getId()) {- c( D4 B; r# F/ r
case R.id.img_live:
2 \0 R- s4 m j7 y& `) i, B( C params.clear();. b' m( j3 l( s4 W* b
mapData.clear();
$ S7 u) O+ P& ^4 N if (!isStartLive) {) V2 j% ]$ A% b$ ]8 h. @
if (!TextUtils.isEmpty(mSharedPreUtils.getStringSharePre("rtmp_url"))) {- x4 [7 [6 R7 C- ]3 [; o+ j% }
liveShowUrl = mSharedPreUtils.getStringSharePre("rtmp_url") + trajectoryId;$ d; M* O( q' |, G. M( W& T( I! E
// LiveModule module = new LiveModule("liveStreamStateChanged","plane",planeId,true,trajectoryId+"");0 x+ s- _1 Z8 }$ l; v% n6 w
MyLog.d("地址:"+liveShowUrl);
# G1 k" v7 k8 C' a* |! d/ E startLiveShow();+ \) I3 r! D F$ E! U
isStartLive = true;
; ~" P* I& q9 X2 Y showToast("开始推流");% ]4 G9 C0 P- x4 ^9 v6 Y( [% h( W4 y
} else {0 I) Y) y) B6 b& d0 q, e% M8 h4 _
showToast("请先进行系统设置(RTMP)。");0 A t! J% X. V! q
}) @3 i6 Y$ k: J8 {' v
} else {, X& W6 x+ d7 l' ]
stopLiveShow();
4 g9 E1 n* w4 u( B Z isStartLive = false;4 Z" l& g/ i) T* c$ w. X
}% ]0 |1 ]# i0 z
break;
% I, u0 n1 _) Z' E4 G case R.id.img_show_back:
, q! r% w% ^& s// controller = null; p/ c1 E, Z; E! r* E5 e
closeConnect();
) ]# @# p8 m" V9 C3 b5 T( } MainActivity.this.finish();! p3 S: \: o, ? p
break;3 S/ ^$ L5 J7 I$ C P, y7 H% @0 [
}
2 l% q1 a2 s8 {# |( l9 C7 C }3 {( K8 r6 f, r! `9 P
private boolean isLiveStreamManagerOn() {( m( y9 m4 M/ a' c
if (DJISDKManager.getInstance().getLiveStreamManager() == null) {; ^) ?( N% z7 p! N0 W
return false;
& \, l2 |) |/ @ b2 h }
5 E, G5 F, {3 m U3 t return true;+ i2 V1 R: A- I5 K5 d
}
7 x: ~. v `- Q* { private void startLiveShow() {
6 U, R% a+ h0 {1 ?4 P if (!isLiveStreamManagerOn()) {
* }$ Z* ~/ B& K2 I return;
2 s+ i7 H2 q2 G7 M' e) q }. i1 w7 Z9 Y" T2 v' N7 z+ i6 Q
if (DJISDKManager.getInstance().getLiveStreamManager().isStreaming()) {
3 }5 e& s& d' ~+ `4 K+ E return;' h" R M0 L) Z0 u" l3 ?# `
}% y. ~+ x. K; u+ z& S' y+ T9 [
new Thread() {
; O) x: r' M% W" T, i8 ~ @Override% p" m, b$ M2 K+ x+ t+ H3 e0 B
public void run() {
0 a0 M; @9 H6 F( Z/ W DJISDKManager.getInstance().getLiveStreamManager().setLiveUrl(liveShowUrl);
0 q5 N& X/ r' O G7 Q" { DJISDKManager.getInstance().getLiveStreamManager().setAudioStreamingEnabled(true);: D8 R! S7 f% \% Q" m" s
int result = DJISDKManager.getInstance().getLiveStreamManager().startStream();! o8 d2 ]& g( V$ s J8 D
DJISDKManager.getInstance().getLiveStreamManager().setStartTime();
0 Y! b8 U- e4 @) A$ P3 M* D }. \" R7 ~- D# b8 }
}.start();
! m- T! O6 d2 l9 q0 w& ?8 g6 ` }" U6 O- u% c$ a* n& l
private void stopLiveShow() {
2 D2 `# V5 o2 Z2 o, U; ^ AlertDialog.Builder Builder = new AlertDialog.Builder(MainActivity.this);
/ `8 `# A0 `" ^. ` Builder.setTitle("提示");# G, h9 ` `9 e% d, }; f6 H' H
Builder.setMessage("是否结束推流?");
" k9 T% A! q+ m7 c* h; b! O Builder.setIcon(android.R.drawable.ic_dialog_alert);3 I; b @" A; m* R" O: M
Builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {9 w n! l1 t6 G5 e8 B4 K
@Override
4 i3 {% `9 y4 k public void onClick(DialogInterface dialog, int which) {. |( V9 }( n: P; B
if (!isLiveStreamManagerOn()) {6 u& m3 |' T. \- O
return;4 t( u) O& t1 O0 i. X
}' c5 f/ s) F6 E; i- [8 Y" @8 Q
DJISDKManager.getInstance().getLiveStreamManager().stopStream();
& z( G* P4 u4 M showToast("结束推流");
9 N8 N4 ?$ a% v, R5 b" ~ }
. |% s7 z# x+ h7 S9 k- K });3 n2 i. W: F& l' A4 k
Builder.setNegativeButton("取消", null);
. L5 N9 h7 T3 X+ c. T' G8 ?& M Builder.show();
/ b& c1 m6 S: l0 s0 v }3 {5 ^8 u6 ?% B" X9 ?
" c9 Y) _; I; O$ ^- j" S c" H2 j4 x //获取飞机信息、云台信息
# w" \5 O4 z2 Z) d& @ protected BroadcastReceiver mReceiver = new BroadcastReceiver() {
3 t j9 O$ x' ^6 y5 H& l d @Override: ^5 L ^: O, `0 o
public void onReceive(Context context, Intent intent) {
& `8 M! G- C& f" ^1 W4 T/ p. b8 _ BaseProduct mProduct = ReceiverApplication.getProductInstance();& y) |0 y4 e( ~3 U( ?
if (null != mProduct && mProduct.isConnected()) {( j: S/ a1 w- V( L+ ]. s$ f
flyInformation(mProduct);2 j/ S% A0 l( t: u o, C
batteryInformation(mProduct);
* C( g) l; g% i | cameraInformation(mProduct);& w( z4 ?2 H0 i2 E9 C4 D" f
camera(mProduct);
; i+ b* \5 Z/ n8 H9 ]// MobileRemote(mProduct);1 o6 C' b$ a0 ]. L; _& S2 M
}
: @+ D& a' l- l" L }$ c0 l1 F7 R% C% W( A
};: I5 o3 x- r2 z6 C% y/ Y
// private void MobileRemote(BaseProduct mProduct) {: B6 ~* H" W: [
// if (null != mProduct && mProduct.isConnected()) {
6 X" M; e! T5 s// mobileController = ((Aircraft) mProduct).getMobileRemoteController();
9 `3 e- K' i0 M# {3 n4 p) g// }* H% C! ]7 n$ N# f" M' N
// }
9 E: i1 T* ~- d' L //获取飞机信息5 G! _1 b1 z1 D% B5 N! Z0 k
private void flyInformation(BaseProduct mProduct) {
: w4 T6 }, ?) U2 s if (null != mProduct && mProduct.isConnected()) {- s7 A# M0 |1 M4 t
controller = ((Aircraft) mProduct).getFlightController();
$ R8 F( I& d9 P! F; P, r }
$ G. z0 O% v8 c( u: w% N if (controller != null) {3 X$ ?) }2 I& `( C! ]
controller.setStateCallback(new FlightControllerState.Callback() {" P% r! w" C2 G( m5 t
@RequiresApi(api = Build.VERSION_CODES.O)/ t* ?. z! p4 H7 w9 D+ J, U/ ^
@Override
; y5 M, B: ]/ q' [ public void onUpdate(@NonNull FlightControllerState flightControllerState) {
# I: q% g9 i5 K, x _ //纬度、经度、高度、俯仰角、滚转、偏航值、速度
9 P6 g6 b0 I( w lat = flightControllerState.getAircraftLocation().getLatitude();* p5 w$ H" F# `. W" L
lon = flightControllerState.getAircraftLocation().getLongitude();- r4 L5 u( _ O8 C
high = flightControllerState.getAircraftLocation().getAltitude();
2 J: x8 l% g$ ~; r+ g5 e5 ]; d attitude = flightControllerState.getAttitude();0 w' I' Z; y1 s' h1 E
pitch = attitude.pitch;& B2 o4 f1 j# B: V( y
roll = attitude.roll;- C' f, G" x% S7 l% R) |
yaw = attitude.yaw;5 ^1 b ]. z/ u' w, f* T$ G
velocity_X = flightControllerState.getVelocityX();
0 I, }' D' U; e; z1 F( Z$ x* j velocity_Y = flightControllerState.getVelocityY();1 S* V7 j- Q) X5 |3 o. Y
velocity_Z = flightControllerState.getVelocityZ();2 D) U3 s( ]& ~% l% A7 P; o
isFlying = flightControllerState.isFlying();
8 i* [0 f2 z: F- x" v8 B // MyLog.d("经度:" + lat + ",纬度:" + lon + ",高度:" + high + ",角度:" + pitch + ",速度:" + velocity_X + "," + velocity_Y + "," + velocity_Z);& }2 v8 [9 |& M' X
}
k6 x' G) {7 _/ O! M });
. }5 J5 t; j, _ controller.setVirtualStickAdvancedModeEnabled(true);
& k8 e4 P$ N* @) c0 n- [/ S controller.setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY);
2 h. _3 N5 U: W0 W0 H controller.setVerticalControlMode(VerticalControlMode.VELOCITY);1 ]% t$ I# ?2 s2 C1 Q
controller.setRollPitchControlMode(RollPitchControlMode.VELOCITY);
# ^7 {) {+ M' H8 E2 z, ^5 C: A$ r8 _ controller.setYawControlMode(YawControlMode.ANGULAR_VELOCITY);
! m3 U: j) Y3 _// controller.setTerrainFollowModeEnabled(false, new CommonCallbacks.CompletionCallback() {
% B; y* ?7 D+ E. C// @Override
/ ^: [7 ^' Q7 P( @9 \// public void onResult(DJIError djiError) {! m# J/ m8 Z5 Q
// MyLog.d(djiError.getDescription());
$ p# w2 R7 \+ Q1 ~// }
# i) y7 N! t X$ h2 _// });
`9 g2 h( w0 m' x2 P2 N" u5 z6 v// controller.setTripodModeEnabled(false, new CommonCallbacks.CompletionCallback() {
4 t R8 c- B7 I( P" f2 \// @Override. g; D1 `' S) w( ]5 `
// public void onResult(DJIError djiError) {
7 }% Q2 H9 y; q// MyLog.d(djiError.getDescription());
/ u: G! [5 g5 P" R" _3 k// }
9 t' k+ N7 j) f: \// });
4 z. C- D! }1 c+ P; N// controller.setFlightOrientationMode(FlightOrientationMode.AIRCRAFT_HEADING, new CommonCallbacks.CompletionCallback() {4 [. Z! o& W, X" a) z
// @Override( J: C. M5 j6 w4 J/ C, y
// public void onResult(DJIError djiError) {# A2 J! L7 O% R$ } L
// MyLog.d(djiError.getDescription());
. X* K3 J- b% y4 z8 ~6 p// if (djiError==null){
' \: i2 x% V# Z: _// if (controller.isVirtualStickControlModeAvailable()){; E5 V" ] {% z, I
//
$ C9 A% e& b- p: e2 v$ `% c// }else {
# ?3 ^3 ^, r; v- ^// MyLog.d("虚拟摇杆模式不可用");
( Y( v6 m" |7 b+ J! [// }; M+ V' l: f# G4 }
// }
: L9 \4 f& y: S$ t G3 {) y% d; X// }6 Z7 I) S6 I/ P" s8 c% M
// });6 [. p7 S* P, z
}$ e8 g0 |2 q/ z5 H( `$ W, }/ G' {
}
7 e2 M- F# J! U. d //电池信息, o2 x; u" w% @. x% k" X8 o: Y. w
private void batteryInformation(BaseProduct mProduct) {
7 {3 d- p B& H! n, ` if (null != mProduct && mProduct.isConnected()) {
t2 T) X) l1 x" {8 B& s" }7 @ battery = ((Aircraft) mProduct).getBattery();
4 y& w, @' S4 k5 P! G/ Y& E, z }
4 t1 ?9 p5 Y/ Z; y' K if (battery != null) {
; Y6 W6 K# X% Q. v battery.setStateCallback(new BatteryState.Callback() {: F' S4 c" r7 ? _0 N. k- T" S
@Override
: g3 u4 W# o! G5 v* c1 m1 Q$ p public void onUpdate(BatteryState batteryState) {
* z9 m! }( H1 p! B/ [1 C //电池电量" `$ |% R5 Q Z: G& z
power = batteryState.getChargeRemainingInPercent();( ]* ?5 l$ o; u1 h( ]: {/ ~
//电池温度1 M& F) f: Z" Z, t7 p1 C$ M& z
temperature = batteryState.getTemperature();) ^* G$ L9 Z. w+ K: k1 f; L
}
+ d! ?$ n2 r( g- B9 F });
/ u+ N1 J) o$ t+ r9 Z7 Y H$ A" p }- E+ N/ U( i2 e2 L8 Q
}
/ ] ^) |6 c t4 V7 Q1 _/ _6 D //云台信息# X6 G9 B8 m$ i
private void cameraInformation(BaseProduct mProduct) {
; j& j ^/ ^. i/ p+ m3 ] if (null != mProduct && mProduct.isConnected()) {- ]% q7 h7 h7 A
gimbal = ((Aircraft) mProduct).getGimbal();
5 a! C- A4 Y, l- a, R7 t7 k }+ v$ Y0 d4 ?5 x) @
if (gimbal != null) {- A: d' ~7 x: ]. W1 j+ J
gimbal.setMode(GimbalMode.YAW_FOLLOW, null);
4 Q: G; ~* {# f& t" A6 f" h! Q gimbal.setStateCallback(new GimbalState.Callback() {7 H' c& O/ y1 W C0 Y
@Override# U% K" U b$ i. R6 f) b% H
public void onUpdate(@NonNull GimbalState gimbalState) {: S$ r0 v8 |0 i. V3 L9 a
//俯仰角、滚转、偏航值
% p1 A, i* @8 j! P0 V/ n# h, u- F: b g_attitude = gimbalState.getAttitudeInDegrees();/ c8 i* w) W t
g_pitch = g_attitude.getPitch();
6 n. A" r% U) d; S, o* k g_roll = g_attitude.getRoll();
5 c2 ? v) ~0 o& U: s! v$ T x$ _5 L g_yaw = g_attitude.getYaw();
0 \* }/ D3 t8 Y! Q. h7 Y& d; u4 g* c. E }# z7 V5 W& v6 x% N! f3 r
});
; m. q+ _# z, Y* _% e: } }/ s3 }! C5 v3 K7 f& {4 Z) [
}
, }) U' Z$ x: }% a4 L private void camera(BaseProduct mProduct) {( T' L; w, y3 D7 N! j e+ B
if (null != mProduct && mProduct.isConnected()) {+ C7 w f1 Q# [) K+ w/ _2 d5 c
camera = ((Aircraft) mProduct).getCamera();- r& d$ P& R4 T. H7 o
}
4 g" v1 b9 v; F4 @ if (camera != null) {9 C8 V+ a( A0 n. e* Z
// camera.setVideoCaptionEnabled(true, new CommonCallbacks.CompletionCallback() {3 Y S: ]6 X+ s% b1 }2 E4 J% h& w
// @Override
* S. Q* a- a- D) x; C( i // public void onResult(DJIError djiError) {
1 ]( Z+ X) F: q8 d& a // MyLog.d("VideoCaptionEnabled"+djiError.toString());
0 g( n9 B( G3 h) [7 _: ` // } t# a+ x3 r$ g' T( B
// });
$ s. `. t- o. F // camera.setMediaFileCustomInformation(projectId +","+trajectoryId, new CommonCallbacks.CompletionCallback() {" K* j- p' R6 l5 j
// @Override& j2 s& |- q1 i+ r2 n% }
// public void onResult(DJIError djiError) {
9 `5 d! N% ?/ K& o' K L; j! I8 g // MyLog.d("自定义信息:"+djiError.toString());+ m- B: g! w5 o# e4 O
// }
& w) y! l% y' q; b. j) x9 N' r" L // });
4 {( @" Z* q4 D1 ^ camera.setSystemStateCallback(new SystemState.Callback() {
( B9 J/ k7 i) {8 N) J @RequiresApi(api = Build.VERSION_CODES.O)! f0 R; A `: n+ C7 z- z1 `4 Z
@Override/ I9 n& a2 J" P/ f, A5 A/ Z- I
public void onUpdate(@NonNull SystemState systemState) {( G# n$ o. O: C# w# @3 W0 |
if (systemState.getMode().equals(SettingsDefinitions.CameraMode.SHOOT_PHOTO)) {* T: B" Z8 ]' |
if (systemState.isStoringPhoto()) {
4 Q, O2 v( K a. N" @7 f9 }3 A' ? dateStr = Long.toString(System.currentTimeMillis());* ?& e" R0 r9 p- Y. q9 G. a
list.add(new DeviceInfo(dateStr, lat, lon, high, pitch, roll, yaw, velocity_X, velocity_Y, velocity_Z, g_yaw, g_roll, g_pitch));! o9 \4 V, r. ?; r& k% A0 d. @
CsvWriter.getInstance(",", "UTF-8").writeDataToFile(list, FileUtil.checkDirPath(FLY_FILE_PATH + "/照片数据") + "/" + DateUtils.getCurrentDates() + ".csv");
1 V8 W! s9 t# @( _0 u list.clear();
" |( m- x/ W. G- b6 E; y return;( x6 |9 N: z( P9 p# m% \
}( G; m3 q5 \# J. A
} else if (systemState.getMode().equals(SettingsDefinitions.CameraMode.RECORD_VIDEO)) {
3 q' H0 N5 m1 f; }/ F' t6 O& U$ K if (systemState.isRecording()) {
, q8 l: |0 Q' B6 C, B try {# f* Y6 ~4 ~( G" k9 |
dateStr = Long.toString(System.currentTimeMillis());
Z v2 ?: u/ f6 u! g6 F: J- b list.add(new DeviceInfo(dateStr, lat, lon, high, pitch, roll, yaw, velocity_X, velocity_Y, velocity_Z, g_yaw, g_roll, g_pitch)); \& f5 G4 s& W: L4 O% C1 ^! h9 d
getList.add(dateStr);
+ w j2 r+ N |1 M! {7 y Thread.sleep(100);5 v+ S B. M% I$ d' F+ Y
} catch (InterruptedException e) {1 ^4 o W: t- r5 M. d4 q
e.printStackTrace();
. @- w& ~: n) o. M }- B* O0 M" c/ U M! Q, V
} else {
( }) D$ p# e& A( u E! I if (list.size() > 1) {
9 @5 @3 Z0 i/ q+ o posName = DateUtils.getCurrentDates() + ".csv";5 l; \' ]( Q7 F/ M8 k! b' ?
CsvWriter.getInstance(",", "UTF-8").writeDataToFile(list, FileUtil.checkDirPath(FLY_FILE_PATH + "/视频数据") + "/" + posName);
& z- U# O7 K. I% }3 A+ i list.clear();* h) s6 C, J# d9 ^ _3 f4 U, I8 n
runOnUiThread(new Runnable() {* z n: g C, j3 h
@Override" x; \, I4 m" _
public void run() {# Q/ d; ^$ k9 q9 m. t9 p
getFileList("end");
8 |* b" I$ b8 e% r# }) a0 G }+ z) W5 m# M7 b
});
* b0 C" d/ B& z }
5 E5 T+ q4 ?' @7 c }
( b* ^8 ^" }5 h, ]0 D" B }: S" T* h( }& c4 a8 T4 o: n
}* E t4 f3 m [6 ^8 q, j1 f
});* Y+ W$ S& r4 D; O! |
}
% n4 |5 I& ? X6 _% Z }
; v- T! C; `8 P5 }# t* v# ? //遥控器信息6 N* @, m* O, k3 H/ D
private void handheldInforamation(BaseProduct mProduct) {
: O' e5 K& F0 t% T if (null != mProduct && mProduct.isConnected()) {
# y3 f2 a+ V, w" l8 @! N$ X( E- @0 t handheldController = ((HandHeld) mProduct).getHandHeldController();
6 o, Y3 q7 ~4 W }1 W' a, E4 A Y
if (handheldController != null) {
1 c4 v# P5 S3 Q" x handheldController.setPowerModeCallback(new PowerMode.Callback() {/ c d5 ~5 F8 M) R4 X
@Override' ~2 ?! ^1 j) G- p5 q8 J2 s
public void onUpdate(PowerMode powerMode) {
2 @4 R# V- A" i$ M switch (powerMode) {( t8 x; L+ T) Y9 T y3 k4 c
case ON:
M; T9 g$ }6 c Battery battery = ((HandHeld) mProduct).getBattery();/ I+ y+ n* I6 R& H' v A
battery.setStateCallback(new BatteryState.Callback() {
. h5 n4 b& b- h" o# ]; G" O+ K" N @Override
. V& e ]& `$ G) k8 l) w% ^ public void onUpdate(BatteryState batteryState) {4 ]3 g- c% M3 _1 D2 ~
h_power = batteryState.getChargeRemainingInPercent();$ i2 _$ D, D) X
}* y3 h, @# @; @, r/ ~
});2 m' E) ^0 R$ j6 g
break;
2 Z1 C3 s* a/ V( l }
9 [/ f( S7 ^2 {3 A" e }
9 d3 _2 |' D/ B+ D6 Y; f });5 Q$ B) {; R0 I& |
}4 x4 Y+ L* b6 z, ~
}
1 t5 _7 \8 i4 Y2 | ~
) R7 r6 v6 Y1 d+ o @Override
9 w7 r; l5 [6 v" |' a! ^ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ p. ^0 C* q. s& p* T if (keyCode == KeyEvent.KEYCODE_BACK
& b/ d) h( M- J7 K* j && event.getAction() == KeyEvent.ACTION_DOWN) {) r, f$ j1 b" J( k8 e
// closeConnect();% c' T X u0 G# r$ V3 z0 R; z
MainActivity.this.finish();
$ d9 B5 `+ u% | }+ g$ ^ C- x% Q. I
return super.onKeyDown(keyCode, event);# g& r7 I+ Y" A9 u9 k# o
}* p; R7 ~% U. e; N9 R% a
}
, x+ q# R A! _. ]* A+ K. A: O完成后界面如下所示:
3 V& } r: I, _( y/ m O; Z6 f
sz1bbeuylep64015956024.jpg
; k$ ~+ ?" l1 ~1 ]+ D上面的工作完成后就可以在无人且宽阔的地方进行无人机飞行了。
. ], t& O9 l D" s" v4
( |6 `$ v# `* h+ c$ i' [多媒体资源的操作
0 K) T0 d; i& b6 X- k多媒体文件操作,主要为多媒体文件的获取、查看、删除、下载的操作* B. @# _3 y; i" [6 i. ^, I5 k% E
同样创建多媒体功能文件FileManagementActivity及activity_file_management.xml
1 Q3 e2 u0 ^) U& w% i$ _activity_file_management.xml
1 B! Y. M. p" WLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"& R* r: x7 @7 K/ d7 s
xmlns:tools="http://schemas.android.com/tools"
" ?& o4 c$ j: l! c" ^6 J$ r android:layout_width="match_parent"- Z3 t$ R( X: ^+ x0 c
android:layout_height="match_parent"" g; v, a$ l1 V( X9 K
xmlns:custom="http://schemas.android.com/apk/res-auto"
! x( j2 j+ q. @2 l tools:context=".ui.FileManagementActivity"2 x% _- e. f: E4 \7 m5 _2 d
android:orientation="vertical"
1 ~6 K% @: b0 s" s5 r" q9 d android:background="@drawable/shape_corner_eight">% d X0 n. @9 D1 r0 F0 x
include layout="@layout/activity_toolbar"
+ m6 h# S; Z) k, N& E$ E8 L android:id="@+id/layout_file">include>9 z% J4 W0 V0 D, e( ?. N$ ]
LinearLayout; ^* m4 h& ?3 {% |
android:layout_width="match_parent"
; ^, G1 H- M; Y# E android:layout_height="match_parent"
8 h; R7 u8 Q, y, M# b android:orientation="horizontal">
8 ?7 b1 O+ j5 ?9 ~5 X3 U LinearLayout
* ?( j* m* b3 t$ E android:layout_width="250dp"
6 }$ F3 V3 A9 m8 z android:layout_height="match_parent"
% l9 G7 y, Z0 K/ | android:orientation="vertical"! P! X) ]1 {( Q- |* v6 _, R
android:layout_marginLeft="15dp"
. F" b( E% U& M! v6 | android:layout_marginRight="15dp">) H4 O8 E Y5 ~6 q3 l3 q2 D* j
RadioGroup
3 D! d5 b! r8 l' Z) \. N* B android:id="@+id/rg_file_management"
; G A3 Q @3 ?7 F% B- D% K7 X' L android:layout_width="match_parent"" W9 H ]& ]! _# Z( L3 T! o
android:layout_height="40dp"4 z5 e) Q# ^) q- s* ~; q" c8 H
android:orientation="horizontal"
$ P" U8 w) ]4 V9 T android:background="#2B3141"
! H. @0 W4 [4 ~ android:gravity="center">, j+ y, m2 {0 Z
RadioButton
5 M" e8 M. H7 Y l5 z android:id="@+id/rb_file_all"0 @4 I w& T, N* v
android:layout_width="0dp"
% \ V1 o' z& ~' ?! Y( c android:layout_height="match_parent"
. {9 F( }9 A, P8 k android:layout_weight="1"1 b! r3 b" }8 ^
android:button="@null"$ M. X0 A- M, ^" ^, ]
android:checked="true"# T+ B, H" T# H$ {& {9 {5 S
android:gravity="center"9 u9 \. [7 v( u% C
android:text="全部"+ k, |' K) \5 f1 I5 T9 d
android:textColor="@drawable/nav_item_color_selector"7 e8 _; E0 l* }( L4 G
android:textSize="18sp"
- F1 O; h% c" z% x( o7 Y) E( ? tools:ignore="TouchTargetSizeCheck">RadioButton># l; t( y% M$ o0 |- |" r7 Q
RadioButton. Q2 i$ I- U0 s6 _) m
android:id="@+id/rb_file_photo": p* J f: Y x8 C
android:layout_width="0dp". m' K: @* {" a5 R9 [0 I+ o( j
android:layout_height="match_parent"2 u8 z" u+ _% d1 x6 x9 W, Q
android:layout_weight="1") D6 x! D+ t. U$ G: C$ p c. s
android:button="@null"
* J v2 ~' X, x- ?% M( r( I android:gravity="center"" Y! Y6 M b+ ?+ m
android:text="照片"
. x7 j. f u) Y android:textColor="@drawable/nav_item_color_selector"4 {- C V9 _8 K! ?; P
android:textSize="18sp"4 D9 e% n5 G, V
tools:ignore="TouchTargetSizeCheck">RadioButton>
, z; T: N4 Z7 g RadioButton
5 l( e& h5 D) G2 H0 S5 N' g android:id="@+id/rb_file_video"% `+ H4 K5 Y2 U ?: y* J% r% c' U
android:layout_width="0dp", i5 N& D# x- \! i% t& w& X
android:layout_height="match_parent"( O' Y+ T5 L' K2 J4 {/ R4 l
android:layout_weight="1"0 p$ T2 n- q% x, {/ ]3 ^& Z! F
android:button="@null"# Q8 ^1 g: b H+ e! X- h
android:gravity="center"" R: B0 P( k ~( o- s+ A, }& \0 H
android:text="视频"6 G5 [# g9 n* ` t' A0 {
android:textColor="@drawable/nav_item_color_selector"% n+ F/ n/ L: @8 l# H
android:textSize="18sp" G! g$ @5 u! W8 y. J8 Z
tools:ignore="TouchTargetSizeCheck">RadioButton>1 m: @' U5 Y* o9 c/ X1 f) D7 I7 @3 f
RadioGroup>
' `! r% a# @* n. g androidx.recyclerview.widget.RecyclerView+ s: }3 l& j& O/ g) R
android:id="@+id/rv_file_management"% S8 J- d: k$ b; T/ n
android:layout_width="match_parent"5 m' }& [! f# J+ T
android:layout_height="0dp"
+ [# e: j- h0 x; h0 H1 w android:layout_weight="1"
* j, z' K6 r) d6 n8 P, e* G android:layout_marginTop="10dp">androidx.recyclerview.widget.RecyclerView>
6 m2 u: \" s- w& o LinearLayout>
! S) Z/ W& `! u& b9 K% J RelativeLayout* o3 t% i) j1 p! a
android:layout_width="0dp"
5 m9 o% _5 R% B+ U) ~$ K android:layout_weight="2"1 J' U' s; D8 U3 D8 h; s
android:layout_height="match_parent">+ @' j" J+ X4 p% M" L' C" B
RelativeLayout
6 i0 @0 [: G+ F, [# Y android:layout_width="match_parent"
8 ]! ^5 L2 q& C android:layout_height="match_parent">1 i* v) s& A; B0 Z7 B- Z: Z
dji.ux.widget.FPVWidget
5 g2 J2 E9 h; S* }; N& G' k0 a android:id="@+id/FPVWidget"4 V7 a6 O) r- f: `7 H
android:layout_width="match_parent"( Z6 V, ^* m: t' _
android:layout_height="match_parent"
0 `. r1 v. }* E android:layout_centerInParent="true": X( A1 K1 A( q: [, i+ T
custom:sourceCameraNameVisibility="false" />3 E. F' G5 P- S- Q
RelativeLayout>" `" F7 s: {! L6 o; s
ImageView/ I& O6 a2 s7 z
android:id="@+id/img_show"! }& y/ @$ b, V) g) _9 c+ A
android:layout_width="match_parent": o L* S& b: q% r/ m; t
android:layout_height="match_parent"7 X$ e& r0 K h' q; k
android:scaleType="fitXY"
, e1 R6 [$ _4 w android:visibility="invisible">ImageView>
) O9 r& _( D% U4 b, P LinearLayout, J0 z" U$ V" A
android:id="@+id/ll_video_btn"- q/ u2 U1 o/ e' P; K, h$ P- k2 P1 F
android:layout_width="match_parent"7 k' z" n+ s- z6 y# p' b* b6 v
android:layout_height="50dp"
; x1 y( |, x+ M0 `) b, t android:orientation="horizontal"& F! |- Z, |. S5 ^
android:gravity="center"
8 ?% \# A) P0 X) h android:layout_marginBottom="15dp"9 v2 `4 a( H0 g4 [7 V! c |" F! i8 {
android:layout_alignParentBottom="true"
; J' ~8 e; Y9 T; Y android:visibility="gone">5 E- v9 F7 y3 [: C1 N" j0 l
ImageView
2 _$ s8 r4 s! l) c! W/ G android:id="@+id/img_video_pause"$ y2 `. i5 K7 h
android:layout_width="35dp"4 U* @& F' ]: R0 E
android:layout_height="35dp"
- A1 V. g% a) n0 P* _" \, Y C' H) A android:src="@drawable/background_stop_selector">ImageView>0 u6 a, p/ o1 W% m
ImageView! _, f8 x( t6 Z/ k$ R
android:id="@+id/img_video_play"$ l: g' U' g$ X/ K/ p& v
android:layout_width="45dp"
/ M! ]; V6 f! c* J J android:layout_height="45dp" H( _5 i$ [, l$ B) ~
android:layout_marginLeft="20dp"
+ g' M7 L: Z( a' R5 I' \" | android:src="@drawable/background_palyer_selector">ImageView>1 t- Q3 `( Y/ n2 {4 w
ImageView* k. Y) t/ c# N# Z+ }
android:id="@+id/img_video_stop"$ p9 a5 e3 H0 A2 ~+ N
android:layout_width="35dp"6 W y! i6 n6 F- A; F- b ~1 ` t
android:layout_height="35dp"' |% v! y7 K1 ~1 q: J! N3 `- I
android:layout_marginLeft="20dp"
; Y" ]1 }( T) L0 K, ?& H4 H android:src="@mipmap/ic_reset_36dp">ImageView>, N; B: e! }( Y, T1 `
LinearLayout>5 H" M* a7 q& `/ Q$ s
RelativeLayout>
3 h% e+ Y7 _( E8 b LinearLayout>
: N& e" o# P# h1 _6 a1 @; ~LinearLayout>. a1 D9 c7 J0 X5 S1 |
FileManagementActivity! `) Y* J5 i5 R( a6 K
@Layout(R.layout.activity_file_management)
& Z" \) ?" `: u! Rpublic class FileManagementActivity extends BaseActivity implements View.OnClickListener {. m4 ?: B' z& B$ \8 A8 ^
private static final String TAG = FileManagementActivity.class.getName();
3 K* k! u7 b1 i @BindView(R.id.layout_file)$ ?7 p j; l3 Z! \! x
View mViewLayoutToolbar; |9 p1 O, f7 M) G6 I* `
@BindView(R.id.tv_toolbar_title)
5 k, f: x, _" Z# y5 F3 E# y TextView mTextViewToolbarTitle;( a J# o3 t& c8 n2 {1 T7 z
@BindView(R.id.ll_file); ~% B* j; P1 w1 [% Q. d3 m2 q
LinearLayout mLinearLayout;
) O+ A/ R) w+ l: n" C @BindView(R.id.rg_file_management)5 n2 o. `' c" U6 J2 I
RadioGroup mRadioGroup;4 K: d W0 t) U1 T H
@BindView(R.id.rv_file_management)
. k: e, B, q1 e3 m' \ RecyclerView mRecyclerView;+ R2 s. _. c4 x8 X) Z
@BindView(R.id.img_show)
' j0 E2 Q0 d, b4 r7 ^1 s ImageView mImageView;
8 F3 Y8 @" W u6 ~2 b4 W7 _ @BindView(R.id.ll_video_btn)
, y) A; c6 }9 x) ]& J& ] LinearLayout mLinearLayoutVideo;7 y5 I: U9 V: x& `2 T* h& Y- \
@BindView(R.id.img_video_play)
2 ?: X" D9 B4 ]$ v ImageView mImageViewVideoPlay;
- J r1 G9 y3 [ @BindView(R.id.img_video_pause)
4 m3 e9 z1 |1 t B2 G/ W7 v/ d) C ImageView mImageViewVideoPause; Q7 |: ]. O5 A6 K
private FileListAdapter mListAdapter;$ O. o" Y; U! \7 S( b( E5 H
private List List = new ArrayList();0 A: m' u0 h9 v6 Z' d( }5 V* i* h, |
private List mediaFileList = new ArrayList();
! H6 U5 n# ]1 T/ ?7 ^& t private MediaManager mMediaManager;
7 I( T& P5 g# H, M: i private MediaManager.FileListState currentFileListState = MediaManager.FileListState.UNKNOWN;% E' l2 U6 g% \* l! }9 q x
private MediaManager.VideoPlaybackState state;; |3 M5 W8 V2 N" F" g" ^5 B
private ProgressDialog mLoadingDialog;! h4 p p, b( E% |; G3 j
private ProgressDialog mDownloadDialog;
# `% s+ o9 R! K4 J9 ] private FetchMediaTaskScheduler scheduler;
- S# u+ S2 B t' I) }8 ? private int lastClickViewIndex = -1;# ?+ M& W7 S6 N4 y; S
private int currentProgress = -1;' u6 ~! ~. J# T5 v, m
private String SavePath = "";
. @; W3 Q; R: B9 B( o8 ? private View lastClickView;
) |: l# j. S! Q2 f3 j private boolean isResume = false;+ n4 x D+ l; k
private SFTPUtils sftp;
l+ D% Z" }' W! n private SettingsDefinitions.StorageLocation storageLocation;
4 I: X6 C* }! c3 S7 i) `6 ~/ C8 K% b @Override7 M$ R+ U% r% {1 c* [! T
public void initViews() {% A* _0 ?$ `4 C9 j+ Q& n, _
mLinearLayout.setVisibility(View.VISIBLE);
9 Y# m; g5 ^+ j! [" m3 L mTextViewToolbarTitle.setText("文件管理");, P. E* a `$ Z8 r! b
mImageViewVideoPlay.setEnabled(true);
- S4 K8 e; u6 f' i* y/ H0 ~4 A mImageViewVideoPause.setEnabled(false);2 Q3 \7 r* R2 k$ k! D; W
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {& Q- N2 B# \0 ~. [. W
@Override
3 |: c' {4 z O) t public void onCheckedChanged(RadioGroup group, int checkedId) {. T1 ^1 E1 k. q3 k6 P" W
List.clear();% }2 g& x% K9 t" i- ^" O
mediaFileList.clear();9 U) j* U( D) ?" X2 u/ r
switch (checkedId) {4 B7 S' p/ h4 z5 U) F/ i' c& @
case R.id.rb_file_all:
. X) T' E4 w1 t getFileList(0);
8 W( |6 H" R6 g! v5 a mListAdapter.notifyDataSetChanged();
* R) f3 z! |" F break;; T( _. ?3 O$ s/ i0 _6 q
case R.id.rb_file_photo:
) h* E' @, `1 c0 ]/ Y2 q$ B getFileList(1);; {- [- t8 O- ^* j" g, T9 ?+ m
mListAdapter.notifyDataSetChanged();! S' }( L8 ]4 |' S$ d
break;
! @' y* z8 B( l1 c3 O case R.id.rb_file_video:
, _; T2 Q6 @( Q# }( a getFileList(2);
. {3 ~" k3 {6 i9 x0 f- h mListAdapter.notifyDataSetChanged();
- T& j. [- M7 v* R. t6 g: X+ B break;
; e6 y( _; ?1 e N# j; y& P8 j' ?$ O }8 P$ d& Z9 {9 y/ }6 a
}3 O; A+ b- u- Y
});
4 n5 m; o' [, G% ^" p LinearLayoutManager layoutManager = new LinearLayoutManager(FileManagementActivity.this, RecyclerView.VERTICAL, false);3 q: D P( \: I. ?+ t3 W
mRecyclerView.setLayoutManager(layoutManager);) @& {" Y1 v4 s4 k" \
//Init FileListAdapter
7 U; S7 x/ @ _. S' ? mListAdapter = new FileListAdapter();
/ E. v8 h6 H5 I" t0 M mRecyclerView.setAdapter(mListAdapter);5 x9 {9 {% A* ]& }9 i' Z
//Init Loading Dialog& @$ G- K6 o1 J( `% |% H2 r
mLoadingDialog = new ProgressDialog(FileManagementActivity.this);; C$ j: c9 o: I7 {6 s, K
mLoadingDialog.setMessage("请等待...");
7 s4 W' q5 e, V( l mLoadingDialog.setCanceledOnTouchOutside(false);/ D- n+ f2 t7 K; C; K' ^8 D
mLoadingDialog.setCancelable(false);
$ v* p3 j& A; t7 ^+ B //Init Download Dialog
" O; v3 \/ |* K5 s. f' Q/ E c mDownloadDialog = new ProgressDialog(FileManagementActivity.this);6 L) x" Q( N" j
mDownloadDialog.setTitle("下载中...");2 B" v0 @" n z T- G3 i
mDownloadDialog.setIcon(android.R.drawable.ic_dialog_info);
* g. S/ v& T3 @/ f; \ mDownloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
! O' c) T& f7 {, f5 M" {% a mDownloadDialog.setCanceledOnTouchOutside(false);* i" f+ v$ H. V/ J; K* e
mDownloadDialog.setCancelable(true);
4 R$ X! T/ ^5 l2 J& U, ^: d mDownloadDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
3 a& u* c% J( [3 {1 W$ H. l @Override' E j6 ^2 b) l7 j$ L" t
public void onCancel(DialogInterface dialog) {
Z& }+ B" `; R5 Y" a if (mMediaManager != null) {
, R) n2 Z2 h) \ mMediaManager.exitMediaDownloading();
0 R7 Y8 l. _0 b+ H* |5 h3 y% S }
/ r+ N5 T: G, \9 g6 T5 B' r2 n }
$ O4 y' }1 z4 V9 r Y) v });8 n# U0 s8 ~: M
sftp = new SFTPUtils("49.4.79.249","uav","uavHHch@YREC.cn");1 M" e* L+ z0 J; m
ReceiverApplication.getAircraftInstance().getCamera().setStorageStateCallBack(new StorageState.Callback() {7 f! t, V: X: ^- Z# \+ s7 Y
@Override; `) w$ ?0 [" _( q$ R A/ P+ e
public void onUpdate(@NonNull @NotNull StorageState storageState) {+ _: K( a! L; B% M
if(storageState.isInserted()) {
) ]3 a: ~1 c) n; i% N9 t y storageLocation = SettingsDefinitions.StorageLocation.SDCARD;1 c1 v/ l& [$ e+ u8 M6 `
ReceiverApplication.getAircraftInstance().getCamera().setStorageLocation(SettingsDefinitions.StorageLocation.SDCARD, new CommonCallbacks.CompletionCallback() {: h+ ~8 h6 s4 B4 z% p: v
@Override2 `, N) ?6 A) Q d; O+ u
public void onResult(DJIError djiError) {5 u9 V6 p" I$ G, H" a5 s. ?
}
7 U3 [0 x" Y" l6 [0 E _! x });
4 p9 q5 x$ V' l: l } else {
' o# c4 c, y% _2 B% y! { storageLocation = SettingsDefinitions.StorageLocation.INTERNAL_STORAGE;
% q2 `; Y1 A/ z7 P1 }# G ReceiverApplication.getAircraftInstance().getCamera().setStorageLocation(SettingsDefinitions.StorageLocation.INTERNAL_STORAGE, new CommonCallbacks.CompletionCallback() {
/ v# F2 v4 B: r; b( K5 p; ~ @Override
% u7 F% Q7 j. s& w public void onResult(DJIError djiError) {5 \4 q0 p& C% n# `8 y+ r/ \
}0 y7 d Y7 Z2 J6 T* i& H9 s. o7 E5 Z
});# w# R* p$ q0 K6 e4 l
}
5 x% g( }2 `% j# f* ]$ O. E% W }
( A% J5 }/ n1 C6 M3 p- M });' A, g6 h, O( U( V1 W7 H8 S! }! ~
} z8 j! T1 Q. [) V/ m" m- c
@Override
7 N7 ]$ f: o7 T& X, r public void initDatas() { z- |- c; r* Z
}
& U3 M M2 {: C! _# F: L1 b* A @Override) m: q9 R( u0 g w
protected void requestData() {
( G/ v9 B4 Q; Z5 Y, o" V" h }) {& \, Y0 E7 Q# `: N
@Override
3 g8 O+ [! B$ E* ^$ l n% R' |( O public void onComplete(String url, String jsonStr) {
2 @/ d3 i& S: [ super.onComplete(url, jsonStr);
$ ]2 Q8 d) Z8 p3 W9 C switch (url){( I+ S, x; L3 c9 O) M" m' i
case POST_VIDEO_INFO:; X, [3 g& a1 f3 W, R5 n8 j8 [# O
break;+ [& t6 J; O" u0 j
default:6 T; \+ @4 g& Q& K
getVideoJson(jsonStr);
8 Q/ F8 c! x( o$ @ break;
# S* o' T( r8 E, n! Y }
% P! Y$ N7 N$ O+ i% l9 `& C3 \ } e# N: y% M0 a
private void getVideoJson(String jsonStr) {# I2 m0 V) m% V6 x2 Z
VideoModule module = GsonUtil.GsonToBean(jsonStr,VideoModule.class);8 \3 b/ e. h7 M: W2 x( ~
if (module.getCode() == 200 && module.getRows().size() == 1){
$ _* c9 O; A$ c* ? runOnUiThread(new Runnable() {# k/ U6 F4 J! A2 _) `1 a
@Override: y+ g" R& N6 r: ?9 V
public void run() {
% o) h" |0 Y5 X8 V( S' A/ E UpdateFileModule fileModule = new UpdateFileModule(module.getRows().get(0).getId(),"/mnt/uavFtpFolder/"+module.getRows().get(0).getFileName());) {/ P- z+ C4 I- W- c- H
http.getHttp(POST_VIDEO_INFO,"PUT",GsonUtil.GsonString(fileModule));
8 `2 n( t6 W9 i7 d% y% X }
. r5 Y1 _# t7 k% B8 K0 t });
( J }1 u U0 o5 h9 S2 ~1 X }, b- o; o4 A" V
}
" z I# }! w+ b) ? @Override: l+ B; `* n2 |0 \
protected void onResume() {+ H1 g# t* I; {; e5 [0 I& v. E, {
super.onResume();; h6 z! f$ I# U
initMediaManager();. N2 C& x1 j& W ~! A5 L
}8 J/ L( C! w; Y0 e+ u3 ~8 j5 y
@Override
% U( \9 i1 e% P/ O/ _ protected void onPause() {. x# W) J( I; d9 B5 f& r
super.onPause();3 Y* S% ~, V$ q$ m& x
}
+ `; u* c& j! W5 P/ x, Y& i, Y3 r @Override
! g9 _4 _ D* T. F; s protected void onStop() {7 W" M8 E6 A3 Y) f
super.onStop();/ W$ g- z" ]1 j8 ~$ a- h( s
}
) [2 ]2 ?6 A& R# f+ H' F1 f2 T+ \1 C" W( s7 m: ~ E% |
@Override
/ c! Q, z! t f7 k% z protected void onDestroy() {
+ u$ L, L& ]! L$ E, \. i8 { lastClickView = null;7 U& | K4 C4 S' l& s$ @+ W: {
if (mMediaManager != null) {/ ?& R2 Q1 A) U
mMediaManager.stop(null);
7 E" |* J- P' q1 n4 `; p! Y mMediaManager.removeFileListStateCallback(this.updateFileListStateListener);
- A- w+ K1 B3 A0 L' H$ u Z) A' L2 y% j mMediaManager.exitMediaDownloading();
6 L( C1 }# N. f, q. I if (scheduler != null) {0 a9 {7 x1 x! h3 H7 _
scheduler.removeAllTasks();
& L3 S. \5 ^$ H5 V g }
5 M: I2 K+ O$ F: L' b3 d. L0 k3 N }2 P9 T! P5 ^4 e: w' C# k
if (isMavicAir2() || isM300()) {
- S# w, p6 z$ R, ~ if (ReceiverApplication.getCameraInstance() != null) {
, [& V& G; ?& {; j, A- V ReceiverApplication.getCameraInstance().exitPlayback(djiError -> {
: d8 L1 S; I9 W if (djiError != null) {
( P. I3 `! ^' ~. M3 @8 I# g ReceiverApplication.getCameraInstance().setFlatMode(SettingsDefinitions.FlatCameraMode.PHOTO_SINGLE, djiError1 -> { n) L; R4 C4 i9 ] V7 |
if (djiError1 != null) {0 F% J0 E+ ~" _9 {1 Z
showToasts("设置单张拍照模式失败. " + djiError1.getDescription());
9 @2 S# m b5 O: `8 y+ e) _ }( m2 h) T' n# ~* N
});, ^0 T& M% K' o8 U+ w% R0 W) ~
}- m3 c. X( d$ X5 ]6 r
});
$ Y6 n) o$ X3 J } else {% v, Q# `" G1 k/ c
ReceiverApplication.getCameraInstance().setMode(SettingsDefinitions.CameraMode.SHOOT_PHOTO, djiError -> {- [4 V% d( F" u+ Z7 G1 m! R
if (djiError != null) {
, c" e& u- M5 u7 D' X: G+ i) e showToasts("设置拍照模式失败. " + djiError.getDescription());% u6 |- {7 F0 @! B
}1 ?( F$ X: f2 W8 x
});1 C) @ ?5 C* h) {3 {' L% `% Z
}) X O8 l. P' K6 {- J$ J1 r# i
}* a. S5 h- s" `* t! C6 E- C
if (mediaFileList != null) {
% D0 d8 U8 g9 S9 T. W$ C) S // List.clear();" }- }: |# |$ G" P
mediaFileList.clear();. l! M1 U# j$ M/ n: g' B. i3 v1 h
}" h5 H6 Q% B$ z. K
super.onDestroy();/ k$ B$ o, P! H/ B+ L# s, `
}
- R- I, N# }! s0 B private void showProgressDialogs() {
' i) N: l$ |+ z& ~" v runOnUiThread(new Runnable() {
# b# X; ]; {9 K6 z8 l) @) j' q public void run() {+ I3 F% b9 p) l' y" ] S' H
if (mLoadingDialog != null) {1 R C: x7 n( ]
mLoadingDialog.show();* j6 P; ^9 X8 B2 e
}
7 m/ M5 d+ q( c/ _7 W) k( W }
+ r& c" i0 l2 o/ m5 S& G, B });& F- ]8 F- K$ \1 O
}- W3 E! g7 s/ B/ ? o
private void hideProgressDialog() {. K; \0 V; b# B6 |# V K& ~; }. H
runOnUiThread(new Runnable() {
; h7 z7 x. p& D public void run() {1 s6 L/ {9 X7 h- g. |& P
if (null != mLoadingDialog && mLoadingDialog.isShowing()) {
# J6 B1 _( K" C, A8 _, H mLoadingDialog.dismiss();( Y- x3 d; A- v8 {0 C
}
2 P' _! `) B# Z# _4 ]& j# U2 E }0 t4 o1 C2 |0 d1 S! s8 ]! z- ?
});% n! ~) _( l; C% p+ _
}) N; `0 a. x, n
private void ShowDownloadProgressDialog() {
# O0 w) ~ y; q& Q8 B8 v" c; ^" O, w if (mDownloadDialog != null) {* m$ V! K% U) W; s/ ^5 W
runOnUiThread(new Runnable() {
+ g! j: q* c `% x" A public void run() {
( I6 O4 q3 u! S6 _( t mDownloadDialog.incrementProgressBy(-mDownloadDialog.getProgress());
: s) f' |4 A% Z- q( o+ l mDownloadDialog.show();
) L9 m* A/ _8 H/ x6 R }
* [8 B* P8 f g6 o% Z/ v });
6 i h) X8 v% |% J3 K ] }
. d1 K4 A' y( M3 b9 Q4 a }3 q; P+ p2 T3 h. T
private void HideDownloadProgressDialog() {8 w* u9 O) [' b: k5 d, C8 c% [
if (null != mDownloadDialog && mDownloadDialog.isShowing()) {
6 w/ Z3 z5 |, |$ G& C- E; f5 S runOnUiThread(new Runnable() {! b4 F; e' T9 [- h S
public void run() {0 Z& g h+ p6 c
mDownloadDialog.dismiss();" w0 E- x. X. M9 o7 O0 d. q6 ]
}$ Y2 l) L% N6 u! r5 v
});+ g; p7 Q0 _8 J, d% s1 G
}. N; ]4 o+ V. }4 p0 G8 z4 g4 }
}
" M" M8 ?/ Y: N$ j; i2 O9 l private void initMediaManager() {5 k! j' v* s- {7 x- l0 H. f
if (ReceiverApplication.getProductInstance() == null) {
3 A8 Z2 {5 P7 {6 j4 j& z) Q3 y& m mediaFileList.clear();$ J5 k1 `) c1 d. h
mListAdapter.notifyDataSetChanged();6 n7 {5 b, Q+ Q3 o# q5 F) z# n; r' I
DJILog.e(TAG, "设备已断开");8 v% }& q0 B5 q9 i. g( R |
return;% C6 `4 i, d' F1 [% b. r/ ]
} else {6 w. i# q5 L& O& @0 ?+ [
if (null != ReceiverApplication.getCameraInstance() && ReceiverApplication.getCameraInstance().isMediaDownloadModeSupported()) {
2 o6 N, a0 L( W$ L: F0 H mMediaManager = ReceiverApplication.getCameraInstance().getMediaManager();5 Q% i" o& B9 ]. s" S
if (null != mMediaManager) {
4 U$ _6 M, z8 ^ R mMediaManager.addUpdateFileListStateListener(this.updateFileListStateListener);
+ F2 d! o" O3 I$ x- D# i* F4 O7 B mMediaManager.addMediaUpdatedVideoPlaybackStateListener(new MediaManager.VideoPlaybackStateListener() {
+ J# b% o( C' Z& [ @Override
4 i6 R1 I1 Y) o7 a9 G2 K6 \4 o6 i3 g public void onUpdate(MediaManager.VideoPlaybackState videoPlaybackState) {" W0 x, C. Z6 m
state = videoPlaybackState;* L, z1 R1 u) z: J4 `, K0 ?
if (videoPlaybackState.getPlaybackStatus() == MediaFile.VideoPlaybackStatus.STOPPED){0 ?; Y# N" c, D
runOnUiThread(new Runnable() {
8 L5 u* y/ n7 o0 Y6 Y2 u @Override! H, f, t0 J8 d5 }# V
public void run() {
" `- g3 i# l# i' c// mImageViewVideoPlay.setEnabled(true);6 `* P! a) M; L6 a! I/ Y
// mImageViewVideoPause.setEnabled(false);. q& m/ L7 R, _9 w) c; x
}
k$ t# m: e: p });
- S1 h" f. U7 H& N+ E }$ F" e9 r$ `4 A% l- n
}
3 P8 F' ~* g( }8 b }); X, _4 u" @. f! s
if (isMavicAir2() || isM300()) {
" l& _4 g) @2 c5 {6 {9 a+ [ ReceiverApplication.getCameraInstance().enterPlayback(djiError -> {+ W8 J* J" \* R
if (djiError == null) {% {* r: s! P& q# c2 \7 Z5 g$ ?
DJILog.e(TAG, "设置cameraMode成功");
' v: x* D+ I* d8 @ showProgressDialogs();3 F# `: c6 s- e. L
getFileList(0);
- X. \& O% t: d7 ^) n } else {
4 E: p( \7 R( A% ?. a0 Q showToasts("设置cameraMode失败");( F' U; I. g, V5 B
}
5 c0 u1 U4 b3 x$ |/ K/ u* c }); v2 ?8 [+ a- I/ Z: D
} else {3 j3 r3 j4 \' s( q
ReceiverApplication.getCameraInstance().setMode(SettingsDefinitions.CameraMode.MEDIA_DOWNLOAD, error -> {- X2 g" _2 C+ D' p4 s
if (error == null) {& v- C. D$ O; z c
DJILog.e(TAG, "设置cameraMode成功");
* }0 e: x8 Y3 m showProgressDialogs();
* J5 Y7 W+ V0 v( }: @" l0 m getFileList(0);. A- b! ^ z6 {& @/ p u p1 R) ?7 A2 |
} else {; e4 n; P( e$ o1 z9 Z/ i ~$ y
showToasts("设置cameraMode失败");6 o( [2 S& z6 o( g( H g9 s8 W
}- ~$ @# S6 S& P" s8 R5 ^; b
});
: o2 D; I, f, V- o }: y% z1 ^7 n% l' g
if (mMediaManager.isVideoPlaybackSupported()) {
& T* J: ?) i; N/ a; V DJILog.e(TAG, "摄像头支持视频播放!"); M2 n9 Z, K# M
} else {( v/ h7 V! X- h3 e
showToasts("摄像头不支持视频播放!");" Q, h+ m. R6 E
}4 }) s) [$ c! T! V3 M) R
scheduler = mMediaManager.getScheduler();. M- K x1 [5 W& {, E- d3 c% Y
}6 i. K* D h2 C, {7 Z; Q! c
} else if (null != ReceiverApplication.getCameraInstance()) A- K+ c! ^+ }
&& !ReceiverApplication.getCameraInstance().isMediaDownloadModeSupported()) {, R7 ]) ^; s! N- Z
showToasts("不支持媒体下载模式");
2 [( E+ z: |( W6 E' b" I6 y' K$ j4 J }* M9 m% J9 r! v. J6 p9 X7 e
}0 `' u- f1 F v; }* H9 N3 q) o, p
return;
8 f/ r5 c" {- E" y/ V, H1 \' Q }7 H. \& u" E) M
private void getFileList(int index) {
5 ]8 B9 S, s! H: c1 w& I- | mMediaManager = ReceiverApplication.getCameraInstance().getMediaManager();8 V6 T4 S# c$ g# _/ r
if (mMediaManager != null) {: N$ n H' y Y7 I7 G+ B
if ((currentFileListState == MediaManager.FileListState.SYNCING) || (currentFileListState == MediaManager.FileListState.DELETING)) {, v/ z& B3 I. g) W& Q( j8 d
DJILog.e(TAG, "媒体管理器正忙.");
4 z/ d" p: K$ H8 M: I& N } else {
K' E4 ]% D% B% y/ y mMediaManager.refreshFileListOfStorageLocation(storageLocation, djiError -> {# [2 O2 [* ^5 q7 T: X/ _
// mMediaManager.refreshFileListOfStorageLocation(SettingsDefinitions.StorageLocation.SDCARD, djiError -> {
( Y5 u2 z$ e" H) V5 y9 t if (null == djiError) {
) I- j; P$ s# z9 a, d# t hideProgressDialog();
+ ]7 N) d# l& U. k. v //Reset data0 M+ f4 }4 u& g
if (currentFileListState != MediaManager.FileListState.INCOMPLETE) {
6 y' O9 W$ E T p List.clear();
7 M+ k: z: N4 Q/ `6 H+ v mediaFileList.clear();
% x) t' `# l' p+ v+ y9 i$ B& v lastClickViewIndex = -1;
1 n- X# b6 t+ U3 j/ c$ \& @" W }8 K. _0 ~7 E: k3 T+ J' |* `3 {: G
// List = mMediaManager.getSDCardFileListSnapshot();1 p! H1 r8 C$ S& B
// List = mMediaManager.getInternalStorageFileListSnapshot();
1 ~" o1 n7 f# d- F8 q# A6 ? if (storageLocation == SettingsDefinitions.StorageLocation.SDCARD) {
( c8 `* y& y( z, j& i List = mMediaManager.getSDCardFileListSnapshot();
, ]% q d0 n: }& T3 B* C } else {$ G- M6 _9 V C$ K; S
List = mMediaManager.getInternalStorageFileListSnapshot();
* J* `$ K: n& w" s" u5 c }3 Q( }& T" z' I# |/ P7 N
switch (index) {
9 V9 D+ O% S. A, Y2 r7 C& b case 0:" u" o9 _1 @$ m/ T
for (int i = 0; i break;$ ?0 E+ v) D. y% \; n
case 1:
: R( i! q/ n" P3 V N) ^( I } for (int i = 0; i if (List.get(i).getMediaType() == MediaFile.MediaType.JPEG) {
* ]+ t+ U, | m; [& }6 c mediaFileList.add(List.get(i));
; Y3 m( B& b7 Y L1 m4 L MyLog.d("图片名称:"+List.get(i).getFileName());. X Q3 Z U3 b4 |- n0 Z7 Q
}
- q" q0 Y% {6 V7 ~# G }6 l4 }5 w2 t0 ]' y4 K! T! Q% x
break;
1 S; L( r l9 ?) G' Y case 2:
* D/ R$ R3 f, J4 x m1 ?' e! I for (int i = 0; i if ((List.get(i).getMediaType() == MediaFile.MediaType.MOV) || (List.get(i).getMediaType() == MediaFile.MediaType.MP4)) {
5 M9 ]6 }# [- b; _! Q mediaFileList.add(List.get(i));
+ e# d' S6 t/ P" J. X' x MyLog.d("视频名称:"+List.get(i).getFileName());( T, j1 N8 e9 r6 U, u
}
: D6 ^' V, S6 R d8 ?) u }
. i/ e6 N7 F) X9 ^ break;
8 o! p: O1 j! N# N5 \- ]3 M+ _ }& P4 r1 Y& M7 r: P, U+ O$ H
if (mediaFileList != null) {9 Z* ?+ s2 \8 P6 Y) e" Z8 ^
Collections.sort(mediaFileList, (lhs, rhs) -> {+ D0 @3 l0 j" p! x' |. F
if (lhs.getTimeCreated() return 1;, T! F. v' `! C+ n7 d1 @
} else if (lhs.getTimeCreated() > rhs.getTimeCreated()) {/ k# D+ S0 z# m0 T
return -1; i& @; M5 P# Y
}" s8 M- o- w) ]6 m
return 0;( @" _: Y; z! W
});
; n) ~' p- D3 k. T6 P9 | }
9 a% X" C- P- |( g2 Q: `6 T scheduler.resume(error -> {
. c& `; n6 R" G1 |$ |" o if (error == null) {
5 J; U0 d( R3 c+ e: V getThumbnails();) l; C3 i) S; U* Q( t6 P, Y
}
6 w$ S5 M: N) `: z& L% W3 M B });! G. s2 I1 w i3 e
} else {
( @9 n2 Y7 T# y$ a/ M* } hideProgressDialog();8 i# ^' `% n& c0 o
showToasts("获取媒体文件列表失败:" + djiError.getDescription());& J0 a% `2 g% w" p7 g7 g5 g5 B
}
- ]6 I8 g; r- v u });
. Z/ U5 }2 m) f# D }
) y$ R( G2 o+ ^8 n7 O: t }' O9 a* u8 t+ _/ b+ {% b6 p7 Y) a! d
}; y9 B0 n9 ]- ]* f, {% ?
private void getThumbnails() {- b/ [ B& i' k$ p3 z5 U
if (mediaFileList.size() 0) {
. E: v2 R* F8 e% J2 X& G! R5 ~ showToasts("没有用于下载缩略图的文件信息");* F% U6 z6 r+ G/ _% B& u2 x4 Z9 A
return;
^3 ?* x' K0 D; y }
+ \# F- a/ m" t for (int i = 0; i private FetchMediaTask.Callback taskCallback = new FetchMediaTask.Callback() {( r1 Z Y( t+ w5 f
@Override
9 ]1 g. N, x4 M$ n- \% m public void onUpdate(MediaFile file, FetchMediaTaskContent option, DJIError error) {2 C8 r9 K3 M: N
if (null == error) {
) S: H4 s9 W$ X$ ]7 X if (option == FetchMediaTaskContent.PREVIEW) {* @6 J( T' [, Y' e0 I2 m+ y
runOnUiThread(new Runnable() {
8 d* b1 C: A/ h% e2 n1 s public void run() {" H1 C" o! s% {+ Z$ ]2 ]
mListAdapter.notifyDataSetChanged();7 |$ m6 Y5 ^( t5 Q; \7 a7 C. b8 l
}
l7 f$ j: F5 @* g. V& v. z });8 q: J" _1 C$ C/ K
}1 ~4 d* _ [5 D
if (option == FetchMediaTaskContent.THUMBNAIL) {
8 @9 q" t# x+ y: S) h runOnUiThread(new Runnable() {7 b" o2 G4 {$ L# B; [$ o2 ?/ u
public void run() {: J' B6 j, _( S8 s
mListAdapter.notifyDataSetChanged();+ V. P, c, t$ g6 `
}
7 r L7 F2 w' b+ m: G });
3 b- C" Q/ E6 l/ S8 `% U. c }, F" |/ Y+ c; {: s2 s1 q$ I0 q
} else {
& A+ t4 K0 d1 h DJILog.e(TAG, "获取媒体任务失败" + error.getDescription());" K. B1 r5 C. p- s! |
}8 t# `1 j5 Y2 r7 R1 n
}
# x! M4 q+ H" q };# G, P K' }, A0 T; x2 D( @
private void getThumbnailByIndex(final int index) {3 x# W% k* a u8 |* B
FetchMediaTask task = new FetchMediaTask(mediaFileList.get(index), FetchMediaTaskContent.THUMBNAIL, taskCallback);
' p6 J) D" ^: M scheduler.moveTaskToEnd(task);
# h; K9 S+ }2 K0 M3 n }
: z+ `# l0 r1 {4 g- M8 V p, g class ItemHolder extends RecyclerView.ViewHolder {
8 |4 K! R# B' C- E$ c ImageView thumbnail_img;0 x" o0 P$ I: t; l: e
TextView file_name;
. G% V) p3 r! r3 U TextView file_type;" _. N' s, p7 j; h4 s/ N
TextView file_size;
. Y# c' Z2 }! l y/ m% g TextView file_time;
2 e( l+ v' v+ i7 h8 d public ItemHolder(View itemView) {6 @' w, m9 l2 {
super(itemView);
. s- f- v2 s9 S; j0 B3 I# o this.thumbnail_img = (ImageView) itemView.findViewById(R.id.filethumbnail);
4 r; e- [7 F# v0 [ this.file_name = (TextView) itemView.findViewById(R.id.filename);' l" u6 c, J: L* J# i+ d
this.file_type = (TextView) itemView.findViewById(R.id.filetype);
# h/ M9 ?7 `! k- Q9 F4 L this.file_size = (TextView) itemView.findViewById(R.id.fileSize);
$ @3 b' E" {. M& Z+ t* i4 }0 h this.file_time = (TextView) itemView.findViewById(R.id.filetime);- e1 @( R. j- f2 l
}
+ D7 R8 V6 }2 y! p- u: B) W1 X }$ k3 j! F6 E" L9 |3 q
private class FileListAdapter extends RecyclerView.AdapterItemHolder> {" R& V* \ Z4 p3 j+ M# b' i
@Override, j4 f4 B: G/ D% @: s; b1 X! `4 p0 Y" H
public int getItemcount() {
$ _ |( G4 o; D. T if (mediaFileList != null) {; k3 r6 Z% W, ]6 Z) @% K
return mediaFileList.size();3 d& G# T1 R1 f! f% O
}
' U6 ]( p' @/ h% {: ]1 `2 }6 G& M return 0;+ G# T! H" `4 b
}- h4 d/ G! b( R2 `3 r' s/ _
@Override6 H2 N, w/ q6 i& N' Q6 W2 U$ W6 u
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {: s3 Q0 i; u0 X- t: U" y
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.media_info_item, parent, false);
; D, m" p1 y9 [- z: {5 ] return new ItemHolder(view);
# F9 ?9 M* y* X }
, Q% E% M+ r5 D. U* y @Override$ U. u, ^% P! p; f/ k
public void onBindViewHolder(ItemHolder mItemHolder, final int index) {# }1 I. O& |' ^! V1 Y3 T2 M
final MediaFile mediaFile = mediaFileList.get(index);
* E5 H" V4 H; I+ f- Z6 ^1 j if (mediaFile != null) {
. v @: _4 o1 X/ H) R/ r9 j8 w if (mediaFile.getMediaType() != MediaFile.MediaType.MOV && mediaFile.getMediaType() != MediaFile.MediaType.MP4) {* k( f% a3 P; z- C1 `9 D+ J
mItemHolder.file_time.setVisibility(View.GONE);
7 f; |# E" s& x4 c, D( | } else {
2 \- c; _9 M* x3 b" K mItemHolder.file_time.setVisibility(View.VISIBLE);
. B* ], K8 i; \+ @3 R mItemHolder.file_time.setText(mediaFile.getDurationInSeconds() + " s");- e; g. {. u1 K
}
f3 O, z6 J$ w; e# J mItemHolder.file_name.setText(mediaFile.getFileName());
# f- }( A/ M6 {3 @& s3 B mItemHolder.file_type.setText(mediaFile.getMediaType().name());$ ^5 p5 @/ q( L, Y6 C) l
mItemHolder.file_size.setText(String.format("%.2f", (double) (mediaFile.getFileSize() / 1048576d)) + " MB");4 m; T4 {. }& n. b4 k# C' W3 ?
mItemHolder.thumbnail_img.setImageBitmap(mediaFile.getThumbnail());
4 y/ e# ?8 I7 e' U, X2 E" k; d mItemHolder.thumbnail_img.setTag(mediaFile);' v2 R, e5 J7 ] H ~! E
mItemHolder.itemView.setTag(index);/ N2 q7 d1 J c' P( u" D
if (lastClickViewIndex == index) {
- [4 j6 w( j/ {6 g' S0 \ mItemHolder.itemView.setSelected(true);9 p8 q6 C* y/ W! Y. O- Y& t
} else {
# M$ r9 a3 S, d2 N- E3 A! c mItemHolder.itemView.setSelected(false);
3 x( T1 z9 r2 W- S" J+ S4 Y } M3 f# c* o! g( g: o3 W! E& l$ H. _
mItemHolder.itemView.setOnClickListener(itemViewOnClickListener);
( B+ s9 ]0 b& q9 I& o6 u }
0 \4 J* P7 j( \/ p T( E }3 |0 O+ A& B$ x' u1 k! {
}& ~, \2 G$ Z/ w8 o
private View.OnClickListener itemViewOnClickListener = new View.OnClickListener() {
# h' d; |, G! p. r3 {, T @Override
# T& L: k* Z* w' v public void onClick(View v) {
8 [. q. c) q- k2 [5 Y7 g/ l# l, z lastClickViewIndex = (int) (v.getTag());
; [; z' D$ q& ^ if (lastClickView != null && lastClickView != v) {# E5 p) y6 J/ q
lastClickView.setSelected(false);9 Y2 D e1 _' q1 @0 O
}
0 Q/ B( i" X% V: w; X& j* } v.setSelected(true);
" K. P/ A% x: D8 P, a5 o1 S lastClickView = v;% S9 ?/ w# G/ V0 @6 ]* G
MediaFile selectedMedia = mediaFileList.get(lastClickViewIndex);
( ?" ]* L) }( d8 F' S; J) e if (selectedMedia != null && mMediaManager != null) {
" V& G8 _2 I3 y6 b addMediaTask(selectedMedia);3 _+ S6 f* T5 _+ {: D! ~! U1 u/ y
}
0 m1 m" r& G& R5 K p, d7 Q }
^) C8 \0 E- Y% Y };
* q% n1 R+ F# O0 M% e5 S private void addMediaTask(final MediaFile mediaFile) {
: m; [5 J5 g- N, y( w final FetchMediaTaskScheduler scheduler = mMediaManager.getScheduler();
( k. d) u( l3 M& C) d4 }* `& S final FetchMediaTask task =1 _, C* i7 M1 O- b
new FetchMediaTask(mediaFile, FetchMediaTaskContent.PREVIEW, new FetchMediaTask.Callback() {
- j1 M- ~* h0 D$ |) j G @Override3 W6 q d3 @! J) _ P# R7 a. X
public void onUpdate(final MediaFile mediaFile, FetchMediaTaskContent fetchMediaTaskContent, DJIError error) {2 U; N7 r) v: D' _ p
if (null == error) {
2 t, b) z2 Q. H if (mediaFile.getPreview() != null) {1 }% U' h0 j x1 r |
runOnUiThread(new Runnable() {
" o3 A' S0 J) j T5 K1 S @Override
4 B f( J7 w( i* w public void run() {
9 {, ?1 i2 B9 m- |/ X. ^ final Bitmap previewBitmap = mediaFile.getPreview();+ Y% p; o+ @" k& X- H2 |9 b1 N
mImageView.setVisibility(View.VISIBLE);
' d' v2 H* Y* y& d/ [ mImageView.setImageBitmap(previewBitmap); X1 [3 O. j! [/ T* f
if (mediaFile.getMediaType() == MediaFile.MediaType.MP4){1 z8 h8 z7 X2 l$ M3 \
mLinearLayoutVideo.setVisibility(View.VISIBLE);! r5 e) ?2 \4 J' }; ^
}else {
; L* x3 M" P" v' |, F mLinearLayoutVideo.setVisibility(View.GONE);
5 n/ u& x% p* r8 Q }' ]* ~& W& C! K
}0 A+ ?0 V; E* B
});
) Y. M6 u4 q% r2 _ } else {$ y. H: X4 u- O3 w# u0 Q. {& r
showToasts("没有图像bitmap!");2 d: [( o! `( Q! j7 L- z
}. H z# T$ }! u7 o& E" @
} else {- M* ]6 X: w# w
showToasts("查找图像内容失败: " + error.getDescription());4 |6 Q) J5 W4 i9 r7 L5 x
}
/ r5 M' f) r. w4 o* V) d4 |# Q0 J }$ u/ N( M) |4 d D6 O5 f
});
# ], d: U5 F7 }% U# x scheduler.resume(error -> {
5 t' v2 h* \- b0 E, K5 f/ ^$ { if (error == null) {
' Y7 ~" N/ A4 _+ N1 @' C1 n scheduler.moveTaskToNext(task);
, ~, N( r6 G' u9 P- \1 N$ o } else {6 O& h9 b' V3 B& P0 j- B" _) z
showToasts("恢复计划程序失败: " + error.getDescription());
) W9 n6 Y$ O4 v/ n. \8 ? }! V( ]9 U" g: u) K8 j
});0 u, g0 X8 `8 W
}
. @& @5 s2 C( e! y2 y. e( ~" _ //Listeners- I, G5 b: V5 }4 K; \
private MediaManager.FileListStateListener updateFileListStateListener = state -> currentFileListState = state;5 N* k2 A, e8 w1 d: ?% z
) \6 M+ [, q6 Q" \: y
private void deleteFileByIndex(final int index) {; R2 R# N; I- x, b3 u+ b0 l! q3 i
ArrayList fileToDelete = new ArrayList();% Q+ Y( h* N% t
if (mediaFileList.size() > index) {
+ X1 l# f+ d" |* z1 [% G' T/ u fileToDelete.add(mediaFileList.get(index));+ p: A$ c" [: u# r x9 s
mMediaManager.deleteFiles(fileToDelete, new CommonCallbacks.CompletionCallbackWithTwoParam, DJICameraError>() {$ z$ h' c% o' ^- Z$ p! B
@Override) ~1 i7 l/ A; J5 E# N
public void onSuccess(List x, DJICameraError y) {
3 `" B8 k9 ?* u# M; O DJILog.e(TAG, "Delete file success");
* t* \; |7 X6 F8 G runOnUiThread(new Runnable() {
+ M+ ]" c# h1 _/ k9 l$ ~5 p8 z6 j3 f public void run() {
! r$ C$ t' t: D: h7 S mediaFileList.remove(index);
. X3 M1 X; w6 _) B& v //Reset select view) }- @9 M+ H9 g: g8 j e5 S& I
lastClickViewIndex = -1;- [) w! U7 H) y% E
lastClickView = null;' H$ Y3 d( _( {: q5 \
//Update recyclerView H( m3 S; x- L; C6 s3 I
mListAdapter.notifyDataSetChanged();
. X: U8 y" @% I$ c( V) h* Q3 f }
1 y) S8 A5 \ D$ J3 U });- }( T$ S$ k/ e+ r* q( L. `
}
" d, H* Z7 {3 t& o* a1 u7 K! c @Override5 m& }0 V- N- n: I' @0 G, z+ p6 s$ H
public void onFailure(DJIError error) {/ W' }/ Z. Z, ~8 C4 A7 M$ d
showToasts("删除失败");
7 u' z) {) W% P }
; \8 a7 D' T& h. m7 m });
4 y( A5 v `9 N$ `2 y }
M! ]6 K% ~9 R. F6 ^& z }
: h* j A0 r [: a9 ^7 w, \ private void downloadFileByIndex(final int index) {
$ j+ N3 @6 E. I' I9 A; S if ((mediaFileList.get(index).getMediaType() == MediaFile.MediaType.PANORAMA)
A" u- g$ N1 W, R( ?9 j || (mediaFileList.get(index).getMediaType() == MediaFile.MediaType.SHALLOW_FOCUS)) {
k6 w) q3 T0 }' R2 l return;
, M: G3 m6 B- A: e( I }
1 l% g& w0 ~3 @' l if ((mediaFileList.get(index).getMediaType() == MediaFile.MediaType.MOV) || (mediaFileList.get(index).getMediaType() == MediaFile.MediaType.MP4)) {
9 r" U* l7 x+ u1 _! {3 O SavePath = MyStatic.FLY_FILE_VIDEO;
. E+ D: j( t# S1 u( I( T' U2 e/ X } else if (mediaFileList.get(index).getMediaType() == MediaFile.MediaType.JPEG) { X# x# U" ?& {: m! r
SavePath = MyStatic.FLY_FILE_PHOTO;2 O6 ]4 p& T# C
}, t" V( l/ h) F( j
File destDir = new File(FileUtil.checkDirPath(SavePath));
, d) P- P- T) Y# Z: R% v" q mediaFileList.get(index).fetchFileData(destDir,null, new DownloadListener() {
' a1 x! D [) I3 x @Override# T4 F! l+ n( h2 b8 v
public void onFailure(DJIError error) {( K4 O8 J' ?2 Y( V6 H
HideDownloadProgressDialog();
3 j: c# Q9 j* y7 N showToasts("下载失败" + error.getDescription());. t1 o R$ I) Z' ?
currentProgress = -1;1 `/ O8 Y5 C, K7 X
}
# \( I( T9 g+ W! Y( ? @Override# e3 U5 y5 w i z0 }) T
public void onProgress(long total, long current) {: ?7 W( b2 n* ]! H7 y/ \: `$ t1 r
}
% E4 v3 d7 a8 c8 l5 t9 P @Override1 ?7 _+ j; w; t% x! [8 I
public void onRateUpdate(long total, long current, long persize) {
. o& ]4 G2 R$ L1 @6 I% I int tmpProgress = (int) (1.0 * current / total * 100);* X& s1 K$ g# N. _
if (tmpProgress != currentProgress) {) C# G3 p5 f- c; b, _) X
mDownloadDialog.setProgress(tmpProgress);% o) _( X% X5 a, r# r4 C5 G
currentProgress = tmpProgress; I# D2 _) r5 y7 b7 ~
}! g( j# | X1 [0 o8 y3 F. M. }* y
}
, e" K6 F' b) L" S @Override/ [( ]3 y! R% W G, D! `( W$ f: M
public void onRealtimeDataUpdate(byte[] bytes, long l, boolean b) {' a5 K* U; j# t3 ?* t6 O
}
0 p6 _+ @ `/ N* H! { @Override
! T& q" E- y* S0 U, y& r$ B2 y public void onStart() {
! Z* P& m: ?; V2 V: I8 x currentProgress = -1;
) \9 W+ C* A# r8 c' g9 [ E ShowDownloadProgressDialog();
{$ Z; c8 u4 U4 `% r# @ }2 p( ^. B8 b$ I' p% {
@Override! W0 p) F) c: e# ]) m8 b
public void onSuccess(String filePath) {+ I) [0 M4 g; H
HideDownloadProgressDialog();
+ s: a3 ]5 H( M( J8 s showToasts("下载成功" + ":" + filePath);! e4 H7 O1 V+ A
currentProgress = -1;
/ ?/ c, i, ?$ G- I& v9 | }
6 t4 y" a6 e6 x+ Q });" o7 w1 g6 M0 w6 V- e
// mediaFileList.get(index).fetchFileByteData(0, new DownloadListener() {' I4 b8 E, t) A# |) J- ~
// @Override
, J4 V- l3 K) N) X' C P$ Y// public void onStart() {8 J" V. r" m/ a* z/ q+ Y B- h$ V
// currentProgress = -1;
0 n1 d5 x* c7 C9 M9 }// ShowDownloadProgressDialog();$ k1 B! H8 ?- k" M! Y( K
// }, {) p# p* E! {0 E
//* j, Z/ N( R6 ~( t) j
// @Override
6 J/ z( P1 ^% _7 _ N M ~( ^// public void onRateUpdate(long total, long current, long persize) {
" U0 p. o. o( |// int tmpProgress = (int) (1.0 * current / total * 100);$ b) C+ [8 G+ }
// if (tmpProgress != currentProgress) {( @2 }, D. \0 S' v8 U4 g2 F1 O
// mDownloadDialog.setProgress(tmpProgress);) P- m! V" }3 E* p2 r: Y
// currentProgress = tmpProgress;( \9 x* o- y8 j1 w* d. I# C
// }
; i- P% F, Q i( ?0 H J6 v: K2 Y// }
; f* \, }1 U/ L. ]8 h- y# ^//1 R; ]& H/ ?- u8 ~/ f) @" Z. V
// @Override- b. |6 G6 Y6 z
// public void onRealtimeDataUpdate(byte[] bytes, long l, boolean b) {# @2 n1 r5 K" [( x6 D
// byteToFile(bytes, FileUtil.checkDirPath(SavePath)+mediaFileList.get(index).getFileName());2 ?. S+ f1 V% n; |2 a. @+ n
// }" K" m2 ~1 ` m' P$ @/ {! ?
//
% K; f9 M, G; w- e// @Override
% r$ P* \& k% B4 U4 C' a9 Z// public void onProgress(long l, long l1) {9 W! R) N( P# p2 {" c
//
; M: z% I0 [1 f& O V# s9 w! R// }
* w3 O: X! _# {//
( C7 J! E& x q// @Override) _/ T$ I6 p) r" w2 n9 e
// public void onSuccess(String s) {
1 H( c$ f+ F+ Q$ W G0 l6 o* ]5 l// HideDownloadProgressDialog();* g1 r8 I) F7 d* O8 N4 I
// showToasts("下载成功" + ":" + s);
% a0 s' n: x# `3 h4 i1 h// currentProgress = -1;
8 {, p# l( ]2 V" Y8 r// }/ O- |# ?5 U. ~8 G
//
( X( A: }3 _8 J( L" ~8 W& u// @Override: L1 ~: r, {- l$ L- U* L7 Q$ x
// public void onFailure(DJIError djiError) {
1 c: q$ U% x1 P% e) X" y0 ?# \$ T//. {4 H8 i# S7 @6 y8 I5 Z
// }
5 n# P$ v3 q7 u& T0 [// });$ G1 p8 b/ s9 r7 w# N: j
}
- B4 [+ c9 l. V1 h public static void byteToFile(byte[] bytes, String path)( v/ [4 ~+ u6 T e
{9 t5 l6 b* K! o2 Y( w ` ^
try
) J( J! A8 I6 ]* c* | {
2 c& D3 y: M5 W6 H5 f( l* ] // 根据绝对路径初始化文件
) |7 ?& d1 e* ?6 U( Q& o$ j" |5 N$ ` File localFile = new File(path);
Z. A' S3 I) t if (!localFile.exists())9 Z$ |+ c7 L2 P; V/ s
{
+ o' I; z+ I4 T- \ localFile.createNewFile();. B3 ?8 ~, x# \8 Y% u
}
- N1 j% Q1 _5 y% A- e. Y+ ^ // 输出流 Z8 V, X: s4 M
OutputStream os = new FileOutputStream(localFile);
. a7 ~! z+ R! B+ B os.write(bytes);. y& k" p9 |: _5 R
os.close();
: K: O$ a; C* X! z }- Z( f% A; P7 M; f1 g. r
catch (Exception e)
' h7 H9 r9 U2 u7 R( ]! j7 O% s# @7 {+ Y {$ t. a0 B1 k5 I2 T) K' L) W
e.printStackTrace();
' k5 ?8 ~' w# i: Y! \0 ~' O- _ }
% ^0 h# ?+ K+ Y9 ` }
' A0 {' [6 S% B8 t; R, R private void playVideo() {
! O1 d1 f2 x1 N& F* F% n2 P mImageView.setVisibility(View.INVISIBLE);1 q' o" [$ A7 R4 w
MediaFile selectedMediaFile = mediaFileList.get(lastClickViewIndex);4 M7 H1 M* U- {! ?; ]& V
if ((selectedMediaFile.getMediaType() == MediaFile.MediaType.MOV) || (selectedMediaFile.getMediaType() == MediaFile.MediaType.MP4)) {5 F; @( S% }# H+ S0 f, q0 m
mMediaManager.playVideoMediaFile(selectedMediaFile, error -> {
; L. b& v0 \* A8 ^2 \7 E0 Y0 p0 E6 v if (null != error) {- [5 J" Q2 r9 |1 ^5 ]
showToasts("播放失败 " + error.getDescription());
0 q$ a/ ~, h9 W$ y# Z; @ } else {2 Q, B, m2 N7 U/ A' W! K3 Q
DJILog.e(TAG, "播放成功");, I5 y& Z! Q4 c/ F$ |; P
runOnUiThread(new Runnable() {# I `; S' b6 P) Y) F$ \2 ~, T
@Override
7 G5 L, V: U4 D7 S$ _ public void run() {
* T+ X M z4 F/ V mImageViewVideoPlay.setEnabled(false);
# B+ n& r; ]1 n% h5 \ mImageViewVideoPause.setEnabled(true);
/ i# J5 h* [7 P0 b }
( O% G. @% s( ?- J });- b+ \: H# K) p! i4 F
}) Z) ^8 _1 e9 d! M
});
, N8 @1 U: r6 G4 e }
& k( V; Q" t% \" R5 d# \5 q }9 y& U( E7 x- M) y, B
@OnClick({R.id.img_back, R.id.img_delete, R.id.img_download, R.id.img_upload, R.id.img_video_play,& }8 P* j$ u$ J8 g$ N, e! P
R.id.img_video_pause, R.id.img_video_stop})
3 l* K1 C4 H2 X( C9 ^" L. G" r @Override+ r; k/ L6 Q9 v& Q4 g
public void onClick(View v) {0 X6 |( {1 a+ ?3 E" E
switch (v.getId()) {
y, }$ V5 q* ?; q$ i case R.id.img_back:* a$ f% \1 L/ ]1 w
FileManagementActivity.this.finish();' [; Q. i% Y' T% H
break;; \4 Y; h% g( _6 f0 S
case R.id.img_delete:
' u; Y9 U0 G; b# i) H/ Y if (lastClickViewIndex >= 0) {
' ^3 U* J2 l" m deleteFileByIndex(lastClickViewIndex);
' V3 L& V9 Y* W! Y } else {- Z9 M! Y6 U6 i% Z5 f2 [/ |
showToasts("请先选择文件。");
- H) b# I% P7 k2 R% @( W }
9 k5 Z6 d1 P4 [; |9 @3 ~9 t break;
6 B$ `4 W7 D6 M) y% Q0 ?) V, u" I: H+ B- l case R.id.img_download:
3 r0 F+ W) r! G5 ]9 R if (lastClickViewIndex >= 0) {
, F% E7 t; Y4 I, _" T downloadFileByIndex(lastClickViewIndex);3 H9 j/ L6 v6 ` {3 v- f" s0 |
} else {
9 F! A9 K) v1 h4 H0 g showToasts("请先选择文件。");, T$ s9 x/ F4 ]. x6 C$ U: _
}
6 s9 b5 A( s4 ~1 b# o# t+ m ]5 r8 z break;
$ N' P- ? m( c& P( |, }+ ]$ Q4 u case R.id.img_upload:+ p# I" `6 \8 r4 L! }7 w
if (lastClickViewIndex >= 0) {
! I. r! E' B& V) l uploadFileByIndex(lastClickViewIndex);
3 L) o# Z0 s ~- q, v } else {+ m- S {4 q& b' V
showToasts("请先选择文件。");! v( w. L9 g: p0 x6 e4 n+ Y [
}
+ ?* C$ f, [, B8 n \7 o break;
$ J! p3 z% p7 ^ case R.id.img_video_play:
, i( v0 c3 t, _+ X5 t if (state.getPlaybackStatus() == MediaFile.VideoPlaybackStatus.STOPPED){
9 [# |; Q- Z8 O2 u% ] playVideo();5 B- O) J- U; S. j
}else if (state.getPlaybackStatus() == MediaFile.VideoPlaybackStatus.PAUSED){+ w" w w$ F* H) Q
mMediaManager.resume(error -> {& }7 \+ l8 _# }) t
if (null != error) {
2 |4 _& u! H, a5 X# {" ~. I showToasts("继续播放失败:" + error.getDescription());) w* l4 z3 H: ~
} else {+ U5 }8 C3 J' \/ ?3 b# j+ E0 K; M
DJILog.e(TAG, "继续播放成功");1 ^5 @8 g# V. @6 ~+ \ m
runOnUiThread(new Runnable() {8 A* B. F) [4 g h
@Override
8 ?2 {; D- L: X" @5 u# D( S public void run() {9 I# R9 Y& P! V
mImageViewVideoPlay.setEnabled(false);
: Q% c9 b+ `; k- u6 J, w mImageViewVideoPause.setEnabled(true);
9 e( X9 p5 |" I4 }5 V/ X- I }# q, X, g) g$ _' h
});
$ ?5 {; ]* {4 M$ G4 S7 s* N; X! j }
- v, _, z- Z" N* [ });& n; F4 p) F" c1 \2 d
}
8 k8 p' U l, `1 F( A) d$ H7 ` break;
6 t% C! F# w5 Y7 a; g N1 p; O case R.id.img_video_pause:1 a! s8 b4 q6 [7 [
mMediaManager.pause(error -> {9 \& w0 D$ x' Y8 N; ?0 u) u
if (null != error) {
* o+ j( {' |* Z, c( e8 y [4 B showToasts("暂停播放失败:" + error.getDescription());# B5 \. H5 P2 o+ T) X( i% i5 a' z
} else {
$ X. f4 l6 P* x& V, E. c! v DJILog.e(TAG, "暂停播放成功");
! m: B. [8 S$ t1 `" P& U _ runOnUiThread(new Runnable() {; L0 B' {; \$ k( c4 S3 n& b
@Override+ O% R4 a* a3 @3 _- W* j
public void run() {+ i* `) G5 a/ B2 |* V" d
mImageViewVideoPlay.setEnabled(true);
0 x: U( r" y- `( V0 t, i mImageViewVideoPause.setEnabled(false);
: ?! Q+ I8 m. Y; t }: g* h0 [# o* F% W% s% u, m2 ?
});) e# u! K; k; }% X0 |5 v
}# Q4 J2 ]1 o/ U" o2 s( K2 f
});; p( J, S, \& H F( W- b" P* R. {. M
break;
& g1 P$ G I( L9 r* l$ i; Y case R.id.img_video_stop:
/ U/ P$ C" h& ?5 K" L/ ]9 J mMediaManager.stop(error -> {
" s( R6 K$ j5 u6 Z- m if (null != error) {
8 E/ R! W9 n* r3 O showToasts("停止播放失败:" + error.getDescription());" `* n3 |1 E5 ^# [# _+ J
} else {: g8 {) C \$ b7 K
DJILog.e(TAG, "停止播放成功");) C8 u& z+ w$ ~
}
( E( x' @ l0 C* [+ g+ G });' e' x0 g' }6 J; X6 q( v, q2 |
break;6 E3 u4 p R3 {% d1 C4 z! x- F
}% Y! w$ p' f* B: m+ e/ \7 t8 L$ J
}$ v/ T+ t( E* K4 k/ C
private void uploadFileByIndex(int index) {7 }; H; C* ~. Q/ n. W1 S, o
if ((mediaFileList.get(index).getMediaType() == MediaFile.MediaType.MOV) || (mediaFileList.get(index).getMediaType() == MediaFile.MediaType.MP4)) {
/ q. S7 s+ _8 R+ G showProgressDialog("正在上传");
# P4 j+ p# A1 \4 z new Thread(new Runnable() {
+ ]: c+ u' D. h8 q, p @Override% h3 E6 e9 L' r# m
public void run() {
: }0 L+ p4 A7 M5 s# Y, j( L boolean isConnect = sftp.connect().isConnected();) j: w# O! d# [. O
if (isConnect){
3 H7 }8 i& s( Q, g" i8 ~ boolean isUpdate = sftp.uploadFile("/mnt/uavFtpFolder/",mediaFileList.get(index).getFileName(), FLY_FILE_VIDEO, mediaFileList.get(index).getFileName());) U5 p! j- Z$ Q1 w/ K1 y1 k
if (isUpdate){
& D' |, j3 r% h runOnUiThread(new Runnable() {
* c E; C% t t0 U) q0 `, X @Override. w2 H% H7 A: W5 P
public void run() { b8 A( L9 Q1 i/ L1 E/ U/ T
removeProgressDialog();
% f; U( Y4 q# Y& X http.getHttp(GET_VIDEO_INFO+"?fileName="+mediaFileList.get(index).getFileName(),"GET"); X8 t4 l* z" `
}
) H9 Z$ M( c' k( G4 P });5 g8 f' k m, y2 s: Y& O# O
sftp.disconnect();
8 m. y3 t) ]% E2 v' {. s }else {" y: X- |+ D: ? w
runOnUiThread(new Runnable() {( s3 J- b' @) y9 n' Z, S; J
@Override
) q3 t2 f7 c# f+ d public void run() {4 l7 l. y1 O# J
showErrorTip("上传失败");& c% Z% y9 s" A1 \" B5 r9 L# F
removeProgressDialog();9 {5 u. O; L% O5 [* x& }. U9 j
}7 N8 ~! u; D: n1 _" n& Z
});9 a0 j! i* V4 t- f+ R3 l$ k2 ?3 q8 k( |
}4 t. x, l) J0 }# R8 C8 u/ s; N
}else {" f# d2 w+ ]3 y) u+ s1 P5 I& [
runOnUiThread(new Runnable() {' ~. D2 U$ m3 ]# q
@Override
8 A0 T, [ p. G: y1 [ public void run() {
8 s- u0 \/ \) q9 D: i showErrorTip("服务器连接失败");
7 D9 _6 P' {" @' K5 J% ? removeProgressDialog();
. ]$ [0 H' j/ Y }
5 a j B2 W& |8 ~" H }); j5 D) K, x, n, J8 |% E6 R( G
}
3 K4 w2 b K4 a- Y; I } }3 j; o; T; \% Y' J' K
}).start();0 B, A2 {# f4 f
}else {
u! u5 z7 f: |2 [' t% b showToasts("当前仅支持视频上传,请选择视频文件!");5 A! ]6 G7 E2 E T+ }' t+ Z
}* T) {: v- X& q' h& V
}
# y# [7 \( O7 W! `* }7 D8 L private boolean isMavicAir2() {* ` L1 d6 s: W* A& f* _9 y
BaseProduct baseProduct = ReceiverApplication.getProductInstance();
: \ ~6 ?. m: r* u if (baseProduct != null) {
2 g' t2 o5 j9 a+ K( a return baseProduct.getModel() == Model.MAVIC_AIR_2;" _) R! C+ ]* z) a+ b6 R5 j
}
* i" {4 `3 A9 {0 {+ ?- |9 ~ return false;
. C2 {* h0 ^3 X& _9 O }) J2 u# j* J6 M% f. j5 D1 u
private boolean isM300() {
; f: N7 B% ~$ |6 v9 P& E BaseProduct baseProduct = ReceiverApplication.getProductInstance();
: `0 T& ^- ?$ \ if (baseProduct != null) {
# ?3 z0 c5 y3 v7 `; v+ g return baseProduct.getModel() == Model.MATRICE_300_RTK;
. [% z. o B. K }9 m! q1 L9 w1 Z8 i
return false;
, {, H$ k+ f' A! _7 S6 O5 s( t }
2 w' J& R& N5 V# ~ H}
' n% Q' `- e, d4 i5 x( n- z运行后界面如下:) o8 ~4 V) K" m4 E/ G
splrzdloa3i64015956124.jpg
# U k4 u+ K8 v D, U: |
: h8 ]- j& ^/ D
szmxbq0ilqc64015956224.png
& O& t, N7 B {% `9 x F' c往期推荐LabVIEW OCR 实现车牌识别
$ I) S" z6 e- S" j; o和12岁小同志搞创客开发:有意思的激光切割技术' H; C0 J7 c9 K1 J
JavaScript+TensorFlow.js让你在视频中瞬间消失
, U; k9 ~5 {) X# \' l使用OpenCV测量图像中物体之间的距离+ ?2 z5 b8 \+ J' R2 I
全网仅此一篇:工业级压力传感器设计及实现 J7 Q- ]- m5 ?# p' a/ c* F7 G
6 X- v6 l% C8 _6 N+ V$ n
libqpzwnv4k64015956324.jpg
6 r, V$ y% k9 D2 E( Q$ {
eaw5giox2vj64015956424.gif
6 x5 D- ~8 @$ X: n0 k5 `
点击阅读原文,更精彩~ |
|