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