|
r0eq1se0iio64015952610.gif
- s1 E @' ]6 q6 B+ e/ ^点击上方蓝色字体,关注我们3 ?) W9 T4 W9 k+ _5 b/ |
+ t$ B! t- s( X- J- u
- K+ [/ P1 N7 e S, J2 X+ _9 R
第三篇文章准备单独拿出来写,因为在大疆为人机的所有功能中,航线规划的功能最为复杂,也相当的繁琐,这里需要说仔细一点,可能会将代码进行多步分解。
& L2 w/ H4 ~- W2 x1
( J3 R4 e+ }- |' I航线规划7 ~& {$ F+ ^& P$ I+ x
航线打点 ! l4 {: s4 p4 v' l
* S5 {8 { S1 }
在地图中手动选择点位选择完成航线打点;若打点位置错了可进行点位删除。
- | t, f. k& @/ U O, i. G
pmpwl4ljnnw64015952710.png
! d* Q' p ]2 E4 m8 b2 U; X0 N
* E7 X6 _9 ]9 u" m5 j4 }& f/ B+ v/ X6 D航点设置
# t4 z4 T8 n: l/ B" d( ]9 y! K" g( E4 k
可对航线点位进行设置,如飞行高度,速度(慢速:3m/s;中速: 7m/s;高速:10 m/s)、任务结束后操作及航向,点击[设置]按钮完成设置。' R9 y" L1 z2 D
vpmhmbwlsto64015952810.png
8 U3 H5 w, P& i* [$ {2 Y设置完成后会显示总距离及飞行总时间。
8 d- E& \/ X" I3 F1 G
auzh0ez4xrs64015952910.png
" B7 n+ V, o9 _1 _, w& Z. c* K9 t# \7 ]- _
航线上传
$ q4 v Y" K- U% h, r; C+ q8 [ R C% B* p" k) R# F K
点击[上传]按钮,进行航线上传。可以进入本地存储中选择航线文件进行上传,航线文件为 .kml结尾。
. ?3 b6 U! Y, `7 n% L: X
wpugeipolqa64015953011.png
, v8 E7 N2 T& E/ B+ m4 U; A' K
E. f R& c$ \ n3 S
航线执行 % ]6 Z# r9 V2 l. X b5 T
8 f) H* s+ P% Y9 l7 r, M, c# x* t/ z
点击 [开始]按钮,则可对航线进行执行。若中途需要暂停也可点击[暂停]安装进行暂停操作。
3 P& c7 N; z7 @5 a* U7 S M
4l4yrjuf4ml64015953111.png
! f6 [8 b/ z, h: t
7 J9 F- ]9 v& }" W航线管理
' j, C9 F7 @8 U6 a. `" L
9 ]6 J o! `+ S: G, b按钮即可进入航线管理界面。
+ y6 a% X! H! {7 G! D3 l+ H# G- o
5 f/ _: [9 N" k" ]9 R
dzwydh0tnfs64015953211.png
2 m4 A$ n1 `( l; b- V
% s+ s3 d1 ?( x% n, `, m. U
获取航线 * W0 \, G; G% l4 Y
* Z/ {% [$ I, T5 M8 l L! @3 d! ^! H点击[获取]按钮,即可将航线信息展示到地图界面中。
. i# q7 \+ ?/ p
0 X. Y d( Y, H$ ~8 L' p8 _2 ?5 i& f/ X2 H' l7 e
2
9 N7 d& u8 \/ O F1 X主要功能代码
% I) F* P3 T% v% L- ]创建activity_setting_route.xml及SettingRouteActivity文件。. H) e$ m& v; F H" ~0 J& I) u
0 K0 k8 G) P" Z3 c7 n' `* ?! G* p0 `4 E5 P: {2 _: W+ b
activity_setting_route.xml# a' Y5 |: I7 g9 ~+ `6 a% R% L
8 N: T" O; A0 u- e. \+ f8 tLinearlayout xmlns:android="http://schemas.android.com/apk/res/android"7 s4 c1 K$ _7 F( m- {, n" J o6 J
xmlns:app="http://schemas.android.com/apk/res-auto"
8 J* h7 v* E! Z z xmlns:tools="http://schemas.android.com/tools"
p8 v; m* u- s8 [ android:layout_width="match_parent"
, M2 z4 r$ D! e$ u8 L- J! ~ android:layout_height="match_parent"/ z2 |" L) J3 c! `1 o8 J
android:orientation="vertical"
0 T$ z% w; y X+ v$ _ tools:context=".ui.SettingRouteActivity">; ~4 B- U0 w/ [, c" ^
include
. m& {* ~% X# v+ v0 q. ~; a android:id="@+id/layout_route"- h; F" B! ^- k* ^7 Q8 J6 w7 X
layout="@layout/activity_toolbar">include>6 k. L& ?7 T& A' h6 l
RelativeLayout% |/ h9 u# k6 a% \
android:layout_width="match_parent"
+ @) R2 `1 A, v$ G* X1 g android:layout_height="match_parent">4 v5 d( e+ z+ s7 f( i( j
com.amap.api.maps.MapView
, M x$ p, H, b# ^ android:id="@+id/map"
4 h9 e3 t6 ~/ n+ W android:layout_width="match_parent"
0 M _ [8 y, T$ ~- l2 K. N! {; h- V M android:layout_height="match_parent" />
6 }/ J5 b! Y; G5 h LinearLayout
6 @" A1 i$ y9 ^8 N android:layout_width="wrap_content"
( g+ G! z# B# e* E8 E9 \ android:layout_height="wrap_content"
1 b! r! g. ^9 j6 ~9 B6 ~/ p2 d android:layout_alignParentTop="true"
1 a* \2 I/ l, E$ F( T- h7 o$ \5 ] android:layout_centerInParent="true"
" v7 q, d! C4 ~/ K" q android:layout_marginTop="5dp">" d) N( o7 F( s) d0 L! X; x
Button
0 r; h6 m) R4 a+ k) } android:id="@+id/btn_delete"8 m5 s& c$ z+ V4 \
android:layout_width="60dp"
& ~# P0 t- V$ S android:layout_height="30dp"7 K Y" ^6 v) J7 v
android:visibility="gone"& B/ k! k/ u$ Y3 T3 M4 v
android:text="删除"1 N9 C( N, E$ t4 K2 Q
android:textColor="@color/white"
! y) }2 _3 ]$ @' @* e android:background="@drawable/button_task_background">Button>: G9 E. N! |4 I1 g/ w0 N" z
Button
! c h- w+ X) b, E1 p; t android:id="@+id/btn_finish"
4 j" I0 X7 o$ v1 r android:layout_width="60dp"
3 u# Z/ M$ s6 n' P: ~ android:layout_height="30dp"
) v7 ?+ Z: b. h' P android:visibility="gone"
1 m4 o& v( @$ N5 z android:textColor="@color/white"/ }- U( b; R! C+ P! _# F9 W1 f5 V
android:background="@drawable/button_task_background"
0 k4 `( p/ o4 A& _ android:text="完成">Button>- l0 P) P* e. N
Button
0 N3 O m% X/ e( C8 R android:id="@+id/btn_setting"
" L. C. _2 E% G android:layout_width="60dp"" x* N% R F& ?
android:layout_height="30dp"
! `& ~2 H$ C' H: u2 x android:visibility="gone"" S: F6 n3 D+ y, ]* E5 M1 V# @
android:textColor="@color/white"( ^+ d5 E! R& }) c) \+ d$ U
android:background="@drawable/button_task_background"5 v# b2 @; k7 Z; o8 ^2 |8 Q( d% c
android:text="设置">Button>
! D4 m" {: e |5 d Button
6 [1 R( `4 F% ]; f4 e2 T android:id="@+id/btn_upload"8 R2 ~; V9 `+ ~4 R
android:layout_width="60dp"
, m- w1 w* p z$ h android:layout_height="30dp"2 c _5 W1 g- k( m5 w, P
android:visibility="gone"9 `+ s4 p. W; q4 W
android:textColor="@color/white"( ?# H6 W) Y. s1 ?' H4 i T8 n
android:background="@drawable/button_task_background"$ F% i1 ` Z& W" H# d! T* l
android:text="上传">Button>
, Z2 d% l, D! v% G, `& m* Y- n7 B, w Button& j5 G, Z9 K* G& L2 H% V9 w
android:id="@+id/btn_start"
+ D. E. |9 v6 [: a6 K% f2 ~& o" e9 S& O android:layout_width="60dp"4 m$ Z+ f6 o" n+ u9 ^3 q* \
android:layout_height="30dp"/ l1 n5 }4 S) a- {4 g5 p/ {
android:visibility="gone"% ]5 Y4 C& X+ q! b7 y# j! J
android:textColor="@color/white"1 }: Q" e" k; ?
android:background="@drawable/button_task_background"
& { R8 D/ E/ _) M android:text="开始">Button>
& X' w9 q1 F' J6 {3 F& y* r* B Button
1 ^( N: A6 D; v, T* t C, o android:id="@+id/btn_stop"
! u& ]2 E4 S3 R* ?8 Z) R5 D& u android:layout_width="60dp"
H/ g* o$ x- y/ H android:layout_height="30dp"5 f1 [& m; K$ Y* ^
android:visibility="gone"# h+ F: p U+ V" N2 Z R
android:textColor="@color/white"% g& F+ F5 M- t8 S! X7 Z; Z. M! V% v3 e
android:background="@drawable/button_task_background"
5 T J/ G: C j5 R- q# G. V android:text="暂停">Button>
6 w0 r/ c- Q0 ? LinearLayout>1 D0 ~5 d# h/ p7 Z' _: d, p
LinearLayout
. Y) m3 A7 w" m! m* ? android:id="@+id/ll_information"
! [4 x" \. i0 @# _+ S* a, E' y android:layout_width="wrap_content"2 G/ m+ O% Y3 s2 ?
android:layout_height="wrap_content"+ T+ [; A. ]0 S
android:layout_alignParentBottom="true"$ G" h8 x+ P: _/ y2 h. x2 T
android:layout_centerInParent="true"
6 @3 o) M* W. R' B( ^ android:layout_marginBottom="5dp"5 ]+ |5 x7 i0 y# E; }7 g
android:padding="10dp"% [) ?% o5 Y, F4 {3 d J
android:visibility="gone"
. C: r; s4 {1 w0 e( z android:background="@color/color_nav_Item_unselected">9 ]* K- R0 _3 a, P9 S$ M0 \+ @
TextView
! I9 d+ q( n6 w5 ?4 w$ k android:id="@+id/tv_height"
! _) m; m0 Z) w% c! A0 o5 Y android:layout_width="wrap_content"
- N0 s$ R' c/ l+ l1 F* N android:layout_height="wrap_content"
8 ^+ t8 f& _3 N5 W5 t android:text="高度:"" p3 z/ Z( H' j$ N6 e
android:textColor="@color/white"9 d' ?+ G' A8 V0 P0 V- r4 I5 h
>TextView>
( I: U+ R! ~; Q: c, D TextView
+ J0 d b% A& Z* {3 T# n/ D9 o9 x5 U b1 } android:id="@+id/tv_speed", u$ a3 c4 O( J. F, `
android:layout_width="wrap_content"5 B, k! D, B. Y
android:layout_height="wrap_content"
$ {& F ? Z5 Z8 E% \9 c7 ^ android:text="速度:"
: [' @2 X7 }: ?/ n android:textColor="@color/white"
4 V. J* P8 k# r* O" @( h$ a/ G: Q android:layout_marginLeft="10dp"8 l$ f2 @4 V/ t: n
>TextView>& D' Q9 A0 t8 E; p$ \- Q2 F9 b
TextView# q u& z4 R* Q* {- R$ Y4 n& L
android:id="@+id/tv_count" [$ i+ n/ g& C
android:layout_width="wrap_content"
9 U: k* ^7 Y _; r9 i+ d' a( H android:layout_height="wrap_content"+ o) x( _$ j: }5 d& a! y# P+ m
android:text="航点数:"
! Q3 _" K, e2 c" x android:textColor="@color/white"
3 }+ H9 P; J8 U$ z [$ o" Q/ K android:layout_marginLeft="10dp", |5 a, B& o* e# c& [7 h
>TextView>! s* W$ ~ B- D, ~9 i; T2 X
TextView' g6 |; y& s7 p- c# c+ t- p
android:id="@+id/tv_distance"
: D8 Z( I! e4 i& @: z android:layout_width="wrap_content"
/ N( d& u0 G! [2 L8 ]7 h C android:layout_height="wrap_content"
! Z3 {6 x4 n. I* g android:text="总距离:"
# i# J4 {1 {3 I4 ]8 `# Y! a android:textColor="@color/white"% f( K R% `: H' d
android:layout_marginLeft="10dp"9 n8 P7 {& p6 x. Q4 [4 \. o. q
>TextView>
% ^* \5 g) W5 H6 N/ `- d% J TextView: B% w% Q: U' `5 N& A
android:id="@+id/tv_time"2 c& [( y& K! V+ t9 n! w4 y
android:layout_width="wrap_content"
! M1 I T' l6 t android:layout_height="wrap_content"
& s7 r& @& ~+ U% m2 X4 [$ R( e android:text="总时间:": n9 t. b* Y+ e
android:textColor="@color/white"4 v/ O5 u3 {# @' i1 W
android:layout_marginLeft="10dp"
3 \2 y2 X) Y5 Z+ A9 d/ _1 ?; m4 P3 K >TextView>& t* x. B: ^& _
LinearLayout>
" j. [+ o$ I) ]' w RelativeLayout>5 u# ~2 _- ^, U
LinearLayout>
! ?- k7 e3 t$ ]0 ^8 USettingRouteActivity+ l9 [4 h9 {4 ]0 A
# P9 b1 F7 u4 m: s, t
public class SettingRouteActivity extends BaseActivity implements AMap.OnMarkerClickListener, View.OnClickListener, AMap.OnMapClickListener, LocationSource, AMapLocationListener, AMap.InfoWindowAdapter {5 ~" h y% s/ q8 z% S" J* n
@BindView(R.id.layout_route)
; X2 O: i" ~2 E0 h6 E8 G View mViewLayoutToolbar;
: W% O) ^" _- I2 f' k/ w" S F( z @BindView(R.id.ll_route)6 g0 D' V& ]) `: H& [6 E
LinearLayout mLinearLayout;5 Q& o- V) R4 Q2 r, g- g/ [/ f: z
@BindView(R.id.tv_toolbar_title)
4 s1 u' ], n8 j8 s7 A2 T" d U- D& Y& Y TextView mTextViewToolbarTitle;8 R, e6 U. y' \/ N N- K9 E! t
// @BindView(R.id.map)
2 w; J5 V! k4 s2 d3 p // MapView mMapView;# `7 G# [' C, l/ @; [2 N, D7 R
@BindView(R.id.btn_delete)
, P& J, E7 |' P7 p/ x& V! h Button mButtonDelete;' Z" i2 h! B' {: r& R: I2 H
@BindView(R.id.btn_finish)
% Q: p% N7 m4 A3 |5 K/ q+ K Button mButtonFinish;3 d! r$ k6 }* | ]9 r* `
@BindView(R.id.btn_setting)
/ X# ?/ k. s4 D2 f& B: Q& F$ _ Button mButtonSetting;
' |0 w0 b) L* F: m6 }0 u% p @BindView(R.id.btn_upload)
" H8 a2 i0 W0 N+ ] Button mButtonUpload;% I9 _5 f$ g, U8 `+ A
@BindView(R.id.btn_start)
" p; M: F( Q; V: e1 D Button mButtonStart;
, s+ ]" G0 h2 T3 R9 s2 n @BindView(R.id.btn_stop)
6 _5 Y' W' X0 n6 l+ `, T2 Z( q Button mButtonStop;
! |/ n3 p/ L; e& y. [ J) O7 x9 p7 _ @BindView(R.id.ll_information)! D8 Q+ d( \1 g+ \2 O( X
LinearLayout mLinearLayoutInformation;9 f, \ {" m8 d! e9 K" F9 @9 E
@BindView(R.id.tv_height)
% }3 ?% L% h! ~) g# `. \. m TextView mTextViewHeight;, g9 A% Q! j0 {6 c
@BindView(R.id.tv_speed): q* P- F% _6 ~8 ]- N5 u! g) R
TextView mTextViewSpeed;4 @: [. A' X. I* b2 K3 g4 V( ~
@BindView(R.id.tv_count)$ x% Y& B! N* d6 c, P ]
TextView mTextViewCount;
4 ?3 Z3 V' e0 R" N9 y8 y @BindView(R.id.tv_distance). W5 {1 D _) \' X* d4 Q2 b5 x
TextView mTextViewDistance;
7 F+ T0 F# R) c @BindView(R.id.tv_time)" ~+ ~) X0 M& J9 m9 C. O! B
TextView mTextViewTime;* `3 Z& r& v) B$ t( l: ]( f
private MapView mMapView;# m2 F! K. A6 S% W3 g5 a7 O+ Z
private OnLocationChangedListener mListener;7 o8 z- T2 {6 G
private AMapLocationClient mlocationClient;) o& k) g' U; W3 u) |% n/ q8 }; Z" \
private AMapLocationClientOption mLocationOption;
I) U/ @4 v" v X private double D_latitude, D_longitude;
, ?" x' y1 `+ m- z& q+ [0 _ t$ F private UiSettings mUiSettings;
! M/ o4 W, J/ a, Y% E3 ` private AMap aMap;
8 D! ?/ R# V$ h$ F! P0 S. @ private Marker droneMarker = null;
6 k1 b2 U/ H/ ]: S% { private float altitude = 100.0f;
/ A8 M- P1 Y3 i: i$ f private float mSpeed = 10.0f;
0 d% [1 D9 w Q [, O, Y private boolean isAdd = false;
- ]3 ]/ O; h5 `+ Q private final Map[I] mMarkers = new ConcurrentHashMap[I](); `8 L: G/ v" z+ W) i/ C4 o z
private Marker mClickMarker;+ U/ d$ u/ B2 q5 A }$ g2 p' @7 x
private List waypointList = new ArrayList();
* T4 y! | {7 m private List mLatLng = new ArrayList();
$ U& c7 m' V+ Y private List mPointInfo = new ArrayList();, |" f$ Q' @# o# F, B1 s' H
public static WaypointMission.Builder waypointMissionBuilder;
+ s" D; q- Z+ `- c. d& { f: S- u private FlightController mFlightController;7 V/ t$ H L1 @" D8 S! K: w; Q2 X
private WaypointMissionOperator instance;: ]/ s% j) j4 R( d6 K( c5 y
private WaypointMissionFinishedAction mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
2 n- L# E8 \. f Z$ ^1 J private WaypointMissionHeadingMode mHeadingMode = WaypointMissionHeadingMode.AUTO;
6 K& R, s6 t# L/ V5 R private SQLiteHelper mSQLiteHelper;
) @1 z4 N4 d6 [ private String FinishedAction, HeadingMode;
, o' K& v! s' I7 i5 H& X0 y //自定义窗体
* A' _; ]1 w1 P% d View infoWindow = null;+ S1 G& z1 C1 p3 Z. Y# {8 ]" u
int speed_RG_id = 0;
7 [9 i. z) {' m0 u& L8 z int actionAfterFinished_RG_id = 0;
( x+ J- X6 a* a- [, o( G int heading_RG_id = 0;+ ?! f1 t b4 \' Q+ M5 I
//kim5 _* c4 |8 p( f5 v7 ~7 v& }0 X v
static ReadKml readKml = new ReadKml();
6 L) K9 u5 G( M8 { private static List sampleList = readKml.getCoordinateList();0 `- K0 X9 K2 r4 l; r
@Override: d, U7 L$ l' f# I( U7 E
public void initViews() {
5 \2 d4 E, O' g7 j0 p- _* r5 b' q5 Z mLinearLayout.setVisibility(View.VISIBLE);( Z2 I0 i% H( R) _/ r; R: ^, O1 l9 s
mTextViewToolbarTitle.setText("航线规划");' S+ S$ P, }* ?" D
IntentFilter filter = new IntentFilter();1 p5 B+ h& K) l; f8 z
filter.addAction(ReceiverApplication.FLAG_CONNECTION_CHANGE);- a# o7 g n1 q
registerReceiver(mReceiver, filter);
. \9 z$ F7 g/ s- R4 O mMapView = findViewById(R.id.map);
% ~$ T2 ?( @8 I- Z B" e; [: S mMapView.onCreate(InstanceState);
1 r& U% n# ^4 K! m initMapView();$ Y& W! K: w0 M4 K
addListener();
0 I& [- O% K# ]. B6 R) j( E onProductConnectionChange();6 G9 n( K _6 F/ Z3 A% Y
}% c9 ^/ x& v D1 o/ p* p
@Override0 ~* _$ p. z7 A3 }. Q% G$ A8 c E
protected void onResume() {
4 b' ^# S3 T4 Q/ n; C3 {# | super.onResume(); x% Z1 `6 ]$ y) z: Y
initFlightController();; M, n6 b# U, f: M
mMapView.onResume();
8 d! `9 F9 I9 v- U1 ` w+ G }7 J9 X) o& F% D
/**# G) ]& h9 \% V0 ]1 O. Z( J
* 方法必须重写6 n& z5 c' Y8 f* c
*/: Y: S( W8 ~3 `; S9 q5 g2 R
@Override6 F5 ?0 ~# L9 O/ U {
protected void onSaveInstanceState(Bundle outState) {2 B% [3 u1 V+ k( b6 a
super.onSaveInstanceState(outState);
% m+ j, k% v: i9 s) ]3 \ mMapView.onSaveInstanceState(outState);
) G- Y8 H: X3 | }
6 N7 l& h: T2 T! i @Override
9 S9 A! O+ j6 \) R protected void onPause() {( a; l' _7 X1 j/ F$ E9 Y
super.onPause();
. Y# L# u9 c$ _* D; K mMapView.onPause();* K: n- _' t# @0 n4 m3 ]
deactivate();# E! u. \, t C( Z2 y9 h$ I) V6 A
}
6 t( t. H/ S2 D. z& T, |7 t5 r( ] @Override# b9 C6 d# N% C4 V& g
protected void onDestroy() {
3 [0 E! h. a+ C/ I super.onDestroy();
& C; d. [0 d/ N7 i unregisterReceiver(mReceiver);
' Y, |+ G2 O' ~' m removeListener();
5 w+ L( g* x; z6 S mMapView.onDestroy();
1 [# q% \/ Y9 m7 j+ z* e$ K' W4 K if (null != mlocationClient) {' [0 r7 h: u5 N4 B- v& Q# l8 D
mlocationClient.onDestroy();! R' C. o" N. E0 G
}
9 k* {! n8 z6 Q0 i$ N) G' t! G3 Z }
. f: S x/ @% x2 r- g @Override
3 C% v9 J) q: }3 c public void initDatas() {2 @# @" S" m; `5 c+ f
}
+ A' D- L; k" ]* X* c- G# w9 @ @Override
% e! \6 |; |$ A+ Z/ [ protected void requestData() {
( U# g2 f6 M& a: f, v { }1 i) A, @. ~8 {6 c/ ^5 _
private void initMapView() {
" d9 h ^1 L8 Y* N- K# x0 H! f if (aMap == null) {
/ ]; X! r' ]2 m4 D% H aMap = mMapView.getMap();
" V" f/ r2 r7 L* c1 b mUiSettings = aMap.getUiSettings();
8 d, Y9 e/ @1 Q/ C( i9 V mUiSettings.setMyLocationButtonEnabled(true);! j8 I0 N2 d k' t( w9 @; B" i! F
mUiSettings.setScaleControlsEnabled(true);$ p6 F5 y" Y8 ~' I3 W. j
aMap.setOnMapClickListener(this);// add the listener for click for amap object
5 H1 i1 e) \. Y# y! _6 r aMap.setLocationSource(this);& F2 V- @0 q. L0 o" e
aMap.setMyLocationEnabled(true);
4 ~. ?! E: V g' [* ~: `, f aMap.setInfoWindowAdapter(this);. b3 F1 D. W8 x
aMap.setOnMarkerClickListener(this);
3 j# X% V$ U9 k+ P; [ setupLocationStyle();
* e$ h4 W; S1 x+ g2 o }
3 t6 t p' `0 ^* l* p0 S/ G4 W } V' p% c3 e2 ^( t9 |
private void setupLocationStyle() {- d8 t( v8 L" q B
// 自定义系统定位蓝点+ t. T) J) z% b5 q8 O0 Z1 x
MyLocationStyle myLocationStyle = new MyLocationStyle();2 ?# b' Q" p+ s4 S
// 自定义定位蓝点图标
% \' r# }: w; l myLocationStyle.myLocationIcon(BitmapDescriptorFactory.6 c. E' j% S/ m
fromResource(R.mipmap.icv_gps_point_36dp));
7 Z' f3 C/ R( \" X$ X+ t // 自定义精度范围的圆形边框颜色- s& V+ c; i4 ~8 _; w! c) g* G
myLocationStyle.strokeColor(Color.parseColor("#00000000"));6 C% U# z6 c M
//自定义精度范围的圆形边框宽度* y) n2 i0 X/ Q9 {1 ?
myLocationStyle.strokeWidth(5);
4 p" ^% U& w) q // 设置圆形的填充颜色
# m9 c: E% P* [" J8 Y* | myLocationStyle.radiusFillColor(Color.parseColor("#00000000"));
: h) r) ^' Z: {/ H // 将自定义的 myLocationStyle 对象添加到地图上- G- C- b) L4 g' L5 L" w: y! a
aMap.setMyLocationStyle(myLocationStyle);3 g7 ~ K1 E/ T& I
}0 z8 y% O7 P8 g
@OnClick({R.id.img_kml_input, R.id.img_setting_route, R.id.img_start_fly, R.id.btn_delete,, l+ k! E9 E. |4 ~, T
R.id.img_setting_clear, R.id.btn_finish, R.id.btn_setting, R.id.btn_upload,
) r* j' c3 K1 f" N9 G! f/ }# X) c R.id.btn_start, R.id.btn_stop, R.id.img_back})$ R/ n3 i- [, R- F9 |
@Override" g- n" h7 K9 t1 Y0 ~0 H
public void onClick(View v) {
) ?+ W0 N" H# N3 W/ i- s2 Q switch (v.getId()) {
. e7 g$ V6 W+ u/ B case R.id.img_back:* Q, T& U' r* x9 l- w
SettingRouteActivity.this.finish();
- C2 g: Y, ~( [" o J break;
# C2 F. o1 o! f4 J9 Z2 q case R.id.img_kml_input:
3 i) P7 a5 i }" [' z7 d# b% B! r Intent intent = new Intent(Intent.ACTION_GET_CONTENT);6 h) v4 ^* f& z7 [7 R1 e
intent.setType("*/*");//设置类型,我这里是任意类型,任意后缀的可以这样写。
0 e' a$ _( F8 _ intent.addCategory(Intent.CATEGORY_OPENABLE);
3 X( c0 `3 v& m& E5 E% o) [% c startActivityForResult(intent, MyStatic.REQUEST_CODE_FILE);* s# Q6 L4 \% T, c1 ~4 e* ]2 x
break;0 M0 d8 A1 H H2 \
case R.id.img_setting_route:
7 H% v% g8 D% B! }1 x+ ` enableDisableAdd();/ Q. L2 @; G( |: }& m+ a
break;
, R2 H1 U1 o4 P( b case R.id.img_setting_clear:5 l; S+ N+ K4 {) l
runOnUiThread(new Runnable() {
6 Y* @& X& M" [; L' y @Override+ S* s. L# }/ b/ W
public void run() {
/ P/ A5 ] F* A: J* Y) C! r aMap.clear();
# C+ K+ ?; H2 j2 @ mMarkers.clear();) Y% L1 U; Q& B6 r6 F, `
mPointInfo.clear();. d, u8 l$ b* Z8 O- _2 o. j' q
mLinearLayoutInformation.setVisibility(View.GONE);
' f2 ^/ c% i( G% O) o# T+ w mButtonFinish.setVisibility(View.GONE);
1 X! t% C0 M4 Y% C1 p" F U8 D mButtonSetting.setVisibility(View.GONE);
8 w4 k( \! u/ a: {* l mButtonUpload.setVisibility(View.GONE);
* Z O' A* j- j% T9 H mButtonStart.setVisibility(View.GONE);
2 P& U; z$ K/ r* H' g5 X mButtonStop.setVisibility(View.GONE);
% E7 ^% k) [8 k, ^) [+ e }0 R' G+ W* v: I- }/ M
});
. a6 ~( O- `+ q! M6 q) z waypointList.clear();
7 D8 W$ X! D8 L* m; D waypointMissionBuilder.waypointList(waypointList);
1 ~) _# k7 j6 b: k: d$ { break;
[# K, h1 o) W case R.id.img_start_fly:- \: w. R3 L0 S% S
atyAction(WaypointActivity.class, MyStatic.REQUEST_CODE_ID);
2 I8 W" p7 v/ f7 Y: X" V break;
$ @! S0 Y( X4 P2 O s* o g. x case R.id.btn_delete:1 I* p& h% w0 A' R4 M0 ?
runOnUiThread(new Runnable() {
: z/ n* `. r* b) ] @Override& Y: D4 u/ N8 P( K/ Y
public void run() {
4 `: N, R" M, N. f aMap.clear();
7 `8 T* {' F; R8 b c- v }
: ^# Q; C" J( u9 i9 | });- l( u5 [: A1 Z; [
for (int i = 0; i if (mMarkers.get(i).getTitle().equals(mClickMarker.getTitle())) {
/ D0 p- D1 O/ I# X; x d0 P for (int j = i; j 1; j++) {
6 C4 q6 Q, n& X- h7 Y% y( z* ^4 Y mMarkers.put(j, mMarkers.get(j + 1));
! B; d6 r5 @; Y% ~8 [ z }
: ?- l0 X; T+ P& g mMarkers.remove(mMarkers.size() - 1);$ F0 T0 ~8 n! ~
}+ ]8 x4 O8 j7 Y. _8 o5 a! q
}- I `+ m& q. n' f/ m3 q
for (int i = 0; i "航点" + (i + 1));
1 L; K( _' x3 C6 | S: `. v }
% u- {" c* @7 u& E' V updateMarkWaypoint();; ^/ S. j; R% M
break;* w a7 x2 Z# q) b: R& s+ C
case R.id.btn_finish:
6 h1 a4 V( ]+ M MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());, L7 w6 s1 r# [3 {/ S
MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
?: A0 f% f5 m2 s1 g8 ^ MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());' k: @0 l/ B) N. q$ G6 M+ s
isAdd = false;# A0 l4 N0 i- s: y* [) H. ] R
mButtonFinish.setVisibility(View.GONE);9 C' g/ P4 C3 f
mButtonSetting.setVisibility(View.VISIBLE);/ X0 l+ ]& s2 q1 u! X
mButtonUpload.setVisibility(View.VISIBLE);
" O! t+ g! A. x" t2 k showSettingDialog();6 k6 P2 Q0 k* p& U; L# D! K" U
break;8 k; I( ]+ ~! f! E- q! c# T# M% Y
case R.id.btn_setting:
9 `" a) d' W4 x# O; N) Y showSettingDialog();+ Y" t- O( X9 b& J- E/ o7 O
break;
( X( [- k1 g7 K! B8 L$ ]0 l4 D case R.id.btn_upload:- I* C5 Y4 d5 C
uploadWayPointMission();
. g" ]% n4 m$ Q" K- M) j& B' m- v break;1 X( \1 q* `' z: L
case R.id.btn_start:
3 R& q3 d# K& g$ V4 O8 C startWaypointMission();
( ~5 s6 J$ P. }' Q break;
, q% B( M& ]1 z/ ?1 N0 z case R.id.btn_stop:
3 \, k* V3 ^( T' S$ D# V* Q stopWaypointMission();$ n4 |6 q* q4 X) l& o
break;
# ?" n$ }3 m7 H8 W( w' X: X }$ ~0 r6 V1 I! w0 C& h) ]
}
( z9 R9 T! B8 e t private void enableDisableAdd() {
, U* R/ _+ @5 [ if (isAdd == false) {, z3 E, M7 S/ a. u
isAdd = true;4 q* x7 x! X& m ? n1 e6 P6 M
mButtonFinish.setVisibility(View.VISIBLE);
( U, h! E6 u5 N5 p* q. R2 u } else {! q1 ?$ o: T' M! G2 |: [
isAdd = false;
/ b1 C+ v2 W- a* p" q& H# i }1 Z& s: X& R$ B0 G0 m: {# W
}
/ J3 J+ r+ q- r. M$ R( \, H7 U' f private void initFlightController() {9 K, P" X, O6 E8 M- J( c; i- h
BaseProduct product = ReceiverApplication.getProductInstance();
3 [& x* X8 j$ i' x+ C( X ~ if (product != null && product.isConnected()) {7 f- g, v# R! x5 x3 A7 B2 ~$ \0 {* |
if (product instanceof Aircraft) {
% [9 w6 X, K+ i6 Q2 b mFlightController = ((Aircraft) product).getFlightController();
! I1 m" x0 f7 u0 N5 \% D, L0 @ }/ M, P9 W' J' D2 o1 N U
}5 H2 b- T9 ~6 @% x. @
if (mFlightController != null) {
; p `8 f+ s7 ]) I9 C" |; N! ~' ~& A mFlightController.setStateCallback(
! E+ s3 ?+ R# w% B new FlightControllerState.Callback() {
; l$ _" N3 g7 Z4 ?( U/ v3 }2 V: n @Override7 C8 a) d3 l, k: \- W. U
public void onUpdate(FlightControllerState3 q6 t `' y0 V8 a3 f% d0 g
djiFlightControllerCurrentState) {& `% d& j' I$ y% ?
if (djiFlightControllerCurrentState.getAircraftLocation().getLatitude() != 0.0 && djiFlightControllerCurrentState.getAircraftLocation().getLongitude() != 0.0) {5 z) {8 N7 t$ x( j: K- V& E! S+ B
D_latitude = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();9 j* f& w. Q- Z* a4 n1 t5 b, N
D_longitude = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();- G+ z/ [) o! r4 I `% H
}! r, B7 l! r7 O1 D: \6 o
updateDroneLocation();
- X5 d" A# t2 N8 D f$ n& t: d" H }4 F# s5 r2 @* s% j; F9 ]$ |0 p
});
) a2 W$ L8 i# Z5 k) q: v1 x* q( u }4 o7 |7 M# ^9 T+ \3 s* W; o) t
}
; M) X4 o' W& ] private void updateDroneLocation() {
+ P- ^2 q2 ]; w" m1 Z {* u9 p- w LatLng pos = new LatLng(D_latitude, D_longitude);5 h7 x5 R! M: t0 ~8 A$ ^0 H
//Create MarkerOptions object
; j" V5 c8 r, ~ final MarkerOptions markerOptions = new MarkerOptions();7 m: @6 b# i: K( D+ j9 h! O3 v4 g
markerOptions.position(pos);6 C+ e1 ?: A" b# F
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_aircraft_write_36dp));
9 V7 G! [+ [9 X$ V, e( Z% Q runOnUiThread(new Runnable() {$ T% M t$ | [8 P
@Override4 ~$ c" E2 K" t# D1 v8 @
public void run() {4 ]! v% k/ f' w
if (droneMarker != null) {9 Y3 c0 s9 N& p7 i# G8 o
droneMarker.remove();
- X; J; K# m2 M9 y/ L6 f } s, i7 r) ?* _1 P* A; y
if (checkGpsCoordination(D_latitude, D_longitude)) {; j. F( R: K, o8 D4 Q/ @
droneMarker = aMap.addMarker(markerOptions);) ?( b2 v' L$ X8 H2 w5 t+ X) D, z
}
' _. h' F( E6 f/ R }$ I5 q* Y2 @/ e* W9 G: C
});- _: X5 M$ l5 j# l% D! r& |; @0 `
}
6 ]" c2 _' ~9 k. a public static boolean checkGpsCoordination(double latitude, double longitude) {9 _7 Q' g& M( V r' B' c* D4 l
return (latitude > -90 && latitude 90 && longitude > -180 && longitude 180) && (latitude != 0f && longitude != 0f);7 |8 k2 H1 z& w. A! @/ V. V4 d
}
6 X' O) R8 H) R# X3 M protected BroadcastReceiver mReceiver = new BroadcastReceiver() {
% b% A; n3 T* B2 M/ F. Y8 N4 c @Override" [/ J- t/ A! c2 P0 e( u& H/ h
public void onReceive(Context context, Intent intent) {& ^( e3 l- g" l
onProductConnectionChange();
- B5 k5 L# |" K. x6 f/ @/ c } {! B. V4 w3 j; i
};$ p+ R! d M0 H
private void onProductConnectionChange() {- q+ Q# a# J, a1 X3 p$ w1 R- n- i% x
initFlightController();, @( Z7 h- d1 N' ?( z" L' V
}
4 h$ ~' y5 t! A# d1 @1 W: g private void addListener() {& V, n- T! ]1 _" K6 R( [7 W
if (getWaypointMissionOperator() != null) {
# R# ~/ b3 w% W0 [ getWaypointMissionOperator().addListener(eventNotificationListener);
' Z6 H2 g* `) ?& d5 N. z9 p }+ n% G5 b7 i% s+ e: A2 c
}
+ x e$ J, }8 i; D private void removeListener() {2 U3 c U1 \+ [& p* v+ o
if (getWaypointMissionOperator() != null) {; T1 \; m" b( s7 Q* D6 a$ m h
getWaypointMissionOperator().removeListener(eventNotificationListener);; j6 t# y( F2 [. m8 H2 c2 `$ o/ W
}3 r1 E! ^7 o9 j6 ~5 G; P/ v
}- H" D) W+ ^ K" y, @
private WaypointMissionOperatorListener eventNotificationListener = new WaypointMissionOperatorListener() {
9 Z/ C! e% l( A! s# e* [2 ?* j @Override! H4 h& y% b$ b& X6 c2 I' j
public void onDownloadUpdate(WaypointMissionDownloadEvent downloadEvent) { u4 B- l2 g7 X% w9 j6 u5 c
}
# Z/ F8 W, Y9 K @Override s; _+ q+ x7 I# n/ Q$ r- r
public void onUploadUpdate(WaypointMissionUploadEvent uploadEvent) {' w; a7 B% e3 F; `& x$ U5 c7 @! v
}8 ^3 H- m; I+ e; X- L5 q
@Override+ @* e0 ?' C6 ^* Y* `6 L; O
public void onExecutionUpdate(WaypointMissionExecutionEvent executionEvent) {
$ t/ e( B/ h2 a* `( B }
' F) h$ u& u( B4 g6 I4 ^ @Override( O0 L* p7 S3 X2 S- K/ v) T& ]
public void onExecutionStart() {
1 a* z0 D" R& ] }
* Y- z/ C6 h7 S% X; @9 O( y @Override2 N) X5 J! ~4 ]$ d$ N2 @
public void onExecutionFinish(@Nullable final DJIError error) {* v& F1 z- K2 _) y4 P; R. ~
showToasts("Execution finished: " + (error == null ? "Success!" : error.getDescription()));
( i P g0 }+ K6 j# u4 Z# q5 m z6 D }+ o N* p* k7 w! G& d- L/ W: q
};
5 P. i/ ]1 S: K$ b$ O public WaypointMissionOperator getWaypointMissionOperator() {
% p/ d& s0 [$ g! s if (instance == null) {
# f! w# f2 o6 r& ]' ~; B instance = DJISDKManager.getInstance().getMissionControl().getWaypointMissionOperator();
( b# ~) N( f% R6 {, w8 _ }, r% N0 ^" {6 j D2 s5 ~) p) |4 |
return instance;
6 f+ K5 L) N( H/ h2 f. V }. c S: S5 v/ m- u. N4 | y
@Override
9 W3 N3 N' {( {! ?+ Y4 Z" j public void onMapClick(LatLng point) {
# }5 @, [# `0 N4 z if (isAdd == true) {
) t) X' d7 i: Z- [ markWaypoint(point);& o: q, `4 p, q3 t6 y
Waypoint mWaypoint = new Waypoint(point.latitude, point.longitude, altitude);
" s; w2 b2 S+ Q* h4 m //Add Waypoints to Waypoint arraylist;
|* j: O- s$ Z6 q [5 x( u+ { if (waypointMissionBuilder != null) {
% g9 B* S: ?" v" K* ?! F waypointList.add(mWaypoint);4 U) ^; f- J2 E3 b% p! W" ~
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
# B6 A; L, ?$ W! x" t! j } else {5 m* \% [" L( K
waypointMissionBuilder = new WaypointMission.Builder();
: {/ \, V- i i% E waypointList.add(mWaypoint);/ o6 p( o0 _8 d
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
. \9 Z" [& Q: h }
/ u, ~! X- V l; m! ` mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
8 c- R9 H# p m3 @ mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");1 N& V# z) B6 Z% Q; d
mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
( p$ `7 M+ r. g' U1 i } else {5 I: z5 m J( } H, Y
if (mClickMarker != null && mClickMarker.isInfoWindowShown()) {
. i* P- o+ b3 G# r4 z mClickMarker.hideInfoWindow();
1 P. K1 S# U0 a" @4 E mButtonDelete.setVisibility(View.GONE);
+ K' a/ k5 F8 I }$ {; O' o3 p5 s, {9 i
// showToasts("当前未开启增加点模式");1 y" P8 T d' r/ e5 `, }
}, U$ t% c5 D1 |3 c! i
}
) t7 A0 B% d6 A- O private void markWaypoint(LatLng point) {9 [& ]6 N: d5 u/ L
MarkerOptions markerOptions = new MarkerOptions();6 [/ n1 J" w" x" A( p! M
markerOptions.position(point);
1 w- ? t& }1 h. x8 b' M mPointInfo.add(new PointInfo(point.latitude, point.longitude));- A# U# P$ N9 t5 ~5 b
markerOptions.title("航点" + (mMarkers.size() + 1));
" y$ l, r* ^( b markerOptions.snippet("事件:");
1 ]3 D/ b0 g6 B# I1 l markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));- w$ z: ?+ f1 O4 [& \9 b+ r
markerOptions.infoWindowEnable(true);
: i' l& X" U/ r, V, L4 I Marker marker = aMap.addMarker(markerOptions);
- d3 O" Y) H8 \- y mMarkers.put(mMarkers.size(), marker);. p5 y3 B# X5 l. i5 ~/ L
marker.showInfoWindow();9 t# c% k& t* L
if (mMarkers.size() > 0) {' H. i& T' I) D) X o0 X+ `
mLatLng.clear();
9 X: V; a* s2 z2 F+ L# l PolylineOptions PolylineOptions = new PolylineOptions();( u, r4 M( U, [ E& X% L
for (int i = 0; i 10);/ a5 ^, b* V% M S( |
PolylineOptions.color(Color.argb(255, 1, 1, 1));
4 _+ k7 | z4 ~' ?$ n, W aMap.addPolyline(PolylineOptions);
% c7 U! T! M# e: a% _6 R6 x4 W% m }
% E) h( K6 U$ n' j1 Z/ A& E! A }
) J; w( i1 e4 p# M private void updateMarkWaypoint() { x) X1 L2 f4 a4 E: H- o
mLatLng.clear();
8 e7 Y$ V' {+ D- e* a S waypointList.clear();" F/ `1 K- P7 `4 s0 R
mPointInfo.clear();. | M8 O' m# i) V }
waypointMissionBuilder.waypointList(waypointList);
+ c1 @4 |' c1 N6 l+ ^# T( w7 i for (int i = 0; i new PointInfo(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude));
9 {- _" M" \9 I* l MarkerOptions markerOptions = new MarkerOptions();) R/ S6 o l8 t9 y1 u0 j% Z+ l
Waypoint mWaypoint = new Waypoint(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude, altitude);# I; @$ v; S) @: J M- _4 ?7 A H
waypointList.add(mWaypoint);: @) j2 h/ s; H" M% g
markerOptions.position(mMarkers.get(i).getPosition());; z7 A& a. Q' C! i, D
markerOptions.title(mMarkers.get(i).getTitle());
1 z0 ?8 }; u0 r$ ^ markerOptions.snippet(mMarkers.get(i).getSnippet());9 z+ k7 b8 H+ F s9 y
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));/ f# W/ _. t( e( L
aMap.addMarker(markerOptions);
4 x3 V. D$ O" F4 E5 F; d Z/ D& x mLatLng.add(mMarkers.get(i).getPosition());
& }3 O1 Y% w/ ^2 [1 U; q }
+ a/ O& V& y$ T9 I( w. c6 y9 N if (mMarkers.size() > 0) {2 V1 [* r- z: Q$ ^- f4 g$ }/ _
PolylineOptions PolylineOptions = new PolylineOptions();
, {; q9 i% P4 q, Y8 |. [ PolylineOptions.addAll(mLatLng);
6 n( b( u: H/ u0 t7 z1 G C PolylineOptions.width(10);
* h0 z; x. r, o PolylineOptions.color(Color.argb(255, 1, 1, 1));/ Q, g+ J3 h4 V+ @$ }2 e: X
aMap.addPolyline(PolylineOptions);/ @* X8 `2 H* L; q4 r
}0 H/ N; L( T* A$ d! e
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
2 a' o I$ ` y2 c/ \ mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());9 ~0 R# n6 U( @0 \' R. ^' A
mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");! ?2 w$ `& M7 M0 h1 I. c3 }6 w) p
mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");) ]0 f" I# A( ^. ?* y5 a
MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());
! y6 M& i8 ?' _2 X( @* e# c" S MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
9 M7 X2 i6 k1 T: y, G3 d MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());" o9 u0 b1 [; Y3 I$ c2 k2 G$ Y b/ |) _
mButtonDelete.setVisibility(View.GONE);
, e8 \; a _9 _! d7 H( P% U4 n }4 h$ ?9 Q" ~: U; B4 C
: z* p. I9 x% S
/**7 P( o6 G. s1 u7 K
* 定位成功后回调函数
! G# I; N* R7 _/ T6 K */* Z# M9 Q% U% J' L, t
@Override: `5 A8 B: n1 g
public void onLocationChanged(AMapLocation amapLocation) {
- [) N( t8 ]. ^$ i' w if (mListener != null && amapLocation != null) {& W- F5 f- T+ V. s
if (amapLocation != null
6 t6 o% L% ^ }' ~# f/ v && amapLocation.getErrorCode() == 0) {
C1 r! h' ^1 u; B D_latitude = amapLocation.getLatitude(); //获取纬度2 h- E+ b H! L0 T5 d
D_longitude = amapLocation.getLongitude(); //获取经度% p7 A, n) t8 Y E+ [
mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
+ d- t: z" _9 Z( F/ @ aMap.moveCamera(CameraUpdateFactory.zoomTo(18));* @$ ]. g0 G* D! D
} else { Y- [' E' t7 {- D; _1 z5 ~7 \
String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();2 L, \: W3 N% Q; D$ H/ O
Log.e("AmapErr", errText);
( e0 Z) l6 _6 R9 @/ U/ t) P5 A }. T+ C `* Q7 k$ F) w, n) @/ H
}
1 D# W/ C0 `, s+ y# q: o' e }
- r2 v# Q. ?& V# y7 }, ? @Override h1 i g# a+ I# A9 G. g/ k4 ~
public void activate(OnLocationChangedListener listener) {% w- R3 j( B* E; E- q8 A
mListener = listener;7 Z2 H0 p0 o! V' L- F; U' G
if (mlocationClient == null) {9 S0 c1 e9 t6 g, ^; ?! B
try {+ ~) Q, _5 r" t3 G! P% Z
mlocationClient = new AMapLocationClient(this);
; n4 n# m$ R* e8 D } catch (Exception e) {* E* |/ M. V9 C( H5 n- C
e.printStackTrace();" @) m7 ?& F8 o' N# ]. ^
}$ X. Z6 x+ \3 m- F" E; ]
mLocationOption = new AMapLocationClientOption();
! _7 G+ l% ^. j3 j //设置定位监听
. G4 D s* l y7 [0 E; E3 n mlocationClient.setLocationListener(this);7 Z" e( L5 u) D5 L
//设置为高精度定位模式
1 |0 X7 p, w# C5 F. A mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
* {' E3 D; a5 x9 S //设置定位参数
, @2 ?# R ]$ i8 H2 m: R mLocationOption.setOnceLocation(true);
1 \' S% y" Z8 ?& v8 X% H* L5 M mlocationClient.setLocationOption(mLocationOption);
) B8 i- w2 Z1 j // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
6 {+ B X$ ~7 p1 `1 S // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
3 r6 J% ~$ \9 I. F // 在定位结束后,在合适的生命周期调用onDestroy()方法2 w0 c4 H$ \+ k* Q: S
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除- S) b# [* I, @" V/ n
mlocationClient.startLocation();
3 `7 ?3 k0 R9 u1 e }
# `- b2 i$ C7 N- H" Y* E$ `- h- g8 v }& l+ ^4 c3 |! U0 a7 W; Q
@Override
0 M7 J+ y2 l5 N) B4 i8 ~/ E' K* | public void deactivate() {
& X2 c2 f7 L7 g* _" w* W mListener = null; F6 g/ ]' G+ t7 q) C) p& A
if (mlocationClient != null) {
+ y B* [! X* S/ L2 U: e, n2 s mlocationClient.stopLocation();
! G' I5 m) g8 k, n/ y mlocationClient.onDestroy();: ?+ }6 u; L5 G
}6 q6 C6 j( v* n4 [+ q- a& a$ C
mlocationClient = null;
2 |3 q& j( H* Y }
6 l7 k% @/ W5 [ @Override
$ V; _, a( l* r: h, ~$ z8 ~% Z6 \ public View getInfoWindow(Marker marker) {
% ^; u1 g, U0 a, }+ w/ Y if (infoWindow == null) {
& Q* s: @/ U7 p* i5 u+ {0 @( e: M- ` infoWindow = LayoutInflater.from(this).inflate(R.layout.amap_info_window, null);# |: ?# `8 L* s- n. Z
}
8 _ a3 `; }- y* V9 w1 N$ X% D render(marker, infoWindow);' H9 l7 z1 h: b4 `' r
return infoWindow;
; H$ g3 J) C1 W: @" v }7 u4 h; t' B2 u6 T! |: Q m
/**% X8 t* r* w, c( S
* 自定义infoWindow窗口
4 r; e' u, @% Z4 x6 B5 J */
* \2 @$ x8 q& i7 W# n/ \ private void render(Marker marker, View infoWindow) {
4 L2 O: w4 v+ A' q4 p% d# h9 G TextView title = infoWindow.findViewById(R.id.info_window_title);
' m5 y1 p5 `: m. o+ l TextView content = infoWindow.findViewById(R.id.info_window_content);
: }& D' N. E7 I* j* s* { title.setText(marker.getTitle());9 w t7 ^2 q M7 r6 f2 b% u
content.setText(marker.getSnippet());. o8 T1 ^# v& P6 e; J
}2 F" `0 _& t9 `) W" v6 t
( R$ i3 h) X8 K% V$ ^& V @Override
8 n" {2 x1 E* D public View getInfoContents(Marker marker) {* g( b) |! {# o) V0 B& l. c- G8 T& A- X
return null;
# u0 A2 Z; O: |$ O1 X$ G }8 H/ P8 z) Q: L ]+ D, N9 I- F
@Override
3 W& ~ W& V% B4 s, M6 j! L4 K public boolean onMarkerClick(Marker marker) {
- q/ }; Q9 F: ~5 D0 h) o marker.showInfoWindow();
7 o: {7 V! i; ]* } G8 J mClickMarker = marker;1 E8 v, C( k* T0 m1 Y( w/ D
mButtonDelete.setVisibility(View.VISIBLE);
* D& e* \ S4 R/ y/ C4 I // aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(),18,0,0)));
( y& V2 ~" o6 V2 E7 E1 r6 P return true;( w0 f0 G U' W0 |
}) ~8 Z {8 B P8 h/ W
private void showSettingDialog() {
" r+ |0 @4 x) }2 H4 x LinearLayout wayPointSettings = (LinearLayout) getLayoutInflater().inflate(R.layout.dialog_waypointsetting, null);
9 z: r2 T6 Y5 J& B% v8 |( z final TextView wpAltitude_TV = (TextView) wayPointSettings.findViewById(R.id.altitude);, g) G; O- Z' Z( z- y) P9 p
RadioGroup speed_RG = (RadioGroup) wayPointSettings.findViewById(R.id.speed);* P& d+ h3 o2 ]1 _/ i4 m( D
RadioGroup actionAfterFinished_RG = (RadioGroup) wayPointSettings.findViewById(R.id.actionAfterFinished);
2 M4 m6 @7 J5 D6 q* b5 s) w& V RadioGroup heading_RG = (RadioGroup) wayPointSettings.findViewById(R.id.heading);
5 I( Q; s; o2 t# J) l ` wpAltitude_TV.setText(Math.round(altitude) + "");" m) S2 M9 f. M$ M
if (speed_RG_id != 0) {, N. j; }2 v W2 I
RadioButton radioButton = (RadioButton) speed_RG.findViewById(speed_RG_id);" z" d2 f: E& c0 ~9 ^1 V3 s) j$ X
radioButton.setChecked(true);4 O8 d0 ?2 \9 \9 [( n6 t: K5 W2 a
}; I5 @5 W: U d* F Z
if (actionAfterFinished_RG_id != 0) {, c e* J' h! t' N6 F" C
RadioButton radioButton = (RadioButton) actionAfterFinished_RG.findViewById(actionAfterFinished_RG_id);4 K6 ^+ O6 C( R: n% I
radioButton.setChecked(true);2 A. |( K: K% S2 F2 P; z
}
# Z' H L q1 h$ ~. {5 I if (heading_RG_id != 0) {' P! C Y& w& ^* J2 U8 i
RadioButton radioButton = (RadioButton) heading_RG.findViewById(heading_RG_id);5 _4 p6 Z/ @6 G/ n; k, N
radioButton.setChecked(true);8 y% \/ c) [8 V4 c1 Y7 p
}
& Q$ ~& g0 |( w5 p: A0 j4 X6 t speed_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
F% B4 }* W6 ?3 M& X& M3 d/ R( s$ p @Override
y, P, T4 b$ @7 B" [ |2 ]9 y+ z public void onCheckedChanged(RadioGroup group, int checkedId) {) |$ N+ y- E/ _7 T3 I6 i
if (checkedId == R.id.lowSpeed) {! {2 e$ ?. f+ z: G2 L. W
mSpeed = 3.0f;* M# J1 E. t: ~0 E# Z: A
} else if (checkedId == R.id.MidSpeed) {+ Q8 E) p; ^8 @5 `/ [. Y: `* f+ T
mSpeed = 5.0f;* I% P5 q4 {9 u- q
} else if (checkedId == R.id.HighSpeed) {& a5 |- Y7 ?% L& Q6 L; n0 _3 i
mSpeed = 10.0f;2 S) P$ q4 d; G) P e
}
) i" w+ Q! C* d! u* s speed_RG_id = checkedId;
* \! T" h, Z) \ }
l, v" k& B$ i: q: R$ e. d. }' I });
# ^* d" w3 f( ~+ ?1 d; h actionAfterFinished_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
4 r1 |2 D* u+ P* R6 |' f @Override
- \; R3 P$ X' A# ~8 K public void onCheckedChanged(RadioGroup group, int checkedId) {
. n+ w. N/ u1 O6 S4 P8 s7 S MyLog.d("选择动作完成");
: Q3 R7 N; i0 `: x9 d5 D9 u% ~$ K if (checkedId == R.id.finishNone) {. c& [; E2 m' c8 }9 P: x
mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;& F! _4 h; g# z8 U: R* C
FinishedAction = "0";
6 J9 p3 U; }7 |9 b J f) l& H } else if (checkedId == R.id.finishGoHome) {
3 a" T x9 ` r: F- f mFinishedAction = WaypointMissionFinishedAction.GO_HOME;+ B# U9 L/ `# I# l( x: R
FinishedAction = "1";
$ P k, D2 y- w W } else if (checkedId == R.id.finishAutoLanding) {
' `3 S1 p" d: g5 r9 b9 c2 N, e( E% } mFinishedAction = WaypointMissionFinishedAction.AUTO_LAND;
/ K! h k6 f7 [! C% V6 e FinishedAction = "2";# I! G0 J+ p5 y$ S% \$ W
} else if (checkedId == R.id.finishToFirst) {3 R6 R+ G3 J' b, E+ }, e* r
mFinishedAction = WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;) Y' Q( y& v6 c: H, p
FinishedAction = "3";
9 q" D' R" i1 R! ]- c. f, [! x }
( p0 f8 ^6 I; N actionAfterFinished_RG_id = checkedId;
7 g" H' S- g6 E }
1 l4 [7 T3 D& V* W) @, I8 a });& K+ `; N& t1 x4 @* ?5 q
heading_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {! j; s- A* r1 ?: Y9 x8 Y
@Override
# K* \7 C% V2 w1 u0 u1 q public void onCheckedChanged(RadioGroup group, int checkedId) {7 l2 X$ W" o& N, J& b/ [
MyLog.d("选择标题");
# p+ {$ ~9 C3 M5 d7 e if (checkedId == R.id.headingNext) {2 J1 z o6 T! X* n. F
mHeadingMode = WaypointMissionHeadingMode.AUTO;
, k# h" I/ \9 h/ ? HeadingMode = "0";
x x. y* P" d& @ } else if (checkedId == R.id.headingInitDirec) {8 S, ?& ~ Y4 O- ~, {9 r
mHeadingMode = WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
1 k; v3 H! `6 U7 D2 F0 }- x0 q HeadingMode = "1";
! m7 A n3 @6 ^ j% B! O# N- u } else if (checkedId == R.id.headingRC) {
' P' O) F) ~( m) y mHeadingMode = WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;
" B" a5 O* ?/ r( s5 I; ]2 j, A/ W HeadingMode = "2";
! i6 C+ e7 o- G } else if (checkedId == R.id.headingWP) { F: R: B( [. J+ c7 \4 T) Q
mHeadingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;. f* \9 U: `# y+ g' T# g: v: u
HeadingMode = "3";
) E5 J6 |4 j2 y; m, ?- e! q8 v3 @ }, X" `* m5 o6 h( G( Y7 }
heading_RG_id = checkedId;
8 v6 x" o; g- L: i+ n3 x7 W }
i( T* U* ?3 y; Y+ k) } });; R3 O" K* h* D {5 K( d
new AlertDialog.Builder(this)
+ }* V+ c- F9 x' s# G+ L+ S .setTitle("航点设置")4 b6 O! }( f; P3 h1 K& K, a
.setView(wayPointSettings)' n( |9 P! m% p3 d% i
.setNeutralButton("设置", new DialogInterface.OnClickListener() {
% c9 X3 f- g1 ~, i/ j$ k public void onClick(DialogInterface dialog, int id) {: `" Q [. v# {3 p6 M0 ?
String altitudeString = wpAltitude_TV.getText().toString();
( r9 y9 a, I& E% b5 {2 }; f" j altitude = Integer.parseInt(nulltoIntegerDefalt(altitudeString));
& p1 }( w& W2 k- G! w7 w6 p- f z: M MyLog.e("altitude " + altitude);& L3 Y7 T& m. Y
MyLog.e("speed " + mSpeed);
/ F: K: }$ C/ k MyLog.e("mFinishedAction " + mFinishedAction);1 B$ m% g6 V8 N6 r9 O, W
MyLog.e("mHeadingMode " + mHeadingMode);3 U3 W" Z. U$ N5 A0 {
configWayPointMission();' h0 A* V: J- c6 m7 o
}0 F2 M. A2 E8 C
})$ ?) C( y U; ^9 x& Y- y$ {
.setCancelable(false)
' ?" z# ]) s3 i t1 y+ L- D .create()/ q( L& L+ [$ k( ]; o& K) u
.show();
' x- _! _9 h' |; ?! Y }
$ p8 V* _) }8 e String nulltoIntegerDefalt(String value) {
6 `6 v0 M2 T; ?; b9 f if (!isIntValue(value))
! S% y" S% t( R* P, ~6 s4 i- \$ e value = "0";+ r: e( y& L" |! h c
return value;
* B: s$ b w+ |2 p0 P/ h }- D# `; q6 _% r! B* j" |
boolean isIntValue(String val) {9 o- Y7 B) P' |
try {
# C9 ^& u/ {( B val = val.replace(" ", "");
3 @) ]; X( c& |1 t/ l; H. N+ q Integer.parseInt(val);; R+ n: S. D: Z' k9 p' T* R
} catch (Exception e) {
( I- s, c3 I0 e! O! [ return false;
6 Y0 S8 I g& z3 F0 h }
5 e& Z$ A {- V; D4 }3 D return true;
+ U. h. c3 X, n0 @; U. E* Q f ~ }
# x! E0 H2 k5 [7 V private void configWayPointMission() {
3 c0 c! y! }* W/ X8 j if (waypointMissionBuilder == null) {
+ k+ g# J( P/ x! W# h. K+ r: ~, f3 T6 e waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)
, E+ C, | u; ~9 v0 h .headingMode(mHeadingMode)
$ F8 K8 l" }7 X& J' ?# } .autoFlightSpeed(mSpeed)- ]: ?/ ~9 P9 f' z- Z/ p4 K! h
.maxFlightSpeed(mSpeed)
* C9 l# U* K. [) C+ U) _' J .flightPathMode(WaypointMissionFlightPathMode.NORMAL);/ g+ K) B3 L5 w3 w
} else {
8 f! v- n& ]5 @4 `% ]5 U- c) [ waypointMissionBuilder.finishedAction(mFinishedAction)7 l# P7 X; C3 m, n8 B; w
.headingMode(mHeadingMode)2 h" S! m @: a3 }8 m
.autoFlightSpeed(mSpeed)
. W* p" L* t/ }4 M- r; w .maxFlightSpeed(mSpeed)* U* M8 V: t& J4 I
.flightPathMode(WaypointMissionFlightPathMode.NORMAL);; b# }0 u( W7 z6 J' l" {
}: H( b- J6 u5 [, R3 {/ f K
if (waypointMissionBuilder.getWaypointList().size() > 0) {# ] M7 F( N- j0 Y( w" O0 k
for (int i = 0; i if (error == null) {+ Q( E% S8 v+ A1 b: O
if (mLinearLayoutInformation.getVisibility() == View.GONE) {) ~* M, r- V- R1 \! N, _( V
mLinearLayoutInformation.setVisibility(View.VISIBLE);
2 C$ E1 J% w* ?% b- }1 t }9 x8 P( }; \8 J( L) R
mTextViewHeight.setText("高度:" + altitude + "m");
+ I1 P+ ~& R/ X3 h mTextViewSpeed.setText("速度:" + mSpeed + "m/s");; i+ W( j; F! d" Z1 m. O; x
mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());+ e( [, f( q. ~" N
mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
' |; x8 Q5 F3 Y4 u- g1 N7 D8 U+ r+ i mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");/ I2 A: n+ s& M7 f
MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());
, s$ B7 v/ y& R& P- u; w MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
8 S. r/ }+ K9 g, K$ N% | MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());
4 m) |6 e) X; C- L4 n. k showToasts("航路点配置成功");
: Q( b. }; }; z ] } else {& y/ ]- q" J4 S2 {5 l9 f: E |
showToasts("航路点配置失败 " + error.getDescription());# F. `" p+ e* D' }8 K8 s
}
b! |" M! {5 I8 P3 b$ S! b }8 i7 }7 K3 I# N( k/ A
private void uploadWayPointMission() {, _1 A, @( l6 N) l4 _$ |, ~ v
getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {
' x0 W* `- V; L3 Y @Override$ z% T4 `( n s, ]: z& p
public void onResult(DJIError error) {) A( d% W7 b& q+ O4 F; c5 L( c
if (error == null) {
+ t) E- ]4 q& e; O runOnUiThread(new Runnable() {
# \$ n7 Q: f" [) l7 X* h$ e" c& a @Override
8 `8 R* e: X9 v3 m$ c% R3 M" F public void run() {1 e( F5 C/ d( p% v: J* B
mButtonSetting.setVisibility(View.GONE);
0 o5 A* C1 A- a1 j% e4 o+ h mButtonUpload.setVisibility(View.GONE);& \: F8 E% [6 b4 y4 ]' @
mButtonStart.setVisibility(View.VISIBLE);
- |" n: I, ~2 h+ @ mButtonStop.setVisibility(View.VISIBLE);% K6 K" W: L: {
}
- j3 f% c2 U9 a" b# ?: r });
L# Q" Q& P5 Z8 i showToasts("任务上传成功!");" u3 `5 r6 g; t
mSQLiteHelper = new SQLiteHelper(SettingRouteActivity.this);
; z D f, E( X4 u5 d7 C MyLog.d("航点值:" + GsonUtil.GsonString(mPointInfo));
+ @. o/ p- V/ p I mSQLiteHelper.doInsert(GsonUtil.GsonString(mPointInfo), altitude, mSpeed, HeadingMode, FinishedAction,
; s) x1 t% O) w* B! j waypointMissionBuilder.getWaypointCount(), Math.round(waypointMissionBuilder.calculateTotalDistance()),+ ^4 S) A" n; M6 u
Math.round(waypointMissionBuilder.calculateTotalTime()), DateUtils.getCurrentDate());
) S9 P( z4 J8 U. f$ w9 U mSQLiteHelper.close();3 f# f1 k+ u4 @0 W) G
} else {4 k2 r& H/ ` K2 r: ^! s+ I
showToasts("任务上传失败, error: " + error.getDescription() + " retrying...");
6 l: T/ k9 ]) d' z) m8 z0 { getWaypointMissionOperator().retryUploadMission(null);) O A. t5 A0 I {! w- [
}0 N8 @) t1 X/ U! |0 w
}
/ `+ |6 s. [, Q. N! @8 u; C7 } });% [8 B! B$ X z! f: e
}
/ B0 F" J- F7 A8 u* _ private void startWaypointMission() {3 U/ ]9 D, x( V& p) j7 R
getWaypointMissionOperator().startMission(new CommonCallbacks.CompletionCallback() {$ {( A( |# {6 L0 ]5 G; ^
@Override
1 q0 ^6 J8 G9 K0 Y* K, F1 l public void onResult(DJIError error) {0 X1 l" S( P' K. @, M+ v
showToasts("任务开始: " + (error == null ? "成功" : "失败:" + error.getDescription())); A% _: ?# Y& {! A0 v
}
* y: R9 j7 e( f8 K });! i: `7 G7 e: y2 ^* u- x# [, L+ B
}3 O- m( K; w5 S$ g
private void stopWaypointMission() {
( N1 B7 ]! D: `* s+ P1 E getWaypointMissionOperator().stopMission(new CommonCallbacks.CompletionCallback() {
/ M0 s7 P3 I; |5 b( o5 q+ D9 { @Override
, y$ k6 r* v7 S: `3 S7 W0 i3 k public void onResult(DJIError error) {& f8 R% ^4 T: T1 ?' b# R
showToasts("任务暂停: " + (error == null ? "成功" : "失败" + error.getDescription()));
. \( a0 v, N1 J) H }
~6 Z! |5 H" ] });
: A3 P. p6 B" U; E+ _: s% O- C! i }" Q, B" c: J5 R3 T4 R
@Override
7 S2 P, m- u' G+ E, E) p5 H* n' | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
6 i% E' ], }% O switch (requestCode) {# j- M4 n3 c( `
case 101:
0 v& P6 d7 \4 e8 H2 S int Id = data.getExtras().getInt("id");
6 p$ `( R" g c MyLog.d("返回的ID:" + Id);2 m9 L3 Z, O; T* x% ]; ~
if (Id > -1) {" x8 ~6 I- b2 R# e& m5 R. ~1 |
refreshMapPoint(Id);
, O1 y9 ?& P0 n5 y8 D# a }) w9 f; M& z) e+ _7 m' d# o$ T$ Z
break;
S `, O9 M( ` X case 102:- W" _ y: X) Q+ p3 @9 O! j
if (data.getData() != null) {/ m' U9 c2 ]; C1 j
Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
1 Z0 b# [9 W* b2 d String img_path = uri.getPath(); Y* `( @! R0 b3 Z9 y0 @4 m
try {5 M: V& m, Z7 _/ g) p
if (!TextUtils.isEmpty(img_path)) {
5 U( x5 f1 x2 q+ B readKml.parseKml(img_path);
8 M; N F0 ~: R; f addSampleMarker();4 N! j4 q6 O- [3 {% R5 l
}3 _$ Y8 O& c2 a9 J) M8 P6 a( H
} catch (Exception e) {
1 I0 B( k, R. [4 \. J7 W* s4 K e.printStackTrace();% r6 {& p. j; B" S# L7 v
}
' B' ~% r+ r( W }
9 ?3 Y) @6 {7 ~ J# n" t% s# M B/ F break;# [( f' D8 {9 _ c
default:
' o. u) [# R2 X6 n. K8 s# x2 p% p# M break;- ]" C3 ?( C5 ~; C c
}
+ @) q1 a. J \6 c8 H" Q }
8 m6 z. [4 J, K6 u3 X0 f private void refreshMapPoint(int id) { B5 @9 ?' \' N$ z& Q- O6 x
aMap.clear();
6 g* _( i& p3 {+ o+ w5 T mMarkers.clear();: h8 T, o1 C" [3 @
mPointInfo.clear();
: |' I( _+ a/ G' ]$ [ mLinearLayoutInformation.setVisibility(View.GONE);) P) Y1 D! }1 L f
mButtonFinish.setVisibility(View.GONE);0 o. A/ v: a4 N) K4 [, x" w% ]
mButtonSetting.setVisibility(View.GONE);
* D. u2 e7 w0 W" x mButtonUpload.setVisibility(View.GONE);
4 G w: C; E$ u( O/ b mButtonStart.setVisibility(View.GONE);
1 S" u4 M' a' _$ i) a0 k% i8 d, L mButtonStop.setVisibility(View.GONE);
& l/ J( m' X" i) k1 I waypointList.clear();6 G4 C7 |2 a0 w* G- e
mSQLiteHelper = new SQLiteHelper(SettingRouteActivity.this);/ R0 d& D- R+ P2 L; y {/ j3 F' N
Cursor c = mSQLiteHelper.doSelectWaypoint(id);
; l( }: p' c$ ~& A# {* D$ Z if (c != null) {$ F# Z( U* _/ J1 y0 V4 E8 r
if (c.moveToNext()) {- |. x8 _2 C0 z) ?" g
MyLog.d("航点:" + "{'pointInfo':" + c.getString(1) + "}");. A( W+ S3 j. h' m
mPointInfo.addAll(GsonUtil.GsonToBean("{'pointInfo':" + c.getString(1) + "}", Root.class).getPointInfo());$ K0 M& ?1 I. V0 W6 X' p! u; s# m( V/ b
altitude = c.getFloat(2);
. ]/ h7 o' J; E! |3 Y mSpeed = c.getFloat(3);2 x" r$ f4 |+ [
switch (c.getString(4)) {9 s, l" _4 S" l* ]/ R4 p
case "0":$ q2 ] B0 ^& T5 N
mHeadingMode = WaypointMissionHeadingMode.AUTO;+ Y- y# t+ `6 p( x3 ]
break;8 B y$ e1 ~5 g8 }. Z- I M
case "1":& V3 P$ o, C6 J
mHeadingMode = WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
/ T9 i6 d* T$ S6 s6 i0 I) V1 j- L break;5 {- Q0 ~% f" m" q- m! m2 J
case "2":
- r! C$ B2 e! [+ @; F( Z/ u/ h mHeadingMode = WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;1 T/ m0 L4 Y7 e: _ v0 d
break;
7 \, `+ @6 k+ v1 M5 T5 N' | case "3":
8 i: g0 ]/ L2 L mHeadingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;
3 m: @2 [% M, C5 [6 \ break;3 }" n3 I6 e: ?6 n6 @3 C& S
case "4":4 a/ n1 m" k* S6 j7 i8 H9 K
mHeadingMode = WaypointMissionHeadingMode.TOWARD_POINT_OF_INTEREST;
/ i. e, h& \# Y) C break;) M: [; j. d- ?& {# x
}8 h$ i+ Q+ `1 J
switch (c.getString(5)) {! ~- V- t% o+ |3 f2 |. ]/ ^& V% B
case "0":! @2 I2 x4 ?8 B) M
mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
# I! @) m" B, Y6 n break;
; a. m0 T/ ]8 O( j case "1":
) Z u/ S4 o9 Z0 _5 N% U mFinishedAction = WaypointMissionFinishedAction.GO_HOME;
I7 h! {% n+ H5 r9 v' ]$ l+ v9 w- f% K2 L break;: {; \4 ^& g z: t* Q# X! F
case "2":& v0 A+ A! H6 n7 r8 A
mFinishedAction = WaypointMissionFinishedAction.AUTO_LAND;
$ A' q! ~5 h9 K" v$ ^8 W break;
; N2 e$ g8 M5 a+ c6 H/ x# p& i/ E case "3":
4 g d Y; ^* m% x$ U mFinishedAction = WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;1 V0 v- q! e. `' r/ o5 z. L! o4 A( H
break;! {3 N& b5 n' K1 F" R. r
case "4":
* H5 m( r. j/ j2 j, L* } mFinishedAction = WaypointMissionFinishedAction.CONTINUE_UNTIL_END;1 H8 y5 c( w- V( M) d
break;
6 L+ @4 p" X( w4 q; _* O# Z }
/ R- U- u4 t; \) V% S8 O }1 o$ v* ?' b( J2 C# V
}7 T5 r8 H4 w1 H: F1 T4 h
for (int i = 0; i new LatLng(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude()));* o. D- ^- r* [- U/ t6 U: P
Waypoint mWaypoint = new Waypoint(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude(), altitude);
# J9 Q5 M m$ p, Y6 J$ a if (waypointMissionBuilder != null) {
& l0 e, N) ^8 j% @/ _' X* C: u: o waypointList.add(mWaypoint);
( Q% K X6 x( x waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());" D2 e5 F. K2 B+ T* q
} else {) W* v* c& ~$ ?) x) F
waypointMissionBuilder = new WaypointMission.Builder();
0 ^ Y4 t- a V: S waypointList.add(mWaypoint);
/ z, {2 {1 ~ m4 e* Q b waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());0 G9 [1 b( ~) m% x: [$ s0 g2 _
}
; G. l6 Z$ Q9 I$ U }
- v8 A0 ]( v2 ]) @2 j t9 S% O aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(mPointInfo.get(0).getLatitude(), mPointInfo.get(0).getLongitude()), 18, 0, 0)));
4 X4 i/ e2 w1 r3 l* E8 r6 X ResultconfigWayPointMission();
- t$ l) A, j( f7 d2 J getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {0 i1 m- `2 r' e3 H3 n$ d' _
@Override
. d2 H/ T9 ~: z! q3 c# }/ o public void onResult(DJIError djiError) {
( y, U n0 I- s. A$ Z if (djiError == null) { r$ @* j$ v, P1 @( ~
showToasts("获取任务成功!");' Y R& E: f' ~9 W$ I% _
}
8 S" w/ e/ N# C! m& j6 i$ @' s9 ] }% g$ i& f& l" D; E
});+ C4 |( S7 c6 U1 D4 w
}9 Y. W: d+ `8 k0 _; k
private void showWaypoint(LatLng point) {* t" |% O ^$ p" {$ Q0 k0 f
MarkerOptions markerOptions = new MarkerOptions();5 ?' p9 K& ~% k7 q/ C" I
markerOptions.position(point);
: ]7 O! ]$ `% |# @: S: o markerOptions.title("航点" + (mMarkers.size() + 1));8 H* X! p- U3 [/ o% { A+ Q i% x+ n# r
markerOptions.snippet("事件:");+ K( H& l2 X# J
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));3 K k1 I! x& A# F0 t0 d
markerOptions.infoWindowEnable(true);
! v1 @: J7 g9 j0 ^1 T8 Z! k* m% ? Marker marker = aMap.addMarker(markerOptions);# f0 Y- R6 w+ W' i8 T; `
mMarkers.put(mMarkers.size(), marker);' f0 o6 A' [$ u! S, d
marker.showInfoWindow();
/ {: ~' ?4 M5 ~3 ~& `0 G if (mMarkers.size() > 0) {
6 j8 `' z! {( ?( N$ |% v0 ` Y mLatLng.clear();
0 k* U/ C' i8 N L( E/ c PolylineOptions PolylineOptions = new PolylineOptions();
$ {7 G( y% u6 h9 A3 x) { for (int i = 0; i 10);
/ e' U( n, L2 } K+ @# h- @ PolylineOptions.color(Color.argb(255, 1, 1, 1));
0 Z6 e0 O4 X& P' k* b; s aMap.addPolyline(PolylineOptions);* p. W" E8 d5 L) O" k7 {2 d
}
0 P+ o+ k) Q& l+ D, ? }
5 s* \( u. }9 X private void ResultconfigWayPointMission() {% Z j3 Y8 @% y
if (waypointMissionBuilder == null) {
7 \# i6 C- b& ?! ]+ G# g9 ]+ } waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)
7 I% D( }8 ]+ i1 r& C: y/ R .headingMode(mHeadingMode)
+ z+ q1 R& I; E- v# r3 @, C .autoFlightSpeed(mSpeed)
7 g- ]4 Q+ I8 V( w) L& V .maxFlightSpeed(mSpeed)
' {; l) l' {6 m3 v& L .flightPathMode(WaypointMissionFlightPathMode.NORMAL);
2 O* Z% _; U( ?8 h* b } else {
+ O+ `4 \: G. X9 g5 @3 X waypointMissionBuilder.finishedAction(mFinishedAction)1 ~8 M) n2 z+ v% S7 f. B6 Y+ D
.headingMode(mHeadingMode)
! ?% j% H5 N& H* ? .autoFlightSpeed(mSpeed)
0 z$ O- G8 I1 @0 [* @! F6 y .maxFlightSpeed(mSpeed)
3 R, \6 m8 ]% X. C% K- ^$ \ .flightPathMode(WaypointMissionFlightPathMode.NORMAL);% y: U5 K* c( [0 ]# n" ~
}* C# o1 g: \+ j4 A- H
if (waypointMissionBuilder.getWaypointList().size() > 0) {* n1 u+ k. K9 G3 r1 e; t7 B
for (int i = 0; i if (error == null) {
8 f0 L ], z! k. X if (mLinearLayoutInformation.getVisibility() == View.GONE) {2 u4 R6 B, H' U3 C1 I% @% V
mLinearLayoutInformation.setVisibility(View.VISIBLE);# E: I& s9 N, w9 @
}
/ v+ B9 ]/ q. O6 J6 q& ~' e$ J mButtonStart.setVisibility(View.VISIBLE);( s) k& q% V8 Q$ p! m" q* J
mButtonStop.setVisibility(View.VISIBLE);
3 G, D; F6 x+ b+ z1 u/ Y) R5 Z, b mTextViewHeight.setText("高度:" + altitude + "m");
' `% u1 J0 b5 a8 G9 U; n7 T mTextViewSpeed.setText("速度:" + mSpeed + "m/s");
4 h r: @. f* u mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());, {" k, H" j+ c& K: T b' B
mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
. i2 \3 }$ | V8 ^0 | mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
' [" `, B: b4 b1 Q. r E* K" f }
& i: M4 L8 D# x' F }
( V" h }' ~3 y" o7 e5 D3 Q private void addSampleMarker() {& M: }0 }: z/ R+ p& i
if (ReadKml.addSampleSuccess) {
6 v* |' U1 J! g5 M6 t! R aMap.clear();
5 R3 }- V2 U2 r2 w' S mMarkers.clear();4 G( Y \/ p7 o4 S; u
mPointInfo.clear();7 E& S1 F C! `2 K
waypointList.clear();! ~: j- P0 _4 l( f
if (mLinearLayoutInformation.getVisibility() == View.VISIBLE) {7 e, O, n" I5 y+ M- k
mLinearLayoutInformation.setVisibility(View.GONE);
' L x1 `0 Q- o$ f* V7 W }% h' o9 {' }& t) @" ?
mButtonFinish.setVisibility(View.GONE); P0 R0 d& N% r- h" z3 Y5 h
mButtonSetting.setVisibility(View.GONE);; u, j( e6 F$ Y5 R2 k
mButtonUpload.setVisibility(View.GONE);
6 M" c' ~! J3 g" l0 W mButtonStart.setVisibility(View.GONE);/ w8 f; m0 n. C
mButtonStop.setVisibility(View.GONE);; x* W+ k3 G8 M: R+ K
for (int i = 0; i new LatLng(sampleList.get(i).getX(), sampleList.get(i).getY()));4 G) S9 Z' \, C' k8 p% s3 l
Waypoint mWaypoint = new Waypoint(sampleList.get(i).getX(), sampleList.get(i).getY(), altitude);
. s3 R! l. a: ~2 v# f6 f" t' u //Add Waypoints to Waypoint arraylist;
; B! S; a1 v8 H6 u1 N; t! l5 j, { if (waypointMissionBuilder != null) {" c0 U, h( ]( {, P" t
waypointList.add(mWaypoint);+ k9 p; Z, J2 m$ _5 t% V
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
1 j. V% U% y5 a# `! v4 k } else {& V+ F& S9 Z3 U" G) Z7 p
waypointMissionBuilder = new WaypointMission.Builder();
- x) r( }9 }9 [3 k3 F% ^! ^* x waypointList.add(mWaypoint);% I0 z3 N2 s$ R! d2 ?
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());& ?4 t5 E7 Q' [
}
& i0 j9 _$ ?% h1 r7 b' n9 | }7 t, H9 m; k9 S8 Z! x t
aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(sampleList.get(0).getX(), sampleList.get(0).getY()), 18, 0, 0)));; @" `/ }1 S" I
showSettingDialog();
8 R: J- w3 q O5 @) ? _, d! W mButtonSetting.setVisibility(View.VISIBLE);
3 K$ `# {6 ~& _2 ?3 F mButtonUpload.setVisibility(View.VISIBLE);; M9 V0 q8 Z/ j% k6 T6 O! ~$ r
} else {
( N, x9 o% e* v Log.d("MainActivity", "addSampleSuccess is false or aMap is null");; W/ }2 l5 L8 @. u# J/ x
}+ j5 ^$ \9 ^# _1 x& K
}
3 j# O' ~3 Q9 v9 i5 q9 K4 R- u: W6 u& A1 j0 u l
3
/ S; L2 r" u9 H7 A- P. V2 t* |航线管理& a* { ~6 k* ?& |0 c) n
创建activity_waypoint.xml和WaypointActivity文件。2 t( D4 m) C" F$ K8 K# H
& B+ t( {( n1 L8 E2 t) U9 J+ Q
activity_waypoint.xml' e6 o+ q' H* B. n6 C+ s2 l
" S0 S8 I6 S' ^0 s' E4 d [LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
% E4 ^/ ?7 h# F- f xmlns:app="http://schemas.android.com/apk/res-auto"
+ J' M( }9 U& b xmlns:tools="http://schemas.android.com/tools": z7 ^2 f3 z6 u! H# w
android:layout_width="match_parent"
3 r6 A F8 {: a$ v android:layout_height="match_parent"6 I7 n0 p3 B3 e. F* U5 U
tools:context=".ui.WaypointActivity" N& J- N# J/ [" d* C/ U W6 o
android:orientation="vertical"5 X4 X' X5 T5 u1 G' W
android:background="@drawable/shape_corner_eight">5 B* F- i+ G& w5 x1 n1 t# w
include
6 @* b9 H z- i2 S android:id="@+id/layout_waypoint"# W: ~" `- d8 o
layout="@layout/activity_toolbar">include>5 `. S; a9 X/ @" ]7 k/ ?
View8 O& N4 z( _8 ^( i
android:layout_width="match_parent"& @2 H" U7 _7 I& u# |$ f
android:layout_height="1dp"3 r7 r" j4 ~4 _2 u) g7 e/ v T
android:background="#5B6782", o6 N7 ?) d X% }5 I" |
android:layout_marginTop="1dp"1 @+ r! r+ q; H R$ I. r L
android:layout_marginRight="20dp"
' m$ h* b8 Q/ ^7 a: o; e android:layout_marginLeft="20dp"
. E! N; W" V! p, ~ >View>% |' v! ]9 Z5 ~4 l7 u
androidx.recyclerview.widget.RecyclerView% s' S+ }1 ~0 l' L
android:id="@+id/rv_waypoint"- G1 Z; O! [4 B3 P9 A
android:layout_width="match_parent"
0 L# W9 J6 u: w5 e' ] android:layout_height="match_parent"& {$ s& b4 ~% G
android:layout_marginRight="20dp"
0 Q9 `7 v" J a3 O2 d android:layout_marginLeft="20dp">androidx.recyclerview.widget.RecyclerView>9 d6 k( R" C7 F$ s$ a
LinearLayout>- a6 i O; X; n; K2 W' h& C& Y
WaypointActivity0 o0 r* U# u" j8 d7 U/ c% O1 d# A
+ c7 p" g8 V% B. j0 t/ @* c
@Layout(R.layout.activity_waypoint)3 e$ z; K' A! E3 o2 B
public class WaypointActivity extends BaseActivity implements View.OnClickListener {7 {- V! q0 p/ `9 u
@BindView(R.id.layout_waypoint)+ k; t( ]6 K# }# w2 O5 d
View mViewLayoutToolbar;! |. b9 h( k8 y2 a( A
@BindView(R.id.ll_waypoint)1 |) G4 @7 M4 L: ^/ s0 a
LinearLayout mLinearLayout;
( v$ S3 O/ t- I+ h9 C @BindView(R.id.tv_toolbar_title)
7 w. w2 B" o7 y/ \ TextView mTextViewToolbarTitle;) @4 p' |* t4 I' p# j
@BindView(R.id.rv_waypoint)( X3 u' f2 `; N4 i4 S
RecyclerView mRecyclerView;
8 N: T. @! @+ p9 \ private SQLiteHelper mSQLiteHelper;, @7 h s* a0 {- ~
private List mWaypointInfo = new ArrayList();
3 _; M: r8 `8 w5 ^ private WaypointAdapter mWaypointAdapter;; b5 R6 l! f1 ^( }$ @- k: r
private List[I] mWaypointId = new ArrayList();+ \/ U m$ I: x7 X0 ] ]
private String StrId = "";
; H* e, `- A4 ] ^5 i" ] @Override* [+ r2 C2 ~) O, G; e
public void initViews() {
6 U+ I) i$ B4 t- s0 j/ t mLinearLayout.setVisibility(View.VISIBLE);( }; ~/ n! U4 a9 }5 [6 y
mTextViewToolbarTitle.setText("航线管理");3 ^1 N* K: M* C5 I* N, V
MyStatic.isChoose = false;
( s2 u- P r8 ]4 I }# z+ a. T2 L: C& h
@Override
! [! x6 O: q& x0 g* ^: ?7 z public void initDatas() {' f |; q; ~# y6 L# m+ g. v
mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);- `( N! W, F) N5 v3 j: f/ t( w
Cursor c = mSQLiteHelper.doSelect();2 w Y# j: G1 \/ M! v4 O1 L3 b
if (c!=null){
) s% R& h% U9 J+ h/ [, i: n3 V: F while (c.moveToNext()){9 H0 B+ g; ] s# W# Y3 Q
mWaypointInfo.add(new WaypointInfo(c.getInt(0),c.getString(1),c.getFloat(2),c.getFloat(3),6 w/ H3 n$ ?+ i2 V+ [, d+ e" S
c.getString(4),c.getString(5),c.getString(6),c.getInt(7),c.getInt(8),
8 [' v( H. D7 d/ g$ l) O c.getInt(9),c.getString(10)));5 ?0 M0 V. k9 y
}
2 n; g+ H; N8 q1 Z2 W: K+ e0 P3 M }
- f$ Y0 I$ H ~! V, c c.close();' x% O# E0 }# F! ]1 q# a& X1 v2 s
mSQLiteHelper.close();
0 W; x0 [* I) r* U3 b+ p* Q mWaypointAdapter = new WaypointAdapter(R.layout.item_waypoint);
, I' u/ U, F$ i8 ^1 _: E- o mWaypointAdapter.setNewData(mWaypointInfo);( q% S7 Q; d1 a+ B# z( f# v% e0 p: r
initRv(mRecyclerView,mWaypointAdapter);
9 b: X5 k! X& v7 E b) @ mWaypointAdapter.setOnItemchildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {, x* r8 U1 o% b, R! I' {
@Override
' g* n8 ?2 Q, A2 V8 s public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
% l8 y. M" P) d/ K; X Intent intent = new Intent();8 u" G$ w/ k$ z6 k5 b9 v6 u
intent.putExtra("id", mWaypointInfo.get(position).getId());$ J! M; V* y3 i3 o+ n
setResult(RESULT_OK, intent);0 F) b8 \: h/ L8 m
finish();4 b4 G% d/ ^2 U, D
}
4 k, `$ l/ J' a });
; s0 h; W) ]: I9 [9 R: ]7 {/ I# p mWaypointAdapter.setOnCheckboxCheckedListener(new WaypointAdapter.OnCheckboxCheckedListener() {
8 O% j2 N1 U5 P9 N8 @. a t2 w: b @Override
& W( E; R% P! n% u; a# o public void OnCheckboxChecked(boolean isCheck, int position) {
) X/ Z. h" D7 _0 O$ q. w if (isCheck){% W2 W- G1 I& i0 B
mWaypointId.add(position);# x1 e% v3 O9 r* @6 I
}else {
u7 n! r$ t1 \ if (mWaypointId.contains(position)){
3 U* M+ V& N: z; D- t, s mWaypointId.remove(position);
( m* H# \+ O" i }! W; ?" I5 d3 ~) g- v3 y* d
}
$ q7 C) h' x4 q. Y* K }
' L4 C6 o3 k1 L });5 |( ~0 c: T) F- e8 `
}$ a$ G$ C1 q; J1 b8 `+ z
@Override
0 o! h5 p5 s$ E/ F5 R. Y protected void requestData() {, I; r8 c4 D- i Z& ?
}
! D: F* ^3 F: [: ~7 k @OnClick({R.id.img_way_choose,R.id.img_way_delete,R.id.img_back})
: z1 M8 l4 w$ u% s @Override* @/ r8 _& |$ ?* T0 j$ T
public void onClick(View v) {. B% @5 \: O8 W& i) i
switch (v.getId()){
! H) z! Z4 f x. U: W case R.id.img_way_choose:
+ g( O- z) ~& X7 o, a4 w if (MyStatic.isChoose){% X/ B# q8 c% f, R
MyStatic.isChoose = false;3 ~ H5 t j& f. d V/ m, V2 l
}else {
% h( A8 Y5 ]: F4 Z2 r$ A" w& x MyStatic.isChoose = true;( `2 J3 |. W- }. T. y
}
( m1 k0 V9 X# d: c( L' D6 z n- U if (mWaypointAdapter!=null){( P3 O0 J! D* }
mWaypointAdapter.notifyDataSetChanged();& H; c7 k# S$ R8 [5 }6 u
}- ~" \7 `/ P; [/ Z7 n3 E
break;
& [1 u7 o. y7 O* [) Q case R.id.img_way_delete:
6 x5 y4 d4 T0 N7 Z' \' w! V if (mWaypointId.size() > 0){& W6 ]2 ~- ~& U# e7 m
for (int i = 0; i ",";
* D" p- w- J$ r4 X( c }5 O6 P) I1 y# v0 T1 j( s
if (!TextUtils.isEmpty(StrId)){. _, j* H# J6 b, h
StrId = StrId.substring(0,StrId.length()-1);
1 d/ w& @/ @% M7 s0 y4 c mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);! E! z2 m4 h( Q/ N0 I( n
mSQLiteHelper.doDelete(StrId);. v& z# b# E1 b' M
mSQLiteHelper.close();) A/ }- g- R' M. _1 x" k0 W
for (int j = 0; j if (mWaypointAdapter!=null){
) Q* x& b* d% [; h1 L( b mWaypointId.clear();0 |+ K, c& `. M& O }' ]) w1 S: D
MyStatic.isChoose = false;$ j C8 Z+ t3 @
mWaypointAdapter.setNewData(mWaypointInfo); b2 Z! y% Q* }5 F
}
6 o4 ]& u# C2 M7 [ }4 k8 e! B$ M- b, X# Q' D# G
}else {
& }- Y0 A# j7 m0 a9 f6 [9 e showToasts("请先选择删除的航线!");
0 I6 I. Z/ g1 p" ~ }) ^/ R C3 b: h
break; l& M3 R* J# _1 w. I2 a& a1 P
case R.id.img_back:
3 \& U/ I) e! \3 `6 D6 u* m Intent intent = new Intent();
; l9 L, X7 l. @4 X intent.putExtra("id", -1);3 d* P" H! r4 _/ _5 |
setResult(RESULT_OK, intent);
' a1 _$ I' p4 ~ finish();0 q* v# ^4 r- T$ v
break;
, S: R7 B; @; o1 w }
" f) [6 _* w& j: R9 d* s }; g5 D7 L# M0 _+ {
以上代码仅供参考,如果想了解更多的大疆无人机二次开发过程可以私信我,源代码因为涉及到商业使用不能给大家共享,有什么问题我可以帮你解决。' e; T9 W& G/ [; P
g2skp2214zg64015953311.png
% ~: O" V0 _. Y往期推荐毕业设计So Easy:基于C++实现网络扫描器
" P6 E% ?# S: O; Z7 T详解CAN总线:CAN节点硬件构成方案
) t+ E6 o* n9 j) ^' |! xLabVIEW串口通信
O3 u! s4 O9 [1 VLabVIEW感兴趣区域分析(实战篇—1)! [, f, w6 T Z% g3 Q v! l
Python Qt GUI设计:信号与槽的使用方法(基础篇—7)/ V; a: M h9 R. M6 W/ Q
和12岁小同志搞创客开发:如何使用继电器?' D2 R3 H5 P- t4 h
PCB天线无线模组如何布局摆放?
Z6 N# n) t; y9 h, }! ^芯片内部长啥样?牛人用1500张照片,一层一层放给你看!( |1 P3 q0 U1 g0 |
移柯L620模组使用MQTT协议连接移动OneNet云平台* x) B9 G* H) G n
9 R; f0 Z3 @6 O2 @ C c
yvmel1ho04t64015953411.jpg
' v4 x4 m' b4 Z
wrl20dowmf064015953511.gif
# B. n$ k- r# t8 a* r6 R* u点击阅读原文,更精彩~ |
|