|

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