管灌系统巡查员智能手机App
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
@@ -5,6 +5,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -35,11 +36,14 @@
import com.dayu.pipirrapp.bean.db.PipeNetWorkDataBean;
import com.dayu.pipirrapp.bean.db.PipeNetworkBean;
import com.dayu.pipirrapp.bean.db.PipeNetworkDataCoordinateBean;
import com.dayu.pipirrapp.bean.net.BaseListResult;
import com.dayu.pipirrapp.bean.net.CenterPointResult;
import com.dayu.pipirrapp.bean.net.DivideListResult;
import com.dayu.pipirrapp.bean.net.DivideResult;
import com.dayu.pipirrapp.bean.net.InsectionResult;
import com.dayu.pipirrapp.bean.net.InspectionRequest;
import com.dayu.pipirrapp.bean.net.IntakeListResult;
import com.dayu.pipirrapp.bean.net.IntakeResult;
import com.dayu.pipirrapp.bean.net.MarkerListResult;
import com.dayu.pipirrapp.bean.net.MarkerResult;
import com.dayu.pipirrapp.bean.net.PipeNetworkResult;
@@ -72,6 +76,7 @@
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.tencent.bugly.crashreport.CrashReport;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -84,6 +89,7 @@
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.reactivex.rxjava3.core.Single;
/**
 * author: zuo
@@ -145,10 +151,55 @@
        // 添加刷新数据的监听
        LiveEventBus.get(CommonKeyName.refreshData).observe(this, o -> {
            getCenterPoint();
            getMarkerData();
            getDivideList();
            getPipeNetworkList();
            // 显示加载动画
            TipUtil.showLoading(MapFragment.this.getActivity(), "正在更新数据...");
            // 创建多个Single对象来表示每个网络请求
            Single<Boolean> centerPointSingle = Single.create(emitter -> {
                getCenterPoint();
                emitter.onSuccess(true);
            });
            Single<Boolean> markerDataSingle = Single.create(emitter -> {
                getMarkerData();
                emitter.onSuccess(true);
            });
            Single<Boolean> divideListSingle = Single.create(emitter -> {
                getDivideList();
                emitter.onSuccess(true);
            });
            Single<Boolean> pipeNetworkListSingle = Single.create(emitter -> {
                getPipeNetworkList();
                emitter.onSuccess(true);
            });
            // 组合所有Single
            compositeDisposable.add(
                    Single.zip(
                                    centerPointSingle,
                                    markerDataSingle,
                                    divideListSingle,
                                    pipeNetworkListSingle,
                                    (centerPoint, marker, divide, pipe) -> true
                            )
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .doFinally(() -> {
                                // 无论成功还是失败,都需要隐藏加载动画
                                TipUtil.dismissLoading();
                            })
                            .subscribe(
                                    result -> {
                                        ToastUtil.showToast(MapFragment.this.getContext(), "数据更新完成");
                                    },
                                    throwable -> {
                                        Log.e(TAG, "数据更新失败: " + throwable.getMessage());
                                        ToastUtil.showToast(MapFragment.this.getContext(), "数据更新失败");
                                    }
                            )
            );
        });
    }
@@ -289,24 +340,31 @@
                    // 检查本地缓存
                    File cachedTile = MapJpgUtils.getInsatance().getCachedTile(androidUrl);
                    if (cachedTile != null && cachedTile.exists()) {
//                        Log.d(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();
                        // 检查文件是否超过6个月
                        long sixMonthsInMillis = 6L * 30 * 24 * 60 * 60 * 1000; // 6个月的毫秒数
                        long fileAge = System.currentTimeMillis() - cachedTile.lastModified();
                        if (fileAge > sixMonthsInMillis) {
                            // 如果文件超过6个月,删除旧文件并重新下载
                            if (cachedTile.delete()) {
                                Log.d(TAG, "已删除过期瓦片: " + androidUrl);
                            } else {
                                Log.e(TAG, "删除过期瓦片失败: " + androidUrl);
                            }
                            ApiManager.getInstance().donwLoadTile(MapFragment.this.getContext(), androidUrl);
                        } else {
                            try {
                                // 从缓存加载瓦片
                                return new WebResourceResponse("image/jpg", "utf-8", new FileInputStream(cachedTile));
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
//                    }
                    } else {
                        //下载瓦片
                        ApiManager.getInstance().donwLoadTile(MapFragment.this.getContext(), androidUrl);
                    }
                }
                return super.shouldInterceptRequest(view, request);
            }
@@ -440,7 +498,7 @@
        //巡检按钮
        binding.inspectButton.setOnClickListener(v -> {
            if (XXPermissions.isGranted(MapFragment.this.getContext(), Permission.ACCESS_BACKGROUND_LOCATION)) {
                new ConfirmDialog(MapFragment.this.getActivity(), "确认开始巡检吗?",(confirmDialog, v1) -> {
                new ConfirmDialog(MapFragment.this.getActivity(), "确认开始巡检吗?", (confirmDialog, v1) -> {
                    chageInspecState(InspectionUtils.STAT_INSPECTION_ONCLICK);
                    confirmDialog.dismiss();
                }).show();
@@ -469,8 +527,13 @@
        });
        //上报问题
        binding.putButton.setOnClickListener(v -> {
            Intent issue = new Intent(MapFragment.this.getActivity(), AddIssueActivity.class);
            MapFragment.this.getActivity().startActivity(issue);
            new ConfirmDialog(MapFragment.this.getActivity(), "确认上报问题吗?", (confirmDialog, v1) -> {
                Intent issue = new Intent(MapFragment.this.getActivity(), AddIssueActivity.class);
                MapFragment.this.getActivity().startActivity(issue);
                confirmDialog.dismiss();
            }).show();
        });
        binding.expandButton.setLegendsArray(new ExpandButton.Quadruple(
                        ContextCompat.getDrawable(requireContext(), R.drawable.marker_blue),
@@ -521,33 +584,33 @@
//                    }
                    // 跳转到选择的位置
                    mWebView.evaluateJavascript(
                        String.format("javascript:setCenterAndZoom(\"%s\",\"%s\",\"17\")",
                        item.getLng(),
                        item.getLat()),
                        null
                            String.format("javascript:setCenterAndZoom(\"%s\",\"%s\",\"17\")",
                                    item.getLng(),
                                    item.getLat()),
                            null
                    );
                });
                // 执行搜索
                compositeDisposable.add(
                    DaoSingleton.getAsynchInstance(requireContext())
                        .divideDao()
                        .searchAllByKeyword(s)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(
                            results -> {
                                if (results != null && !results.isEmpty()) {
                                    searchDialog.setData(results);
                                    searchDialog.show();
                                } else {
                                    ToastUtil.showToast(requireContext(), "未找到相关结果");
                                }
                            },
                            throwable -> {
                                ToastUtil.showToast(requireContext(), "搜索失败:" + throwable.getMessage());
                            }
                        )
                        DaoSingleton.getAsynchInstance(requireContext())
                                .divideDao()
                                .searchAllByKeyword(s)
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(
                                        results -> {
                                            if (results != null && !results.isEmpty()) {
                                                searchDialog.setData(results);
                                                searchDialog.show();
                                            } else {
                                                ToastUtil.showToast(requireContext(), "未找到相关结果");
                                            }
                                        },
                                        throwable -> {
                                            ToastUtil.showToast(requireContext(), "搜索失败:" + throwable.getMessage());
                                        }
                                )
                );
            }
            return null;
@@ -609,8 +672,23 @@
        });
    }
    /**
     * 隐藏底部布局的动画效果
     */
    private void hideBottomLayoutWithAnimation() {
        binding.bottomLL.animate()
                .translationY(binding.bottomLL.getHeight())
                .setDuration(300)
                .setInterpolator(new android.view.animation.AccelerateInterpolator())
                .withEndAction(() -> {
                    binding.bottomLL.setVisibility(View.GONE);
                    binding.bottomLL.setTranslationY(0);
                })
                .start();
    }
    public void closeWaterIntakeDetail() {
        binding.bottomLL.setVisibility(View.GONE);
        hideBottomLayoutWithAnimation();
    }
    /**
@@ -844,7 +922,7 @@
                boolean isfrist = true;
                for (PipeNetworkDataCoordinateBean data : pipeNetworkBean.getData().getCoordinates()) {
                    if (!TextUtils.isEmpty(data.getLat()) && !TextUtils.isEmpty(data.getLng())) {
                        mWebView.evaluateJavascript("javascript:addPipeNetwork(\"" + data.getLng() + "\",\"" + data.getLat() + "\",\"" + isfrist +  "\",\"" + isShowPipeNetwork +"\")", new ValueCallback<String>() {
                        mWebView.evaluateJavascript("javascript:addPipeNetwork(\"" + data.getLng() + "\",\"" + data.getLat() + "\",\"" + isfrist + "\",\"" + isShowPipeNetwork + "\")", new ValueCallback<String>() {
                            @Override
                            public void onReceiveValue(String value) {
                            }
@@ -958,7 +1036,30 @@
                        binding.lat.setText(lat);
                        mWebView.evaluateJavascript("javascript:cancelPin()", value -> {
                        });
                        ToastUtil.showToastLong(MapFragment.this.getContext(), "修改成功!");
                        // 更新本地数据库
                        compositeDisposable.add(
                                DaoSingleton.getAsynchInstance(MapFragment.this.getContext())
                                        .markerDao()
                                        .updateMarkerLocation(markerBean.getId(), lng, lat)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(
                                                () -> {
                                                    // 更新本地缓存Map中的数据
                                                    MarkerBean cachedMarker = markerBeanSet.get(markerBean.getId());
                                                    if (cachedMarker != null) {
                                                        cachedMarker.setLng(lng);
                                                        cachedMarker.setLat(lat);
                                                    }
                                                    ToastUtil.showToastLong(MapFragment.this.getContext(), "修改成功!");
                                                },
                                                throwable -> {
                                                    Log.e(TAG, "更新本地数据库失败: ");
                                                    ToastUtil.showToastLong(MapFragment.this.getContext(), "修改成功,但本地数据库更新失败");
                                                }
                                        )
                        );
                    } else {
                        ToastUtil.showToastLong(MapFragment.this.getContext(), t.getMsg());
@@ -998,6 +1099,7 @@
                    mMarkerBean.setAddress(result.getAddress());
                    mMarkerBean.setBlockName(result.getBlockName());
                    mMarkerBean.setDivideId(result.getDivideId());
                    getDeviceData(result.getName());
                    showMarker(mMarkerBean);
                } else {
                    ToastUtil.showToast(MapFragment.this.getContext(), t.getMsg());
@@ -1008,7 +1110,7 @@
    }
    /**
     * 显示取水口详情
     * 显示分水房详情
     */
    private void getDivideDetail(DivideBean divideBean) {
        ApiManager.getInstance().requestGet(this.getContext(), Constants.BASE_URL + "/project/divide/getone/" + divideBean.getDivideId(), DivideResult.class, null, new SubscriberListener<BaseResponse<DivideResult>>() {
@@ -1016,6 +1118,7 @@
            public void onNext(BaseResponse<DivideResult> t) {
                if (t.isSuccess()) {
                    DivideBean divideBean = getDivideBean(t.getContent());
                    getDeviceData(divideBean.getDivideName());
                    showDivideMarker(divideBean);
                } else {
                    ToastUtil.showToast(MapFragment.this.getContext(), t.getMsg());
@@ -1026,10 +1129,23 @@
    }
    /**
     * 显示底部布局的动画效果
     */
    private void showBottomLayoutWithAnimation() {
        binding.bottomLL.setVisibility(View.VISIBLE);
        binding.bottomLL.setTranslationY(binding.bottomLL.getHeight());
        binding.bottomLL.animate()
                .translationY(0)
                .setDuration(300)
                .setInterpolator(new android.view.animation.DecelerateInterpolator())
                .start();
    }
    /**
     * 显示取水口详情
     */
    private void showMarker(MarkerBean markerBean) {
        binding.bottomLL.setVisibility(View.VISIBLE);
        showBottomLayoutWithAnimation();
        binding.phoneLL.setVisibility(View.GONE);
        binding.headerLL.setVisibility(View.GONE);
        binding.editePoint.setVisibility(View.VISIBLE);
@@ -1073,7 +1189,7 @@
     * @param divideBean
     */
    private void showDivideMarker(DivideBean divideBean) {
        binding.bottomLL.setVisibility(View.VISIBLE);
        showBottomLayoutWithAnimation();
        binding.phoneLL.setVisibility(View.VISIBLE);
        binding.headerLL.setVisibility(View.VISIBLE);
        binding.editePoint.setVisibility(View.GONE);
@@ -1081,6 +1197,11 @@
        binding.markerName.setText(divideBean.getDivideName());
        binding.markerBlockName.setText(divideBean.getBlockName());
        binding.phone.setText(divideBean.getPhone());
        binding.phone.setOnClickListener(v -> {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            intent.setData(Uri.parse("tel:" + divideBean.getPhone()));
            startActivity(intent);
        });
        binding.header.setText(divideBean.getHeader());
        binding.lat.setText(divideBean.getLat());
        binding.lng.setText(divideBean.getLng());
@@ -1337,4 +1458,45 @@
        }
    }
    /**
     * 获取设备相关状态信息
     *
     * @param intakeNum
     */
    private void getDeviceData(String intakeNum) {
        Map<String, Object> params = new HashMap<>();
        params.put("intakeNum", intakeNum);
        ApiManager.getInstance().requestGetHideLoading(MapFragment.this.getContext(), BASE_URL + "/remote/monitor/all_intakes", IntakeListResult.class, params, new SubscriberListener<BaseResponse<IntakeListResult>>() {
            @Override
            public void onNext(BaseResponse<IntakeListResult> t) {
                try {
                    if (t.isSuccess()) {
                        if (t.getContent() != null && t.getContent().getObj().size() > 0) {
                            binding.deviceStateLL.setVisibility(View.VISIBLE);
                            binding.rtuAddressLL.setVisibility(View.VISIBLE);
                            IntakeResult intakeResult = t.getContent().getObj().get(0);
                            if (intakeResult.isOnLine()) {
                                binding.deviceState.setText("在线");
                                binding.deviceState.setTextColor(getResources().getColor(R.color.down_green_up, null));
                            } else {
                                binding.deviceState.setText("离线");
                                binding.deviceState.setTextColor(getResources().getColor(R.color.delete_color, null));
                            }
                            binding.rtuAddress.setText(intakeResult.getRtuAddr());
                        } else {
                            binding.deviceStateLL.setVisibility(View.GONE);
                            binding.rtuAddressLL.setVisibility(View.GONE);
                        }
                    } else {
                        ToastUtil.showToastLong(MapFragment.this.getContext(), t.getMsg());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    CrashReport.postCatchedException(e);
                }
            }
        });
    }
}