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