|

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