package com.dayu.pipirrapp.fragment; import android.content.Context; import android.content.Intent; import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.ValueCallback; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.dayu.pipirrapp.bean.db.CenterPointBean; import com.dayu.pipirrapp.bean.db.MarkerBean; import com.dayu.pipirrapp.bean.net.CenterPointResult; import com.dayu.pipirrapp.bean.net.MarkerResult; import com.dayu.pipirrapp.dao.DaoSingleton; import com.dayu.pipirrapp.databinding.FragmentMapBinding; import com.dayu.pipirrapp.js.MyWebViewInterface; import com.dayu.pipirrapp.net.ApiManager; import com.dayu.pipirrapp.net.BaseResponse; import com.dayu.pipirrapp.net.Constants; import com.dayu.pipirrapp.net.subscribers.SubscriberListener; import com.dayu.pipirrapp.observer.MapFragmenObserver; import com.dayu.pipirrapp.service.MyLocationService; import com.dayu.pipirrapp.utils.CommonData; import com.dayu.pipirrapp.utils.MapJpgUtils; import com.dayu.pipirrapp.utils.MyLog; import com.dayu.pipirrapp.utils.ToastUtil; import com.dayu.pipirrapp.utils.WebViewUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Random; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; /** * author: zuo * Date: 2023/12/20 * Time: 10:16 * 备注:地图页 */ public class MapFragment extends BaseFragment { static String TAG = "MapFragment"; FragmentMapBinding binding; //定位相关 LocationManager locationManager; WebView mWebView; CenterPointBean centerPointBean; String strMarkerJson; boolean isStartInspec = false; @Override public void onAttach(@NonNull Context context) { super.onAttach(context); requireActivity().getLifecycle().addObserver(new MapFragmenObserver()); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onStart() { super.onStart(); //显示巡检状态 if (isStartInspec) { binding.stateText.setVisibility(View.VISIBLE); } else { binding.stateText.setVisibility(View.GONE); } } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentMapBinding.inflate(inflater, container, false); Log.i("MapFragment", "onCreateView"); mWebView = binding.webView; mWebView = WebViewUtils.initWebView(mWebView); MyWebViewInterface myWebViewInterface = new MyWebViewInterface(MapFragment.this); mWebView.addJavascriptInterface(myWebViewInterface, "Android"); mWebView.loadUrl("file:///android_asset/index.html"); getCenterPoint(); initView(); initLocalData(); getMarkerData(); //开启定位 Intent location = new Intent(this.getActivity(), MyLocationService.class); location.putExtra("isSingle", false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { this.getActivity().startForegroundService(location); } else { this.getActivity().startService(location); } return binding.getRoot(); } /** * 初始化本地数据 */ public void initLocalData() { centerPointBean = DaoSingleton.getInstance(MapFragment.this.getContext()).centerPointDao().findFirst(); List markerBeans = DaoSingleton.getInstance(MapFragment.this.getContext()).markerDao().findAll(); strMarkerJson = beanToJson(markerBeans); jumpCenterPoint(); setMapMarker(); } /** * 跳转地图中心点 */ public void jumpCenterPoint() { if (centerPointBean != null) { Log.d(TAG, "jumpCenterPoint>>>>>>>>>>>>>>>>>>>" + centerPointBean.getLng() + "\",\"" + centerPointBean.getLat()); mWebView.evaluateJavascript("javascript:setCenterAndZoom(\"" + centerPointBean.getLng() + "\",\"" + centerPointBean.getLat() + "\")", value -> { }); } } /** * 添加标注点 */ public void setMapMarker() { Log.i("mWebView", "addMarker????????????" + strMarkerJson); mWebView.evaluateJavascript("javascript:addMarker(\"" + strMarkerJson + "\")", new ValueCallback() { @Override public void onReceiveValue(String value) { Log.i("mWebView", "addMarker!!!!!!!!!" + value); } }); } /** * 获取取水口列表 */ private void getMarkerData() { ApiManager.getInstance().requestGetHideLoading(this.getContext(), Constants.BASE_URL + ":8085/project/intake/all", MarkerResult.class, null, new SubscriberListener>() { @Override public void onNext(BaseResponse t) { if (t.isSuccess()) { if (t.isSuccess()) { if (t.getContent().getObj() != null && !t.getContent().getObj().isEmpty()) { List markerBeans = new ArrayList<>(); for (int i = 0; i < t.getContent().getObj().size(); i++) { MarkerResult.Obj result = t.getContent().getObj().get(i); //保存数据 MarkerBean markerBean = new MarkerBean(); markerBean.setLng(result.getLng()); markerBean.setLat(result.getLat()); markerBean.setBlockId(result.getBlockId()); markerBean.setName(result.getName()); markerBean.setRemarks(result.getRemarks()); markerBean.setTownId(result.getTownId()); markerBean.setVillageId(result.getVillageId()); markerBean.setCountyId(result.getCountyId()); markerBeans.add(markerBean); } strMarkerJson = beanToJson(markerBeans); setMapMarker(); DaoSingleton.getInstance(MapFragment.this.getContext()).markerDao().deleteAll(); // 使用 RxJava 异步插入数据 DaoSingleton.getAsynchInstance(MapFragment.this.getContext()).markerDao().insertAll(markerBeans) .subscribeOn(Schedulers.io()) // 在 IO 线程上执行 .observeOn(AndroidSchedulers.mainThread()) // 在主线程上观察 .subscribe(() -> { // 插入成功 Log.i("mWebView", "数据插入成功"); }, throwable -> { // 插入失败 Log.e("mWebView", "数据插入失败: " + throwable.getMessage()); }); } } } else { ToastUtil.showToast(MapFragment.this.getContext(), t.getMsg()); } } }); } /** * bean转json * * @param markerBeans */ private String beanToJson(List markerBeans) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("["); for (int i = 0; i < markerBeans.size(); i++) { MarkerBean markerBean = markerBeans.get(i); stringBuilder.append("["); stringBuilder.append(markerBean.getLng()); stringBuilder.append(","); stringBuilder.append(markerBean.getLat()); stringBuilder.append(",\"" + markerBean.getName() + "\"]"); if (i != markerBeans.size() - 1) { stringBuilder.append(","); } } stringBuilder.append("]"); return stringBuilder.toString().replace("\\", "\\\\").replace("\"", "\\\""); } /** * 添加标注点 */ public void addMarker() { Random random = new Random(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("["); // 中国经纬度范围 double minLongitude = 73.43; double maxLongitude = 135.05; double minLatitude = 3.52; double maxLatitude = 53.57; for (int i = 0; i < 1000; i++) { stringBuilder.append("["); // 生成随机经度 double longitude = minLongitude + (maxLongitude - minLongitude) * random.nextDouble(); stringBuilder.append(longitude); stringBuilder.append(","); // 生成随机纬度 double latitude = minLatitude + (maxLatitude - minLatitude) * random.nextDouble(); stringBuilder.append(latitude); stringBuilder.append(",\"237取水口\"],"); } stringBuilder.append("[116.417854,39.921988,\"235取水口\"]]"); String jsonData = stringBuilder.toString().replace("\\", "\\\\").replace("\"", "\\\""); Log.i("mWebView", "addMarker????????????" + jsonData); mWebView.evaluateJavascript("javascript:addMarker(\"" + jsonData + "\")", new ValueCallback() { @Override public void onReceiveValue(String value) { Log.i("mWebView", "addMarker!!!!!!!!!" + value); } }); } @Override public void onResume() { super.onResume(); mWebView.onResume(); // 恢复 WebView,能正常执行网页的响应 } @Override public void onPause() { super.onPause(); // mWebView.onPause(); // 通过 onPause 动作通知内核暂停所有的动作,如 DOM 的解析、plugin 的执行、JavaScript 执行等 } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy>>>>>>>>>>>>>>>>>>>>>>>>>>>"); ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.destroy(); // 当 Activity 要 destroy 时,应先将 WebView 移除,再 destroy 掉 } void initView() { //跳转到指定位置 binding.flyBtn.setOnClickListener(v -> { mWebView.evaluateJavascript("javascript:locationOverLay(116.399565,39.89432)", value -> { }); }); mWebView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { String url = request.getUrl().toString(); //判断当前是否为加载瓦片 if (MapJpgUtils.getInsatance().isTianDiTuTileRequest(url)) { String androidUrl = url.replace(CommonData.webKey, CommonData.androidKey); // 检查本地缓存 File cachedTile = MapJpgUtils.getInsatance().getCachedTile(androidUrl); if (cachedTile != null && cachedTile.exists()) { Log.i(TAG, "本地缓存>>>" + androidUrl); // if (MapJpgUtils.getInsatance().validateImageFile(androidUrl,request.)) // 判断缓存是否过期 // if (!MapJpgUtils.getInsatance(MapFragment.this.getContext()).isCacheExpired(cachedTile)) { try { // 从缓存加载瓦片 return new WebResourceResponse("image/jpg", "utf-8", new FileInputStream(cachedTile)); } catch (FileNotFoundException e) { e.printStackTrace(); } // } } else { //下载瓦片 ApiManager.getInstance().donwLoadTile(androidUrl); } Log.i(TAG, "在线加载>>>" + url); } return super.shouldInterceptRequest(view, request); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); // 捕获加载过程中发生的错误 int errorCode = error.getErrorCode(); String description = error.getDescription().toString(); String failingUrl = request.getUrl().toString(); Log.e("setWebViewClient", "errorCode:" + errorCode + ">>>>description:" + description + ">>>>failingUrl:" + failingUrl); // 处理错误,例如显示错误页面或提示用户 // view.loadUrl("file:///android_asset/error.html"); } @Override public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { super.onReceivedHttpError(view, request, errorResponse); // 捕获HTTP错误(如404, 500等) int statusCode = errorResponse.getStatusCode(); String description = errorResponse.getReasonPhrase(); Log.e("setWebViewClient", "statusCode:" + statusCode + ">>>>description:" + description); // 根据HTTP状态码处理错误 } }); binding.inspectButton.setOnClickListener(v -> { if (!isStartInspec) { isStartInspec = true; binding.inspectButton.setText("终"); } else { isStartInspec = false; } binding.stateText.setVisibility(View.VISIBLE); }); } public void showWaterIntakeDetail(String data) { MyLog.i(data); binding.bottomLL.setVisibility(View.VISIBLE); } /** * 获取地图中心点 */ private void getCenterPoint() { ApiManager.getInstance().requestGet(this.getContext(), Constants.BASE_URL + ":8080/base/dict_item/map_center", CenterPointResult.class, null, new SubscriberListener>() { @Override public void onNext(BaseResponse t) { if (t.isSuccess()) { if (centerPointBean == null) { centerPointBean = new CenterPointBean(); } centerPointBean.setLat(t.getContent().getLat()); centerPointBean.setLng(t.getContent().getLng()); DaoSingleton.getInstance(MapFragment.this.getContext()).centerPointDao().insert(centerPointBean); jumpCenterPoint(); } else { ToastUtil.showToast(MapFragment.this.getContext(), t.getMsg()); } } }); } public void closeWaterIntakeDetail() { binding.bottomLL.setVisibility(View.GONE); } }