|

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