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