调整定位
This commit is contained in:
@@ -14,7 +14,12 @@
|
||||
<!--定位权限-->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
|
||||
<!--用于申请调用A-GPS模块-->
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
|
||||
<!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<!--如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明-->
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
|
||||
@@ -30,6 +35,11 @@
|
||||
|
||||
<!-- 高德地图定位服务 -->
|
||||
<service android:name="com.amap.api.location.APSService" />
|
||||
<!--高德导航-->
|
||||
<activity
|
||||
android:name="com.amap.api.navi.AmapRouteActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|navigation" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -1,74 +1,277 @@
|
||||
package com.lnkj.ln_jq_app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationClientOption;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.AMapOptions;
|
||||
import com.amap.api.maps.CameraUpdateFactory;
|
||||
import com.amap.api.maps.LocationSource;
|
||||
import com.amap.api.maps.MapView;
|
||||
import com.amap.api.maps.MapsInitializer;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.Marker;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.api.maps.model.Poi;
|
||||
import com.amap.api.navi.AMapNavi;
|
||||
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.INaviInfoCallback;
|
||||
import com.amap.api.navi.enums.PathPlanningStrategy;
|
||||
import com.amap.api.navi.model.AMapCarInfo;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.services.core.AMapException;
|
||||
import com.amap.api.services.core.LatLonPoint;
|
||||
import com.amap.api.services.geocoder.GeocodeResult;
|
||||
import com.amap.api.services.geocoder.GeocodeSearch;
|
||||
import com.amap.api.services.geocoder.RegeocodeAddress;
|
||||
import com.amap.api.services.geocoder.RegeocodeQuery;
|
||||
import com.amap.api.services.geocoder.RegeocodeResult;
|
||||
import com.amap.api.services.route.BusRouteResult;
|
||||
import com.amap.api.services.route.DriveRouteResult;
|
||||
import com.amap.api.services.route.RideRouteResult;
|
||||
import com.amap.api.services.route.RouteSearch;
|
||||
import com.amap.api.services.route.WalkRouteResult;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import io.flutter.plugin.platform.PlatformView;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* 高德地图导航
|
||||
*/
|
||||
public class NativeMapView implements PlatformView, LocationSource, AMapLocationListener,
|
||||
GeocodeSearch.OnGeocodeSearchListener, RouteSearch.OnRouteSearchListener, AMap.OnMarkerClickListener {
|
||||
|
||||
public class NativeMapView implements PlatformView, LocationSource, AMapLocationListener {
|
||||
private static final String TAG = "NativeMapView";
|
||||
private final MapView mapView;
|
||||
private final AMap aMap;
|
||||
private final FrameLayout container;
|
||||
|
||||
// 地图相关
|
||||
private MapView mapView;
|
||||
private AMap aMap;
|
||||
private OnLocationChangedListener mListener;
|
||||
|
||||
// 定位相关
|
||||
private AMapLocationClient mlocationClient;
|
||||
private final Context mContext;
|
||||
private Activity mActivity; // 保存Activity引用用于导航
|
||||
private GeocodeSearch geocoderSearch;
|
||||
private RouteSearch routeSearch;
|
||||
private final OkHttpClient httpClient = new OkHttpClient();
|
||||
|
||||
// UI组件
|
||||
private EditText startInput;
|
||||
private EditText endInput;
|
||||
private LatLng currentLatLng;
|
||||
private String startName = "我的位置";
|
||||
private String endName = "目的地";
|
||||
private LatLng startPoint;
|
||||
private LatLng endPoint;
|
||||
private boolean isFirstLocation = true;
|
||||
private final List<Marker> stationMarkers = new ArrayList<>();
|
||||
|
||||
public NativeMapView(Context context, int id, Object args) {
|
||||
this.mContext = context;
|
||||
|
||||
// 隐私合规接口,必须在创建MapView之前设置
|
||||
// 尝试获取Activity引用
|
||||
mActivity = getActivityFromContext(context);
|
||||
|
||||
MapsInitializer.updatePrivacyShow(context, true, true);
|
||||
MapsInitializer.updatePrivacyAgree(context, true);
|
||||
|
||||
container = new FrameLayout(context);
|
||||
container.setClickable(true);
|
||||
container.setFocusable(true);
|
||||
|
||||
mapView = new MapView(context);
|
||||
// 在 Flutter PlatformView 中,savedInstanceState 通常为 null
|
||||
mapView.onCreate(null);
|
||||
mapView.onCreate(null);
|
||||
aMap = mapView.getMap();
|
||||
|
||||
// 设置地图的 UI 选项
|
||||
container.addView(mapView, new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
initServices(context);
|
||||
initOverlays(context);
|
||||
setupMapUi();
|
||||
|
||||
// 注册到 MainActivity 以便同步生命周期
|
||||
// 通知MainActivity
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).setMapView(this);
|
||||
}
|
||||
|
||||
Log.d(TAG, "NativeMapView初始化完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化服务
|
||||
*/
|
||||
private void initServices(Context context) {
|
||||
try {
|
||||
geocoderSearch = new GeocodeSearch(context);
|
||||
geocoderSearch.setOnGeocodeSearchListener(this);
|
||||
routeSearch = new RouteSearch(context);
|
||||
routeSearch.setRouteSearchListener(this);
|
||||
} catch (AMapException e) {
|
||||
Log.e(TAG, "服务初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化覆盖层UI
|
||||
*/
|
||||
private void initOverlays(Context context) {
|
||||
LinearLayout searchBox = new LinearLayout(context);
|
||||
searchBox.setOrientation(LinearLayout.VERTICAL);
|
||||
searchBox.setBackground(getRoundedDrawable(Color.WHITE, 12));
|
||||
searchBox.setElevation(dp2px(8));
|
||||
int p = dp2px(15);
|
||||
searchBox.setPadding(p, p, p, p);
|
||||
searchBox.setClickable(true);
|
||||
searchBox.setFocusable(true);
|
||||
|
||||
startInput = createInput(context, "起点: 正在定位...");
|
||||
searchBox.addView(startInput);
|
||||
|
||||
View vSpace = new View(context);
|
||||
searchBox.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(10)));
|
||||
|
||||
LinearLayout endRow = new LinearLayout(context);
|
||||
endRow.setOrientation(LinearLayout.HORIZONTAL);
|
||||
endRow.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
endInput = createInput(context, "终点: 请输入目的地");
|
||||
endRow.addView(endInput, new LinearLayout.LayoutParams(0, dp2px(42), 1f));
|
||||
|
||||
Button routeBtn = new Button(context);
|
||||
routeBtn.setText("路径规划");
|
||||
routeBtn.setTextColor(Color.WHITE);
|
||||
routeBtn.setAllCaps(false);
|
||||
routeBtn.setTextSize(14);
|
||||
routeBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 6));
|
||||
routeBtn.setOnClickListener(v -> startRouteSearch());
|
||||
endRow.addView(routeBtn, new LinearLayout.LayoutParams(dp2px(90), dp2px(42)));
|
||||
|
||||
searchBox.addView(endRow);
|
||||
|
||||
FrameLayout.LayoutParams searchParams = new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
searchParams.setMargins(dp2px(15), dp2px(50), dp2px(15), 0);
|
||||
container.addView(searchBox, searchParams);
|
||||
|
||||
ImageButton locBtn = new ImageButton(context);
|
||||
locBtn.setImageResource(android.R.drawable.ic_menu_mylocation);
|
||||
locBtn.setBackground(getRoundedDrawable(Color.WHITE, 30));
|
||||
locBtn.setElevation(dp2px(4));
|
||||
locBtn.setOnClickListener(v -> {
|
||||
if (currentLatLng != null) {
|
||||
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f));
|
||||
}
|
||||
});
|
||||
FrameLayout.LayoutParams locParams = new FrameLayout.LayoutParams(dp2px(50), dp2px(50));
|
||||
locParams.setMargins(0, 0, dp2px(20), dp2px(120));
|
||||
locParams.gravity = Gravity.BOTTOM | Gravity.END;
|
||||
container.addView(locBtn, locParams);
|
||||
}
|
||||
|
||||
private EditText createInput(Context context, String hint) {
|
||||
EditText et = new EditText(context);
|
||||
et.setHint(hint);
|
||||
et.setTextSize(14f);
|
||||
et.setTextColor(Color.BLACK);
|
||||
et.setPadding(dp2px(12), dp2px(10), dp2px(12), dp2px(10));
|
||||
et.setBackground(getRoundedDrawable(Color.parseColor("#F5F5F5"), 6));
|
||||
et.setSingleLine(true);
|
||||
et.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
et.setFocusable(true);
|
||||
et.setFocusableInTouchMode(true);
|
||||
return et;
|
||||
}
|
||||
|
||||
private GradientDrawable getRoundedDrawable(int color, int radiusDp) {
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setShape(GradientDrawable.RECTANGLE);
|
||||
shape.setCornerRadius(dp2px(radiusDp));
|
||||
shape.setColor(color);
|
||||
return shape;
|
||||
}
|
||||
|
||||
private int dp2px(float dp) {
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
private void setupMapUi() {
|
||||
aMap.setLocationSource(this);
|
||||
aMap.setMyLocationEnabled(true);
|
||||
aMap.setOnMarkerClickListener(this);
|
||||
|
||||
MyLocationStyle myLocationStyle = new MyLocationStyle();
|
||||
myLocationStyle.interval(2000);
|
||||
// 连续定位并将视角移动到地图中心点,定位蓝点跟随设备移动
|
||||
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
|
||||
|
||||
// --- 放大定位图标 ---
|
||||
try {
|
||||
Bitmap carBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.car);
|
||||
if (carBitmap != null) {
|
||||
// 放大到 80dp
|
||||
int iconSize = dp2px(25);
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(carBitmap, iconSize, iconSize, true);
|
||||
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromBitmap(scaledBitmap));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "设置大图标失败", e);
|
||||
}
|
||||
|
||||
myLocationStyle.anchor(0.5f, 0.5f);
|
||||
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
|
||||
myLocationStyle.showMyLocation(true);
|
||||
myLocationStyle.strokeColor(Color.TRANSPARENT);
|
||||
myLocationStyle.radiusFillColor(Color.TRANSPARENT);
|
||||
aMap.setMyLocationStyle(myLocationStyle);
|
||||
|
||||
// 显示缩放按钮
|
||||
|
||||
aMap.getUiSettings().setZoomControlsEnabled(true);
|
||||
aMap.getUiSettings().setScaleControlsEnabled(true);
|
||||
aMap.getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
// ==================== LocationSource 接口实现 ====================
|
||||
@Override
|
||||
public void activate(OnLocationChangedListener listener) {
|
||||
mListener = listener;
|
||||
@@ -88,56 +291,405 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
||||
public void startLocation() {
|
||||
if (mlocationClient == null) {
|
||||
try {
|
||||
AMapLocationClient.updatePrivacyShow(mContext, true, true);
|
||||
AMapLocationClient.updatePrivacyAgree(mContext, true);
|
||||
mlocationClient = new AMapLocationClient(mContext);
|
||||
AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
|
||||
AMapLocationClientOption option = new AMapLocationClientOption();
|
||||
mlocationClient.setLocationListener(this);
|
||||
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
mlocationClient.setLocationOption(mLocationOption);
|
||||
option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
mlocationClient.setLocationOption(option);
|
||||
mlocationClient.startLocation();
|
||||
Log.d(TAG, "定位启动成功");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "startLocation error", e);
|
||||
Log.e(TAG, "定位启动失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(AMapLocation amapLocation) {
|
||||
if (mListener != null && amapLocation != null) {
|
||||
if (amapLocation.getErrorCode() == 0) {
|
||||
mListener.onLocationChanged(amapLocation);
|
||||
// 首次定位成功后缩放地图
|
||||
// aMap.moveCamera(CameraUpdateFactory.zoomTo(15));
|
||||
} else {
|
||||
Log.e(TAG, "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo());
|
||||
public void onLocationChanged(AMapLocation loc) {
|
||||
if (loc != null) {
|
||||
if (mListener != null) {
|
||||
mListener.onLocationChanged(loc);
|
||||
}
|
||||
currentLatLng = new LatLng(loc.getLatitude(), loc.getLongitude());
|
||||
|
||||
if (loc.getErrorCode() == 0) {
|
||||
if (isFirstLocation) {
|
||||
isFirstLocation = false;
|
||||
startPoint = currentLatLng;
|
||||
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14f));
|
||||
getAddressByLatlng(currentLatLng);
|
||||
fetchRecommendStation(loc);
|
||||
fetchNearbyStations(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
if (mapView != null) {
|
||||
mapView.onResume();
|
||||
// ==================== 逆地理编码 ====================
|
||||
private void getAddressByLatlng(LatLng latLng) {
|
||||
LatLonPoint point = new LatLonPoint(latLng.latitude, latLng.longitude);
|
||||
RegeocodeQuery query = new RegeocodeQuery(point, 200, GeocodeSearch.AMAP);
|
||||
geocoderSearch.getFromLocationAsyn(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
|
||||
if (rCode == AMapException.CODE_AMAP_SUCCESS && result != null && result.getRegeocodeAddress() != null) {
|
||||
RegeocodeAddress addr = result.getRegeocodeAddress();
|
||||
String fullAddr = addr.getFormatAddress();
|
||||
|
||||
// 优化地址显示逻辑
|
||||
startName = formatAddress(fullAddr,result);
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
startInput.setText(startName);
|
||||
startInput.setSelection(startName.length()); // 光标移到末尾
|
||||
});
|
||||
|
||||
Log.d(TAG, "逆地理编码成功: " + startName);
|
||||
} else {
|
||||
Log.e(TAG, "逆地理编码失败: code=" + rCode + ", result=" + (result != null ? "null" : "has data"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化地址显示,移除重复的前缀并限制长度
|
||||
*/
|
||||
private String formatAddress(String fullAddress,RegeocodeResult result) {
|
||||
if (fullAddress == null || fullAddress.isEmpty()) {
|
||||
return "未知地点";
|
||||
}
|
||||
|
||||
// 获取各级地址信息
|
||||
String province = null;
|
||||
String city = null;
|
||||
String district = null;
|
||||
String township = null;
|
||||
|
||||
try {
|
||||
if (result.getRegeocodeAddress() != null) {
|
||||
RegeocodeAddress addr = result.getRegeocodeAddress();
|
||||
province = addr.getProvince();
|
||||
city = addr.getCity();
|
||||
district = addr.getDistrict();
|
||||
township = addr.getTownship();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "获取地址信息失败", e);
|
||||
}
|
||||
|
||||
String formattedAddr = fullAddress;
|
||||
|
||||
// 按优先级移除重复前缀(省、市、区、乡)
|
||||
String[] prefixes = {province, city, district, township};
|
||||
for (String prefix : prefixes) {
|
||||
if (prefix != null && !prefix.isEmpty() && formattedAddr.startsWith(prefix)) {
|
||||
formattedAddr = formattedAddr.substring(prefix.length());
|
||||
Log.d(TAG, "移除前缀: " + prefix + " -> " + formattedAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// 限制地址长度并添加省略号
|
||||
if (formattedAddr.length() > 25) {
|
||||
formattedAddr = formattedAddr.substring(0, 25) + "...";
|
||||
Log.d(TAG, "地址长度截断: " + formattedAddr);
|
||||
}
|
||||
|
||||
return formattedAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGeocodeSearched(GeocodeResult result, int rCode) {
|
||||
}
|
||||
|
||||
// ==================== API请求 ====================
|
||||
|
||||
private void fetchRecommendStation(AMapLocation loc) {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("province", loc.getProvince() != null ? loc.getProvince() : "");
|
||||
json.put("city", loc.getCity() != null && !loc.getCity().isEmpty() ? loc.getCity() : "");
|
||||
json.put("district", loc.getDistrict() != null ? loc.getDistrict() : "");
|
||||
json.put("longitude", String.valueOf(loc.getLongitude()));
|
||||
json.put("latitude", String.valueOf(loc.getLatitude()));
|
||||
|
||||
RequestBody body = RequestBody.create(json.toString(), MediaType.parse("application/json; charset=utf-8"));
|
||||
Request request = new Request.Builder()
|
||||
.url("https://beta-esg.api.lnh2e.com/appointment/station/getStationInfoByArea")
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
httpClient.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
try {
|
||||
JSONObject res = new JSONObject(response.body().string());
|
||||
if (res.getInt("code") == 0 && !res.isNull("data")) {
|
||||
JSONObject data = res.getJSONObject("data");
|
||||
endPoint = new LatLng(data.getDouble("latitude"), data.getDouble("longitude"));
|
||||
endName = data.getString("name");
|
||||
String addr = data.optString("address", "");
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
endInput.setText(addr);
|
||||
markStation(endPoint, endName, true);
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchNearbyStations(AMapLocation loc) {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("longitude", String.valueOf(loc.getLongitude()));
|
||||
json.put("latitude", String.valueOf(loc.getLatitude()));
|
||||
|
||||
RequestBody body = RequestBody.create(json.toString(), MediaType.parse("application/json; charset=utf-8"));
|
||||
Request request = new Request.Builder()
|
||||
.url("https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation")
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
httpClient.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
try {
|
||||
JSONObject res = new JSONObject(response.body().string());
|
||||
if (res.getInt("code") == 0 && !res.isNull("data")) {
|
||||
JSONArray array = res.getJSONArray("data");
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
try {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
markStation(new LatLng(item.getDouble("latitude"), item.getDouble("longitude")),
|
||||
item.getString("name"), false);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void markStation(LatLng latLng, String name, boolean isRecommend) {
|
||||
MarkerOptions opt = new MarkerOptions()
|
||||
.position(latLng).title(name)
|
||||
.icon(BitmapDescriptorFactory.defaultMarker(isRecommend ? BitmapDescriptorFactory.HUE_RED : BitmapDescriptorFactory.HUE_GREEN));
|
||||
Marker m = aMap.addMarker(opt);
|
||||
m.setObject(latLng);
|
||||
stationMarkers.add(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMarkerClick(Marker marker) {
|
||||
if (marker.getObject() instanceof LatLng) {
|
||||
endPoint = (LatLng) marker.getObject();
|
||||
endName = marker.getTitle();
|
||||
endInput.setText(endName);
|
||||
startRouteSearch();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== 路径规划 ====================
|
||||
|
||||
private void startRouteSearch() {
|
||||
if (startPoint == null || endPoint == null) {
|
||||
Toast.makeText(mContext, "正在定位中,请稍后...", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Poi start = new Poi(startName, startPoint, "");
|
||||
Poi end = new Poi(endName, endPoint, "");
|
||||
|
||||
AmapNaviParams params = new AmapNaviParams(start, null, end, AmapNaviType.DRIVER, AmapPageType.ROUTE);
|
||||
|
||||
try {
|
||||
AMapNavi mAMapNavi = AMapNavi.getInstance(mContext);
|
||||
AMapCarInfo carInfo = new AMapCarInfo();
|
||||
carInfo.setCarNumber("沪AGK2267");
|
||||
carInfo.setCarType("1");
|
||||
carInfo.setVehicleAxis("6");
|
||||
carInfo.setVehicleHeight("3.32");
|
||||
carInfo.setVehicleLength("6.9");
|
||||
carInfo.setVehicleWidth("2.26");
|
||||
carInfo.setVehicleSize("2");
|
||||
carInfo.setVehicleLoad("4.5");
|
||||
carInfo.setVehicleWeight("4.5");
|
||||
carInfo.setRestriction(true);
|
||||
carInfo.setVehicleLoadSwitch(true);
|
||||
mAMapNavi.setCarInfo(carInfo);
|
||||
} catch (com.amap.api.maps.AMapException e) {
|
||||
Log.e(TAG, "设置车辆信息失败", e);
|
||||
}
|
||||
|
||||
params.setRouteStrategy(PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT);
|
||||
|
||||
if (mActivity != null) {
|
||||
AmapNaviPage.getInstance().showRouteActivity(mActivity, params, new INaviInfoCallback() {
|
||||
@Override
|
||||
public void onInitNaviFailure() {
|
||||
Log.e(TAG, "导航初始化失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(String s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChange(AMapNaviLocation location) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveDestination(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartNavi(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(int[] ints) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopSpeaking() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRoute(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArrivedWayPoint(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExitPage(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStrategyChanged(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviDirectionChanged(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDayAndNightModeChanged(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastModeChanged(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleAutoChanged(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getCustomNaviBottomView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getCustomNaviView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getCustomMiddleView() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDriveRouteSearched(DriveRouteResult result, int rCode) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBusRouteSearched(BusRouteResult r, int c) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalkRouteSearched(WalkRouteResult r, int c) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRideRouteSearched(RideRouteResult r, int c) {
|
||||
}
|
||||
|
||||
private Activity getActivityFromContext(Context context) {
|
||||
if (context instanceof Activity)
|
||||
return (Activity) context;
|
||||
if (context instanceof android.content.ContextWrapper) {
|
||||
Context base = ((android.content.ContextWrapper) context).getBaseContext();
|
||||
if (base instanceof Activity)
|
||||
return (Activity) base;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
if (mapView != null) {
|
||||
mapView.onPause();
|
||||
}
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (mapView != null) {
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
public void onSaveInstanceState(Bundle out) {
|
||||
mapView.onSaveInstanceState(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (mapView != null) {
|
||||
mapView.onDestroy();
|
||||
if (mlocationClient != null) {
|
||||
mlocationClient.stopLocation();
|
||||
mlocationClient.onDestroy();
|
||||
}
|
||||
deactivate();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#2196F3"
|
||||
android:pathData="M24,4C13.4,4 4,13.4 4,24s9.4,20 20,20 20,-9.4 20,-20S34.6,4 24,4zM24,40c-8.8,0 -16,-7.2 -16,-16s7.2,-16 16,-16 16,7.2 16,16 -7.2,16 -16,16zM24,36c-6.6,0 -12,-5.4 -12,-12s5.4,-12 12,-12 12,5.4 12,12 -5.4,12 -12,12zM24,32c-4.4,0 -8,-3.6 -8,-8s3.6,-8 8,-8 8,3.6 8,8 -3.6,8 -8,8zM24,30c-3.3,0 -6,-2.7 -6,-6s2.7,-6 6,-6 6,2.7 6,6 -2.7,6 -6,6zM24,24c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
|
||||
</vector>
|
||||
BIN
ln_jq_app/android/app/src/main/res/drawable/car.png
Normal file
BIN
ln_jq_app/android/app/src/main/res/drawable/car.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:fillColor="#F44336"
|
||||
android:pathData="M16,4C10.48,4 6,8.48 6,14c0,4.84 9.2,13.76 9.2,13.76C15.49,28.05 15.74,28.14 16,28.14s0.51,-0.09 0.8,-0.38C16.8,27.76 26,18.84 26,14C26,8.48 21.52,4 16,4zM16,17c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#666666"
|
||||
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
|
||||
</vector>
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,16l-4,4h8z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:fillColor="#4CAF50"
|
||||
android:pathData="M16,4C10.48,4 6,8.48 6,14c0,4.84 9.2,13.76 9.2,13.76C15.49,28.05 15.74,28.14 16,28.14s0.51,-0.09 0.8,-0.38C16.8,27.76 26,18.84 26,14C26,8.48 21.52,4 16,4zM16,17c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:fillColor="#2196F3"
|
||||
android:pathData="M16,2C9.38,2 4,7.38 4,14c0,5.28 10,14 10,14s10,-8.72 10,-14C24,7.38 18.62,2 16,2zM16,17c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM16,12c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1z"/>
|
||||
</vector>
|
||||
BIN
ln_jq_app/android/app/src/main/res/drawable/ic_tag.png
Normal file
BIN
ln_jq_app/android/app/src/main/res/drawable/ic_tag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
Reference in New Issue
Block a user