|

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