|

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