前言
開發者在面對配送行業場景,諸如外賣,B2C零售,商超等需要路線規划的功能,尤其網約車行業,還需要用到計算路費、動畫模擬小車在路線上行駛等功能,這個騰訊位置服務產品的小demo就可以實現定位、規划路線、計算距離和路費,以及模擬小車平滑移動等基礎功能。
實現步驟
先看下實現效果:
新建個Android項目並新建個Activity,命名為DrivingRouteActivity,先來畫一下UI布局,布局比較簡單,由一個騰訊SDK包下的地圖組件MapView,以及兩個用於輸入起始位置的輸入框,兩個確認路線規划的Button,一個定位當前位置的ImageView,一個用於顯示行程信息的TextView組成,布局代碼只是為了方便展示實現功能,所以下面直接貼出布局代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.DrivingRouteActivity">
<com.tencent.tencentmap.mapsdk.maps.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="bottom"
android:paddingTop="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/from_et"
android:hint="您在哪兒上車"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="50dp"></EditText>
<ImageButton
android:id="@+id/location_ib"
android:background="@drawable/sendtocar_balloon"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:layout_width="50dp"
android:layout_height="50dp"></ImageButton>
</LinearLayout>
<EditText
android:id="@+id/to_et"
android:hint="您要去哪兒"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></EditText>
<TextView
android:id="@+id/orderdesc_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20sp"></TextView>
<Button
android:id="@+id/confirm_btn"
android:text="確定"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:visibility="gone"></Button>
<Button
android:id="@+id/order_btn"
android:text="預約快車"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></Button>
</LinearLayout>
</LinearLayout>
1.賬號注冊與配置
在開發之前,我們需要到騰訊位置服務官網注冊一個賬號
注冊后進入控制台
選擇key管理,點擊創建新秘鑰,按照申請信息提交申請
將上面申請的key在application標簽下進行如下配置(value替換成自己的key)
<meta-data
android:name="TencentMapSDK"
android:value="XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" />
2.引入騰訊Android地圖SDK
進入Android地圖SDK,下載3D版地圖SDK壓縮包
下載完成后打開壓縮包,將libs文件夾下的jar包拷貝到app的libs目錄下,右鍵該jar包選擇add as library添加為依賴,並且在項目app\src\main路徑下建立名為jniLibs的目錄,把壓縮包libs/jniLibs/strip文件夾下的所有包放到jniLibs目錄下
引入后在AndroidManifest.xml文件下配置相關權限
<!-- 訪問網絡獲取地圖服務 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 檢查網絡可用性 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 訪問WiFi狀態 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 需要外部存儲寫權限用於保存地圖緩存 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 獲取 device id 辨別設備 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
3.地圖初始化
配置完成,現在開始實現我們的邏輯交互,為了讓實現邏輯更加清晰,我將業務邏輯代碼與視圖渲染代碼分到了兩個包中,除了activity包中的DrivingRouteActivity之外,新建了一個present包,並在包下建立一個DrivingRoutePresent類,分別由DrivingRouteActivity負責對UI組件進行視圖渲染,由DrivingRoutePresent類負責業務邏輯。這里我還新建了一個contract包,並創建一個DrivingRouteContract接口,通過這個接口定義的方法,實現DrivingRoutePresent與DrivingRouteActivity之間的交互。我們在DrivingRouteContract接口中定義兩個接口,一個View接口供DrivingRouteActivity實現,一個Presenter接口供DrivingRoutePresent實現,並定義一些初始化的方法
public interface DrivingRouteContract {
interface View{
void initView();//初始化View
void initOnClick();//初始化OnClickListener
void setOrderDescTV(String content);//渲染訂單行程信息
EditText getFromET();
}
interface Presenter{
void attachView(DrivingRouteContract.View view);//綁定View
}
}
接着再讓DrivingRouteActivity實現DrivingRouteContract.View接口並聲明UI中的組件進行初始化
public class DrivingRouteActivity extends Activity implements DrivingRouteContract.View, View.OnClickListener {
private MapView mapView;
private TencentMap mMap;
private Button confirmBtn;
private Button orderBtn;
private ImageButton locationIB;
private EditText fromET;
private EditText toET;
private TextView orderDescTV;
private DrivingRoutePresent drivingRoutePresent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_driving_route);
initView();
initOnClick();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.order_btn:
//實現行程路線規划
break;
case R.id.confirm_btn:
//開啟動畫移動
break;
case R.id.location_ib:
//定位當前位置
break;
}
}
/**
* mapview的生命周期管理
*/
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onRestart() {
super.onRestart();
mapView.onRestart();
}
@Override
public void initView() {
mapView = findViewById(R.id.mapview);
confirmBtn = findViewById(R.id.confirm_btn);
orderBtn = findViewById(R.id.order_btn);
locationIB = findViewById(R.id.location_ib);
fromET = findViewById(R.id.from_et);
toET = findViewById(R.id.to_et);
orderDescTV = findViewById(R.id.orderdesc_tv);
mMap = mapView.getMap();
drivingRoutePresent = new DrivingRoutePresent();
drivingRoutePresent.attachView(this);
}
@Override
public void initOnClick() {
orderBtn.setOnClickListener(this);
confirmBtn.setOnClickListener(this);
locationIB.setOnClickListener(this);
}
@Override
public void setOrderDescTV(String content) {
orderDescTV.setText(content);
}
@Override
public EditText getFromET() {
return fromET;
}
}
DrivingRoutePresent實現DrivingRouteContract.Presenter接口
public class DrivingRoutePresent implements DrivingRouteContract.Presenter {
private DrivingRouteContract.View drinvingRouteView;
@Override
public void attachView(DrivingRouteContract.View view) {
drinvingRouteView = view;
}
}
因為我們后面在多個地方都需要用到當前應用的上下文,為了方便,需要再編寫一個全局的應用上下文工具類來幫助我們獲取上下文,建立一個util包並創建一個GlobalApplication類
public class GlobalApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext(){
return context;
}
}
同時,在Android類文件的application標簽中加入下面屬性,讓應用啟動時加載上面的GlobalApplication
android:name=".util.GlobalApplication"
到這里,我們就完成了界面與業務代碼的基本設計,運行app,可以看到顯示的基本地圖信息。接下來我們來實現一下路線規划的功能。騰訊官方Android地圖SDK開發文檔對路線規划服務和地址解析都有較詳細的說明。
另外還提供了調用示例Demo。如果不清楚如何調用的話可以參考官方Demo或參考下面代碼。
4.地址解析與路線規划
首先我們在DrivingRouteContract.Presenter接口申明一個用於通過地址查找經緯度的geocoder方法和一個用於路線規划的routePlan方法
public interface DrivingRouteContract {
interface View{
void initView();//初始化View
void initOnClick();//初始化OnClickListener
void setOrderDescTV(String content);//渲染訂單行程信息
EditText getFromET();
}
interface Presenter{
void attachView(DrivingRouteContract.View view);//綁定View
void geocoder(String address, Integer type);//地址解碼,轉經緯度
void routePlan();//實現路線規划
}
}
通過騰訊Android地圖SDK路線規划服務的開發文檔,我們了解到要獲得規划路線需要先獲取起點和終點的經緯度,而在一般業務場景中,我們幾乎不會讓用戶手動輸入經緯度,所以我這里還需要用到地址解析服務,通過輸入中文地址來獲取經緯度,再通過經緯度規划路線(不過在實際業務中最好是加上關鍵詞輸入提示這個服務,方便用戶找到輸入的位置)。
在DrivingRoutePresent類中實現這兩個方法
public static final Integer FROM_TYPE = 0x100; //獲取起始位置坐標
public static final Integer TO_TYPE = 0x101; //獲取目的位置坐標
private LatLng fromLatLng;
private LatLng toLatLng;
/**
* 地址解碼
* @param address 傳入需要解碼的地址
* @param type 地址類型,起始位置、目的位置
*/
@Override
public void geocoder(String address, final Integer type) {
TencentSearch tencentSearch = new TencentSearch(GlobalApplication.getContext());
Address2GeoParam address2GeoParam =
new Address2GeoParam(address);
tencentSearch.address2geo(address2GeoParam, new HttpResponseListener<BaseObject>() {
@Override
public void onSuccess(int arg0, BaseObject arg1) {
if (arg1 == null) {
return;
}
Address2GeoResultObject obj = (Address2GeoResultObject)arg1;
if (obj.result.latLng != null) {
if (type==FROM_TYPE)
fromLatLng = obj.result.latLng;
else if (type==TO_TYPE)
toLatLng = obj.result.latLng;
routePlan();
}
}
@Override
public void onFailure(int arg0, String arg1, Throwable arg2) {
Log.e("test", "error code:" + arg0 + ", msg:" + arg1);
}
});
}
private TencentSearch tencentSearch = new TencentSearch(GlobalApplication.getContext());
private StringBuffer lineStringBuilder = new StringBuffer();//路線坐標
private Double taxiFare = 0d;//預估打車費用
private Float distance = 0f;//預計全程里程
/**
* 路線規划
*/
@Override
public void routePlan() {
if (fromLatLng!=null&&toLatLng!=null){
Toast.makeText(GlobalApplication.getContext(), "正在為您規划路線", Toast.LENGTH_SHORT).show();
DrivingParam drivingParam = new DrivingParam(fromLatLng, toLatLng);
drivingParam.policy(DrivingParam.Policy.TRIP);//駕車路線規划策略,網約車場景,送乘客
drivingParam.setCarNumber("粵A00001");//填入車牌號,在路線規划時會避讓車牌限行區域
tencentSearch.getRoutePlan(drivingParam, new HttpResponseListener<DrivingResultObject>() {
@Override
public void onSuccess(int i, DrivingResultObject drivingResultObject) {
for (DrivingResultObject.Route route : drivingResultObject.result.routes){
for (LatLng latLng : route.polyline){
lineStringBuilder.append(latLng.latitude + "," + latLng.longitude);
lineStringBuilder.append(",");
}
distance += route.distance;
taxiFare += route.taxi_fare.fare;
}
drinvingRouteView.setOrderDescTV("行程大約" + distance + "m,預計¥" + taxiFare + "元");
//清空行程路線,里程,費用信息
lineStringBuilder = new StringBuffer();
distance = 0f;
taxiFare = 0d;
}
@Override
public void onFailure(int i, String s, Throwable throwable) {
Log.d("DrivingRouteActivity", "onSuccess: " + s + i);
}
});
fromLatLng=null;
toLatLng=null;
}
}
其中geocoder方法用於獲得我們輸入的起始位置(從哪兒上車),以及輸入的目的位置(到哪兒下車)的坐標經緯度,記錄位置的經緯度后調用routePlan方法請求路線規划接口,並記錄下里程,費用信息,路線行駛過程中經過的點的經緯度(用於后面實現小車移動)。
路線規划接口除了上面使用的幾個常用參數外,還有很多接口參數,具體可以查看官方接口文檔按需要加入
5.車輛行駛動畫
有了路線規划方法后,給"預約快車"按鈕添加實現
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.order_btn:
drivingRoutePresent.geocoder(fromET.getText().toString(), DrivingRoutePresent.FROM_TYPE);
drivingRoutePresent.geocoder(toET.getText().toString(), DrivingRoutePresent.TO_TYPE);
confirmBtn.setVisibility(View.VISIBLE);
orderBtn.setVisibility(View.GONE);
break;
case R.id.confirm_btn:
//開啟動畫移動
break;
case R.id.location_ib:
//定位當前位置
break;
}
}
此時,運行APP,輸入起點和終點就可以獲得駕車的規划路線了
接下來,我們再實現一下效果圖上小車根據規划路線行駛的功能
在DrivingRouteContract.View接口中加入小車動畫初始化方法initAnimation
public interface DrivingRouteContract {
interface Model{
}
interface View{
void initView();//初始化View
void initOnClick();//初始化OnClickListener
void setOrderDescTV(String content);//渲染訂單行程信息
EditText getFromET();
void initAnimation(String line);//初始化小車移動動畫
}
interface Presenter{
void attachView(DrivingRouteContract.View view);//綁定View
void startLocation(boolean single);
void stopLocation();
void geocoder(String address, Integer type);//地址解碼,轉經緯度
void routePlan();//實現路線規划
}
}
實現initAnimation方法,關於Marker其他參數同樣參考上面的接口文檔
private Marker mCarMarker;
private LatLng[] mCarLatLngArray;
private MarkerTranslateAnimator mAnimator;
@Override
public void initAnimation(String line) {
//拆分獲得經緯度數組
String[] linePointsStr = line.split(",");
mCarLatLngArray = new LatLng[linePointsStr.length / 2];
for (int i = 0; i < mCarLatLngArray.length; i++) {
double latitude = Double.parseDouble(linePointsStr[i * 2]);
double longitude = Double.parseDouble(linePointsStr[i * 2 + 1]);
mCarLatLngArray[i] = new LatLng(latitude, longitude);
}
//添加小車路線
mMap.addPolyline(new PolylineOptions().add(mCarLatLngArray)
.color(R.color.colorLine));//這個顏色是colors.xml中自定義的顏色
//添加小車
LatLng carLatLng = mCarLatLngArray[0];
mCarMarker = mMap.addMarker(
new MarkerOptions(carLatLng)
.anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.taxi_t))//小車圖標
.flat(true)
.clockwise(false));
//創建移動動畫
mAnimator = new MarkerTranslateAnimator(mCarMarker, 50 * 1000, mCarLatLngArray, true);
//調整最佳視野
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(
LatLngBounds.builder().include(Arrays.asList(mCarLatLngArray)).build(), 50));
}
並在routePlan方法中調用這個方法,傳入行駛路線字符串
//初始化小車動畫
drinvingRouteView.initAnimation(lineStringBuilder.substring(0, lineStringBuilder.length()-1));
完整代碼參考
/**
* 路線規划
*/
@Override
public void routePlan() {
if (fromLatLng!=null&&toLatLng!=null){
Toast.makeText(GlobalApplication.getContext(), "正在為您規划路線", Toast.LENGTH_SHORT).show();
DrivingParam drivingParam = new DrivingParam(fromLatLng, toLatLng);
drivingParam.policy(DrivingParam.Policy.TRIP);//駕車路線規划策略,網約車場景,送乘客
drivingParam.setCarNumber("粵A00001");//填入車牌號,在路線規划時會避讓車牌限行區域
tencentSearch.getRoutePlan(drivingParam, new HttpResponseListener<DrivingResultObject>() {
@Override
public void onSuccess(int i, DrivingResultObject drivingResultObject) {
for (DrivingResultObject.Route route : drivingResultObject.result.routes){
for (LatLng latLng : route.polyline){
lineStringBuilder.append(latLng.latitude + "," + latLng.longitude);
lineStringBuilder.append(",");
}
distance += route.distance;
taxiFare += route.taxi_fare.fare;
}
//初始化小車動畫
drinvingRouteView.initAnimation(lineStringBuilder.substring(0, lineStringBuilder.length()-1));
drinvingRouteView.setOrderDescTV("行程大約" + distance + "m,預計¥" + taxiFare + "元");
//清空行程路線,里程,費用信息
lineStringBuilder = new StringBuffer();
distance = 0f;
taxiFare = 0d;
}
@Override
public void onFailure(int i, String s, Throwable throwable) {
Log.d("DrivingRouteActivity", "onSuccess: " + s + i);
}
});
fromLatLng=null;
toLatLng=null;
}
}
最后我們在"確定"按鈕的點擊事件上調用MarkerTranslateAnimator的startAnimation方法來開始動畫
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.order_btn:
drivingRoutePresent.geocoder(fromET.getText().toString(), DrivingRoutePresent.FROM_TYPE);
drivingRoutePresent.geocoder(toET.getText().toString(), DrivingRoutePresent.TO_TYPE);
confirmBtn.setVisibility(View.VISIBLE);
orderBtn.setVisibility(View.GONE);
break;
case R.id.confirm_btn:
//開啟動畫移動
mAnimator.startAnimation();
orderBtn.setVisibility(View.VISIBLE);
confirmBtn.setVisibility(View.GONE);
break;
case R.id.location_ib:
//定位當前位置
break;
}
}
6.引入騰訊Android定位SDK
基本效果已經完成了,現在還差最后一個定位功能,要實現定位功能需要引入另一個SDK(Android定位SDK)
我們打開Android定位SDK開發文檔,下載最新的SDK
將壓縮包內的jar包放入app的libs包下,並添加為依賴
再把壓縮包libs文件夾下的各個so文件拷貝到項目jniLibs的對應目錄中
打開AndroidManifest.xml文件,加入下面權限配置
<!-- 通過GPS得到精確位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 通過網絡得到粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 訪問網絡. 某些位置信息需要從網絡服務器獲取 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 訪問WiFi狀態. 需要WiFi信息用於網絡定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 修改WiFi狀態. 發起WiFi掃描, 需要WiFi信息用於網絡定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 訪問網絡狀態, 檢測網絡的可用性. 需要網絡運營商相關信息用於網絡定位 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 訪問網絡的變化, 需要某些信息用於網絡定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 訪問手機當前狀態, 需要device id用於網絡定位 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 支持A-GPS輔助定位 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!-- 用於 log 日志 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7.顯示當前定位
配置完成后,我們在DrivingRouteContract.Presenter接口中加入一個開始定位的startLocation和一個結束定位的stopLocation方法
void startLocation(boolean single);
void stopLocation();
再實現一下DrivingRoutePresent的方法
private boolean IS_SINGLE_LOCATION_MODE = false;//是否連續定位
private TencentLocationManager mLocationManager = TencentLocationManager.getInstance(GlobalApplication.getContext());
private TencentLocationRequest locationRequest;
@Override
public void startLocation(boolean single) {
IS_SINGLE_LOCATION_MODE = single;//因為這里只需要定位一次,所以加了個參數
locationRequest = TencentLocationRequest.create();
locationRequest.setInterval(5000);//定位間隔
//根據用戶獲取的位置信息的詳細程度,REQUEST_LEVEL_ADMIN_AREA:包含經緯度,位置所處的中國大陸行政區划
locationRequest.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA);
locationRequest.setAllowGPS(true);//是否允許使用GPS定位
mLocationManager.requestLocationUpdates(locationRequest, this);//連續定位
}
@Override
public void stopLocation() {
mLocationManager.removeUpdates(this);
}
除此之外,為了獲得定位的位置信息,我們還需要讓DrivingRoutePresent額外實現TencentLocationListener接口,實現onLocationChanged(用於接收定位結果)和onStatusUpdate(用於接收GPS,WiFi,Cell的狀態碼)方法。
@Override
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
if (IS_SINGLE_LOCATION_MODE)
stopLocation();
switch (i){
case TencentLocation.ERROR_OK:
//定位成功
drinvingRouteView.setLocation(tencentLocation);
//渲染定位信息
if (drinvingRouteView.getFromET()!=null&&drinvingRouteView.getFromET().getText().toString().trim().equals(""))
drinvingRouteView.getFromET().setText(tencentLocation.getAddress());
// Toast.makeText(GlobalApplication.getContext(), "定位成功", Toast.LENGTH_SHORT).show();
break;
case TencentLocation.ERROR_NETWORK:
Toast.makeText(GlobalApplication.getContext(), "網絡問題引起的定位失敗", Toast.LENGTH_SHORT).show();
break;
case TencentLocation.ERROR_BAD_JSON:
Toast.makeText(GlobalApplication.getContext(), "GPS, Wi-Fi 或基站錯誤引起的定位失敗", Toast.LENGTH_SHORT).show();
break;
case TencentLocation.ERROR_WGS84:
Toast.makeText(GlobalApplication.getContext(), "無法將WGS84坐標轉換成GCJ-02坐標時的定位失敗", Toast.LENGTH_SHORT).show();
break;
case TencentLocation.ERROR_UNKNOWN:
Toast.makeText(GlobalApplication.getContext(), "未知原因引起的定位失敗", Toast.LENGTH_SHORT).show();
break;
}
}
@Override
public void onStatusUpdate(String s, int i, String s1) {
//TencentLocationListener回調此方法傳入的GPS,WiFi,Cell狀態碼,具體狀態碼查看Android定位SDK開發文檔
}
最后,我們再把給定位的小按鈕綁定的點擊事件加上實現,在onResume和onPause方法調用一下startLocation和stopLocation方法讓app在開啟或切換回當前Activity時自動定位
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.order_btn:
drivingRoutePresent.geocoder(fromET.getText().toString(), DrivingRoutePresent.FROM_TYPE);
drivingRoutePresent.geocoder(toET.getText().toString(), DrivingRoutePresent.TO_TYPE);
confirmBtn.setVisibility(View.VISIBLE);
orderBtn.setVisibility(View.GONE);
break;
case R.id.confirm_btn:
//開啟動畫移動
mAnimator.startAnimation();
orderBtn.setVisibility(View.VISIBLE);
confirmBtn.setVisibility(View.GONE);
break;
case R.id.location_ib:
//定位一次
drivingRoutePresent.startLocation(true);
break;
}
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
drivingRoutePresent.startLocation(true);
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
drivingRoutePresent.stopLocation();
}
結尾
寫到這里,效果圖上所有的功能就基本完成了,總的來說,功能還是十分強大的,對於有相關需求的企業來說開發起來非常省時省力。另外開發文檔和接口文檔也比較詳細。由於時間有限,暫時只體驗了其中的幾個服務,有更多需求的同學可以自行到官網探索。