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