|

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