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