|

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