|

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