优化算路
This commit is contained in:
@@ -40,6 +40,12 @@
|
||||
android:name="com.amap.api.navi.AmapRouteActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|navigation" />
|
||||
<!--自定义导航 Activity-->
|
||||
<activity
|
||||
android:name="com.lnkj.ln_jq_app.NavigationActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|navigation"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.lnkj.ln_jq_app;
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -15,7 +14,6 @@ import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
|
||||
@@ -39,39 +37,6 @@ public class MainActivity extends FlutterActivity {
|
||||
"NativeFirstPage",
|
||||
new NativeMapFactory(this)
|
||||
);
|
||||
|
||||
// 注册方法通道用于地图控制
|
||||
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
|
||||
.setMethodCallHandler((call, result) -> {
|
||||
switch (call.method) {
|
||||
case "requestPermissions":
|
||||
requestPermissions();
|
||||
result.success(null);
|
||||
break;
|
||||
case "onResume":
|
||||
if (mapView != null) {
|
||||
mapView.onResume();
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "onPause":
|
||||
if (mapView != null) {
|
||||
mapView.onPause();
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "onDestroy":
|
||||
if (mapView != null) {
|
||||
mapView.dispose();
|
||||
mapView = null;
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,23 +98,6 @@ public class MainActivity extends FlutterActivity {
|
||||
this.mapView = mapView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// 注意:高德SDK合规检查通过后再进行定位相关操作
|
||||
// 这里仅保留地图生命周期调用,权限建议在Flutter端或按需触发
|
||||
if (mapView != null) {
|
||||
mapView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (mapView != null) {
|
||||
mapView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
@@ -160,13 +108,6 @@ public class MainActivity extends FlutterActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mapView != null) {
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.lnkj.ln_jq_app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
@@ -35,6 +36,7 @@ import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -60,7 +62,6 @@ import com.amap.api.navi.AmapNaviPage;
|
||||
import com.amap.api.navi.AmapNaviParams;
|
||||
import com.amap.api.navi.AmapNaviType;
|
||||
import com.amap.api.navi.AmapPageType;
|
||||
import com.amap.api.navi.enums.PathPlanningStrategy;
|
||||
import com.amap.api.navi.model.AMapCarInfo;
|
||||
import com.amap.api.navi.model.NaviPoi;
|
||||
import com.amap.api.services.core.AMapException;
|
||||
@@ -150,6 +151,8 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
|
||||
// 存储货车路线算法接口返回的数据
|
||||
private TruckRouteData truckRouteData;
|
||||
//当前定位信息
|
||||
private AMapLocation mLoc;
|
||||
|
||||
|
||||
public NativeMapView(Context context, int id, Object args) {
|
||||
@@ -171,6 +174,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
|
||||
container.addView(mapView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
initLoadingView(context);
|
||||
initData(context);
|
||||
initServices(context);
|
||||
initOverlays(context);
|
||||
@@ -194,6 +198,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
}
|
||||
|
||||
private LinearLayout bottomContainer;
|
||||
|
||||
private void initOverlays(Context context) {
|
||||
// --- 底部主容器 (包含两个互斥显示的面板) ---
|
||||
bottomContainer = new LinearLayout(context);
|
||||
@@ -392,6 +397,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
//最后调用监听函数
|
||||
addKeyboardListener();
|
||||
}
|
||||
|
||||
private void addKeyboardListener() {
|
||||
container.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
|
||||
Rect r = new Rect();
|
||||
@@ -412,6 +418,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateBottomMargin(int bottomPx) {
|
||||
if (bottomContainer != null) {
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) bottomContainer.getLayoutParams();
|
||||
@@ -422,6 +429,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LinearLayout createDetailPanel(Context context) {
|
||||
LinearLayout panel = new LinearLayout(context);
|
||||
panel.setOrientation(LinearLayout.VERTICAL);
|
||||
@@ -516,12 +524,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始规划前隐藏输入框面板
|
||||
searchArea.setVisibility(View.GONE);
|
||||
|
||||
RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(startPoint.latitude, startPoint.longitude), new LatLonPoint(endPoint.latitude, endPoint.longitude));
|
||||
RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
|
||||
routeSearch.calculateDriveRouteAsyn(query);
|
||||
fetchTruckRouteAlgorithm(mLoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -603,11 +606,10 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
}
|
||||
|
||||
//确定目的地坐标和名称
|
||||
// 优先级:用户手动选择 > truckRouteData (接口返回的精准点) > endPoint (地图点击/搜索的点)
|
||||
LatLng finalDestinationLatLng = null;
|
||||
String finalDestinationName = endName;
|
||||
|
||||
// 如果用户手动选择了目的地,直接使用用户选择的地址
|
||||
// 优先级:用户手动选择 > truckRouteData (接口返回的精准点) > endPoint (地图点击/搜索的点)
|
||||
if (isUserSelectedDestination && endPoint != null) {
|
||||
finalDestinationLatLng = endPoint;
|
||||
finalDestinationName = endName;
|
||||
@@ -619,8 +621,10 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
//防止 parseDouble 崩溃
|
||||
if (latStr != null && !latStr.isEmpty() && lngStr != null && !lngStr.isEmpty()) {
|
||||
try {
|
||||
finalDestinationLatLng = new LatLng(Double.parseDouble(latStr), Double.parseDouble(lngStr));
|
||||
if (truckRouteData.destinationSite.name != null && !truckRouteData.destinationSite.name.isEmpty()) {
|
||||
finalDestinationLatLng = new LatLng(Double.parseDouble(latStr),
|
||||
Double.parseDouble(lngStr));
|
||||
if (truckRouteData.destinationSite.name != null &&
|
||||
!truckRouteData.destinationSite.name.isEmpty()) {
|
||||
finalDestinationName = truckRouteData.destinationSite.name;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -640,64 +644,83 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
return;
|
||||
}
|
||||
|
||||
//构造起点和终点 POI
|
||||
Poi start = new Poi(startName, startPoint, "");
|
||||
Poi end = new Poi(finalDestinationName, finalDestinationLatLng, "");
|
||||
|
||||
//配置导航参数
|
||||
AmapNaviParams params = new AmapNaviParams(start, null, end, AmapNaviType.DRIVER, AmapPageType.ROUTE);
|
||||
|
||||
try {
|
||||
AMapNavi mAMapNavi = AMapNavi.getInstance(mContext);
|
||||
|
||||
// 设置车辆信息 (只有在数据完整时设置)
|
||||
if (truckRouteData != null && truckRouteData.truckDto != null) {
|
||||
AMapCarInfo carInfo = new AMapCarInfo();
|
||||
carInfo.setCarNumber(plateNumber); // 使用初始化时获取的车牌
|
||||
carInfo.setCarType(String.valueOf(truckRouteData.truckDto.mcarType));
|
||||
carInfo.setVehicleAxis(String.valueOf(truckRouteData.truckDto.mvehicleAxis));
|
||||
carInfo.setVehicleHeight(truckRouteData.truckDto.mvehicleHeight);
|
||||
carInfo.setVehicleLength(truckRouteData.truckDto.mvehicleLength);
|
||||
carInfo.setVehicleWidth(truckRouteData.truckDto.mvehicleWidth);
|
||||
carInfo.setVehicleSize(String.valueOf(truckRouteData.truckDto.mvehicleSize));
|
||||
carInfo.setVehicleLoad(truckRouteData.truckDto.mvehicleLoad);
|
||||
carInfo.setVehicleWeight(truckRouteData.truckDto.mvehicleWeight);
|
||||
carInfo.setRestriction(truckRouteData.truckDto.isRestriction);
|
||||
carInfo.setVehicleLoadSwitch(truckRouteData.truckDto.mvehicleLoadSwitch);
|
||||
|
||||
params.setCarInfo(carInfo);
|
||||
mAMapNavi.setCarInfo(carInfo);
|
||||
}
|
||||
|
||||
//处理途径点 (如果接口返回了 naviList)
|
||||
if (truckRouteData != null && truckRouteData.pathDto != null && truckRouteData.pathDto.naviList != null) {
|
||||
NaviPoi startNaviPoi = new NaviPoi(startName, startPoint, "");
|
||||
NaviPoi endNaviPoi = new NaviPoi(finalDestinationName, finalDestinationLatLng, "");
|
||||
|
||||
List<NaviPoi> waysPoiIds = new ArrayList<>();
|
||||
for (NaviPoint np : truckRouteData.pathDto.naviList) {
|
||||
if (np.coordinate != null && !TextUtils.isEmpty(np.coordinate.latitude) && !TextUtils.isEmpty(np.coordinate.longitude)) {
|
||||
try {
|
||||
double lat = Double.parseDouble(np.coordinate.latitude);
|
||||
double lng = Double.parseDouble(np.coordinate.longitude);
|
||||
waysPoiIds.add(new NaviPoi(np.name, new LatLng(lat, lng), np.poiId));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "途径点坐标解析错误: " + np.name);
|
||||
}
|
||||
//获取途径点
|
||||
List<NaviPoi> waysPoiIds = new ArrayList<>();
|
||||
if (truckRouteData != null && truckRouteData.pathDto != null && truckRouteData.pathDto.naviList !=
|
||||
null) {
|
||||
for (NaviPoint np : truckRouteData.pathDto.naviList) {
|
||||
if (np.coordinate != null && !TextUtils.isEmpty(np.coordinate.latitude) &&
|
||||
!TextUtils.isEmpty(np.coordinate.longitude)) {
|
||||
try {
|
||||
double lat = Double.parseDouble(np.coordinate.latitude);
|
||||
double lng = Double.parseDouble(np.coordinate.longitude);
|
||||
waysPoiIds.add(new NaviPoi(np.name, new LatLng(lat, lng), np.poiId));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "途径点坐标解析错误: " + np.name);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有途径点,主动触发算路逻辑
|
||||
if (!waysPoiIds.isEmpty()) {
|
||||
mAMapNavi.calculateDriveRoute(startNaviPoi, endNaviPoi, waysPoiIds, PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "配置导航参数出错: " + e.getMessage());
|
||||
}
|
||||
//车辆信息
|
||||
AMapCarInfo carInfo = new AMapCarInfo();
|
||||
carInfo.setCarNumber(plateNumber);
|
||||
carInfo.setCarType(String.valueOf(truckRouteData.truckDto.mcarType));
|
||||
carInfo.setVehicleAxis(String.valueOf(truckRouteData.truckDto.mvehicleAxis));
|
||||
carInfo.setVehicleHeight(truckRouteData.truckDto.mvehicleHeight);
|
||||
carInfo.setVehicleLength(truckRouteData.truckDto.mvehicleLength);
|
||||
carInfo.setVehicleWidth(truckRouteData.truckDto.mvehicleWidth);
|
||||
carInfo.setVehicleSize(String.valueOf(truckRouteData.truckDto.mvehicleSize));
|
||||
carInfo.setVehicleLoad(truckRouteData.truckDto.mvehicleLoad);
|
||||
carInfo.setVehicleWeight(truckRouteData.truckDto.mvehicleWeight);
|
||||
carInfo.setRestriction(truckRouteData.truckDto.isRestriction);
|
||||
carInfo.setVehicleLoadSwitch(truckRouteData.truckDto.mvehicleLoadSwitch);
|
||||
|
||||
//启动高德
|
||||
AmapNaviPage.getInstance().showRouteActivity(mActivity, params, null);
|
||||
// 检查途径点数量,决定使用哪种导航方式
|
||||
int wayPointsCount = waysPoiIds.size();
|
||||
Log.d(TAG, "途经点数量: " + wayPointsCount);
|
||||
if (wayPointsCount > 3) {
|
||||
// 途经点超过3个,跳转到 NavigationActivity
|
||||
Intent intent = new Intent(mContext, NavigationActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
// 设置起点和终点 POI
|
||||
NaviPoi startNaviPoi = new NaviPoi("", startPoint, "");
|
||||
NaviPoi endNaviPoi = new NaviPoi("", finalDestinationLatLng, "");
|
||||
intent.putExtra("startPoi", startNaviPoi);
|
||||
intent.putExtra("endPoi", endNaviPoi);
|
||||
|
||||
// 设置车辆信息
|
||||
if (truckRouteData != null && truckRouteData.truckDto != null) {
|
||||
intent.putExtra("carInfo", carInfo);
|
||||
}
|
||||
|
||||
// 设置途径点
|
||||
if (!waysPoiIds.isEmpty()) {// 必须转换为 ArrayList 才能调用 putParcelableArrayListExtra
|
||||
ArrayList<NaviPoi> wayPointsArrayList = new ArrayList<>(waysPoiIds);
|
||||
intent.putParcelableArrayListExtra("wayPoints", wayPointsArrayList);
|
||||
}
|
||||
|
||||
mContext.startActivity(intent);
|
||||
|
||||
} else {
|
||||
Poi start = new Poi(startName, startPoint, "");
|
||||
Poi end = new Poi(finalDestinationName, finalDestinationLatLng, "");
|
||||
AmapNaviParams params = new AmapNaviParams(start, null, end, AmapNaviType.DRIVER,
|
||||
AmapPageType.ROUTE);
|
||||
|
||||
try {
|
||||
AMapNavi mAMapNavi = AMapNavi.getInstance(mContext);
|
||||
// 设置车辆信息
|
||||
if (truckRouteData != null && truckRouteData.truckDto != null) {
|
||||
params.setCarInfo(carInfo);
|
||||
mAMapNavi.setCarInfo(carInfo);
|
||||
}
|
||||
params.setNeedDestroyDriveManagerInstanceWhenNaviExit(true);
|
||||
AmapNaviPage.getInstance().showRouteActivity(mActivity, params, null);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "配置导航参数出错: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initData(Context context) {
|
||||
@@ -721,6 +744,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
* 获取货车路线算法信息
|
||||
*/
|
||||
private void fetchTruckRouteAlgorithm(AMapLocation loc) {
|
||||
|
||||
showLoading();
|
||||
|
||||
if (plateNumber == null || plateNumber.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -742,6 +768,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
Log.e(TAG, "fetchTruckRouteAlgorithm failed", e);
|
||||
dismissLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -756,18 +783,78 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
JSONObject data = res.getJSONObject("data");
|
||||
truckRouteData = parseTruckRouteData(data);
|
||||
Log.d(TAG, "TruckRouteAlgorithm data loaded");
|
||||
|
||||
dismissLoading();
|
||||
|
||||
// 开始规划前隐藏输入框面板
|
||||
searchArea.setVisibility(View.GONE);
|
||||
|
||||
RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(startPoint.latitude, startPoint.longitude), new LatLonPoint(endPoint.latitude, endPoint.longitude));
|
||||
RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
|
||||
routeSearch.calculateDriveRouteAsyn(query);
|
||||
} else {
|
||||
dismissLoading();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "parseTruckRouteAlgorithm error", e);
|
||||
}
|
||||
} else {
|
||||
dismissLoading();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "fetchTruckRouteAlgorithm error", e);
|
||||
dismissLoading();
|
||||
}
|
||||
}
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private FrameLayout loadingOverlay;
|
||||
|
||||
private void initLoadingView(Context context) {
|
||||
// 创建遮罩层 (全屏透明,拦截点击)
|
||||
loadingOverlay = new FrameLayout(context);
|
||||
loadingOverlay.setLayoutParams(new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
loadingOverlay.setClickable(true); // 拦截点击
|
||||
loadingOverlay.setFocusable(true);
|
||||
loadingOverlay.setVisibility(View.GONE); // 默认隐藏
|
||||
|
||||
progressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
|
||||
FrameLayout.LayoutParams progressParams = new FrameLayout.LayoutParams(
|
||||
dp2px(45), dp2px(45));
|
||||
progressParams.gravity = Gravity.CENTER; // 居中显示
|
||||
|
||||
// 把进度条加到遮罩层
|
||||
loadingOverlay.addView(progressBar, progressParams);
|
||||
|
||||
// 最后把整个遮罩层添加到主容器的最顶层
|
||||
container.addView(loadingOverlay);
|
||||
}
|
||||
|
||||
private void showLoading() {
|
||||
if (mActivity == null)
|
||||
return;
|
||||
mActivity.runOnUiThread(() -> {
|
||||
if (loadingOverlay != null) {
|
||||
loadingOverlay.setVisibility(View.VISIBLE);
|
||||
}
|
||||
// 如果想在加载时给用户文字提示,可以动态加一个 TextView 在 ProgressBar 下方
|
||||
});
|
||||
}
|
||||
|
||||
private void dismissLoading() {
|
||||
if (mActivity == null)
|
||||
return;
|
||||
mActivity.runOnUiThread(() -> {
|
||||
if (loadingOverlay != null) {
|
||||
loadingOverlay.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupMapUi() {
|
||||
aMap.setLocationSource(this);
|
||||
aMap.setMyLocationEnabled(true);
|
||||
@@ -829,6 +916,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
mlocationClient = new AMapLocationClient(mContext);
|
||||
AMapLocationClientOption option = new AMapLocationClientOption();
|
||||
mlocationClient.setLocationListener(this);
|
||||
option.setNeedAddress(true);
|
||||
option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
mlocationClient.setLocationOption(option);
|
||||
mlocationClient.startLocation();
|
||||
@@ -840,19 +928,19 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(AMapLocation loc) {
|
||||
if (loc != null && loc.getErrorCode() == 0) {
|
||||
currentLatLng = new LatLng(loc.getLatitude(), loc.getLongitude());
|
||||
mLoc = loc;
|
||||
if (mLoc != null && mLoc.getErrorCode() == 0) {
|
||||
currentLatLng = new LatLng(mLoc.getLatitude(), mLoc.getLongitude());
|
||||
if (mListener != null)
|
||||
mListener.onLocationChanged(loc);
|
||||
mListener.onLocationChanged(mLoc);
|
||||
if (isFirstLocation) {
|
||||
isFirstLocation = false;
|
||||
startPoint = currentLatLng;
|
||||
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14f));
|
||||
getAddressByLatlng(currentLatLng);
|
||||
fetchRecommendStation(loc);
|
||||
fetchNearbyStations(loc);
|
||||
// 获取货车路线算法信息
|
||||
fetchTruckRouteAlgorithm(loc);
|
||||
fetchRecommendStation(mLoc);
|
||||
fetchNearbyStations(mLoc);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1322,6 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
|
||||
private void switchMode(String mode) {
|
||||
// 处理模式切换逻辑
|
||||
Toast.makeText(mContext, "切换到:" + mode, Toast.LENGTH_SHORT).show();
|
||||
modeMenu.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@@ -1252,7 +1339,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
GradientDrawable gd = new GradientDrawable();
|
||||
gd.setColor(color);
|
||||
// 顺序:左上x2, 右上x2, 右下x2, 左下x2
|
||||
gd.setCornerRadii(new float[]{r, r, r, r, 0, 0, 0, 0});
|
||||
gd.setCornerRadii(new float[]{r, r, r, r, r, r, r, r});
|
||||
return gd;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
package com.lnkj.ln_jq_app;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.amap.api.maps.AMapException;
|
||||
import com.amap.api.navi.AMapNavi;
|
||||
import com.amap.api.navi.AMapNaviListener;
|
||||
import com.amap.api.navi.AMapNaviView;
|
||||
import com.amap.api.navi.AMapNaviViewListener;
|
||||
import com.amap.api.navi.AMapNaviViewOptions;
|
||||
import com.amap.api.navi.enums.NaviType;
|
||||
import com.amap.api.navi.enums.PathPlanningStrategy;
|
||||
import com.amap.api.navi.model.AMapCalcRouteResult;
|
||||
import com.amap.api.navi.model.AMapCarInfo;
|
||||
import com.amap.api.navi.model.AMapLaneInfo;
|
||||
import com.amap.api.navi.model.AMapModelCross;
|
||||
import com.amap.api.navi.model.AMapNaviCameraInfo;
|
||||
import com.amap.api.navi.model.AMapNaviCross;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
|
||||
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
|
||||
import com.amap.api.navi.model.AMapServiceAreaInfo;
|
||||
import com.amap.api.navi.model.AimLessModeCongestionInfo;
|
||||
import com.amap.api.navi.model.AimLessModeStat;
|
||||
import com.amap.api.navi.model.NaviInfo;
|
||||
import com.amap.api.navi.model.NaviPoi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.activity.ComponentActivity;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* 导航
|
||||
*/
|
||||
public class NavigationActivity extends ComponentActivity implements AMapNaviListener {
|
||||
|
||||
private static final String TAG = "NavigationActivity";
|
||||
|
||||
private AMapNavi mAMapNavi;
|
||||
private AMapNaviView naviView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// 创建导航视图
|
||||
naviView = new AMapNaviView(this);
|
||||
naviView.onCreate(savedInstanceState);
|
||||
naviView.setAMapNaviViewListener(new AMapNaviViewListener() {
|
||||
@Override
|
||||
public void onNaviSetting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviCancel() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNaviBackClick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviMapMode(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviTurnClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextRoadClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanViewButtonClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockMap(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewLoaded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewShowMode(int i) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
AMapNaviViewOptions aMapNaviViewOptions = new AMapNaviViewOptions();
|
||||
Bitmap carBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.car);
|
||||
aMapNaviViewOptions.setCarBitmap(carBitmap);
|
||||
aMapNaviViewOptions.setSettingMenuEnabled(false);
|
||||
naviView.setViewOptions(aMapNaviViewOptions);
|
||||
|
||||
// 创建 AMapNavi 实例
|
||||
try {
|
||||
mAMapNavi = AMapNavi.getInstance(this);
|
||||
mAMapNavi.addAMapNaviListener(this);
|
||||
} catch (AMapException e) {
|
||||
Log.e(TAG, "初始化导航失败", e);
|
||||
Toast.makeText(this, "初始化导航失败", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加到容器
|
||||
FrameLayout container = new FrameLayout(this);
|
||||
container.addView(naviView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
setContentView(container);
|
||||
|
||||
// 获取 Intent 中的参数
|
||||
processIntent(getIntent());
|
||||
|
||||
// 处理返回键
|
||||
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Log.d(TAG, "NavigationActivity created");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
processIntent(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Intent 参数并启动导航
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void processIntent(Intent intent) {
|
||||
if (intent == null) {
|
||||
Log.w(TAG, "Intent is null");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取起点、终点和途经点
|
||||
NaviPoi startNaviPoi = (NaviPoi) intent.getParcelableExtra("startPoi");
|
||||
NaviPoi endNaviPoi = (NaviPoi) intent.getParcelableExtra("endPoi");
|
||||
List<NaviPoi> wayPoints = intent.getParcelableArrayListExtra("wayPoints");
|
||||
|
||||
if (wayPoints != null) {
|
||||
Log.d("Navi", "获取到途径点数量: " + wayPoints.size());
|
||||
}
|
||||
|
||||
|
||||
if (startNaviPoi == null || endNaviPoi == null) {
|
||||
Log.e(TAG, "Missing start or end point");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置车辆信息
|
||||
AMapCarInfo carInfo = (AMapCarInfo) intent.getParcelableExtra("carInfo");
|
||||
if (carInfo != null) {
|
||||
mAMapNavi.setCarInfo(carInfo);
|
||||
}
|
||||
|
||||
// 计算并启动导航
|
||||
mAMapNavi.calculateDriveRoute(startNaviPoi, endNaviPoi, wayPoints, PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT);
|
||||
|
||||
Log.d(TAG, "Navigation started from: " + startNaviPoi.getName() + " - " + endNaviPoi.getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Process intent error", e);
|
||||
Toast.makeText(this, "导航启动失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (naviView != null) {
|
||||
naviView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (naviView != null) {
|
||||
naviView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (naviView != null) {
|
||||
naviView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
// 停止导航
|
||||
if (mAMapNavi != null) {
|
||||
mAMapNavi.stopNavi();
|
||||
mAMapNavi.removeAMapNaviListener(this);
|
||||
}
|
||||
if (naviView != null) {
|
||||
naviView.onDestroy();
|
||||
}
|
||||
Log.d(TAG, "NavigationActivity destroyed");
|
||||
}
|
||||
|
||||
private int dp2px(float dp) {
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
return (int) (dp * density + 0.5f);
|
||||
}
|
||||
|
||||
// ============ AMapNaviListener 回调实现 ============
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitNaviFailure() {
|
||||
Log.e(TAG, "onInitNaviFailure");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitNaviSuccess() {
|
||||
Log.d(TAG, "onInitNaviSuccess");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartNavi(int i) {
|
||||
Log.d(TAG, "onStartNavi: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrafficStatusUpdate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(int i, String s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(String s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndEmulatorNavi() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveDestination() {
|
||||
Log.d(TAG, "onArriveDestination");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(int i) {
|
||||
Log.e(TAG, "onCalculateRouteFailure: " + i);
|
||||
Toast.makeText(this, "路径计算失败: " + i, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCross(AMapNaviCross aMapNaviCross) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCross() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showModeCross(AMapModelCross aMapModelCross) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideModeCross() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLaneInfo() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(int[] ints) {
|
||||
Log.d(TAG, "onCalculateRouteSuccess");
|
||||
if (mAMapNavi != null) {
|
||||
mAMapNavi.startNavi(NaviType.GPS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyParallelRoad(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayRing(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
Log.d(TAG, "onCalculateRouteSuccess (result)");
|
||||
if (mAMapNavi != null) {
|
||||
mAMapNavi.startNavi(NaviType.GPS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
Log.e(TAG, "onCalculateRouteFailure: " + aMapCalcRouteResult.getErrorCode());
|
||||
Toast.makeText(this, "路径计算失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsSignalWeak(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForYaw() {
|
||||
Log.d(TAG, "onReCalculateRouteForYaw");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForTrafficJam() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArrivedWayPoint(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsOpenStatus(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdate(NaviInfo naviInfo) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user