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