package com.dayu.pipirrapp.tool; import static com.dayu.pipirrapp.net.Constants.BASE_URL; import android.content.Context; import android.location.Location; import android.text.TextUtils; import android.util.Log; import androidx.room.Transaction; import com.dayu.pipirrapp.MyApplication; import com.dayu.pipirrapp.bean.db.InspectionBean; import com.dayu.pipirrapp.bean.db.InspectionLocationBean; import com.dayu.pipirrapp.bean.db.LatLonBean; import com.dayu.pipirrapp.bean.net.InsectionResult; import com.dayu.pipirrapp.bean.net.InspectionRequest; import com.dayu.pipirrapp.dao.DaoSingleton; import com.dayu.pipirrapp.fragment.MapFragment; import com.dayu.pipirrapp.net.ApiManager; import com.dayu.pipirrapp.net.BaseResponse; import com.dayu.pipirrapp.net.subscribers.SubscriberListener; import com.dayu.pipirrapp.utils.DateUtils; import com.dayu.pipirrapp.utils.MyLog; import com.tencent.bugly.crashreport.CrashReport; import java.util.List; import java.util.UUID; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; /** * InspectionUtils -巡检记录相关功能合集 * * @author zuoxiao * @version 1.0 * @since 2024-11-29 */ public class InspectionUtils { private static final String TAG = "InspectionUtils"; //打点的最小两点最小距离 private static final int MinMeters = 10; //0没有开始,1开始,2暂停,3关闭,4是点击的开始按钮 public static final int NO_INSPECTION = 0; public static final int STAT_INSPECTION = 1; public static final int STAT_INSPECTION_ONCLICK = 4; public static final int PAUSE_INSPECTION = 2; public static final int STOP_INSPECTION = 3; /** * 获取当前巡检记录ID * * @param fragment * @return */ public static void getInspectionId(MapFragment fragment) { DaoSingleton.getAsynchInstance(fragment.getContext()).inspectionDao().getMostRecentInspectionWithNoStopTime() .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()).subscribe(inspectionBean -> { }); } /** * 继续显示异常关闭之前的巡检坐标 * * @param fragment */ public static void aginShowLocation(MapFragment fragment) { //查询当前未关闭的巡检记录 DaoSingleton.getAsynchInstance(fragment.getContext()).inspectionDao().getMostRecentInspectionWithNoStopTime() .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()).subscribe(inspectionBean -> { fragment.mInspectionBean = inspectionBean; // 查询当前未关闭的巡检记录下所有的坐标 DaoSingleton.getAsynchInstance(fragment.getContext()).inspectionLocationDao().findByInspectId(inspectionBean.getmInspectId()).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe(inspectionLocationBeans -> { fragment.aginShowLocation(inspectionLocationBeans); }); }); } /** * 开始巡检并插入巡检记录 * * @param context 上下文 * @return Completable 表示插入完成或失败的流 */ public static InspectionBean startInspection(Context context) { // 创建巡检记录 InspectionBean inspectionBean = new InspectionBean(); inspectionBean.setmInspectId(UUID.randomUUID().toString()); inspectionBean.setStartTime(DateUtils.getNowDateStr()); inspectionBean.setId(UUID.randomUUID().toString()); inspectionBean.setInspectorId(MyApplication.myApplication.userId); // inspectionBean. // 异步插入到数据库 DaoSingleton.getAsynchInstance(context) .inspectionDao() .insert(inspectionBean) // 插入操作 .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(() -> { Log.i(TAG, "Inspection started and inserted successfully."); }, throwable -> { Log.e(TAG, "Error inserting inspection data: " + throwable); }); // 获取Dao并执行插入操作 return inspectionBean; // 插入完成后切换到主线程 } /** * 添加巡检记录坐标 * * @param context * @param locationBean */ public static void addInspectionLocationData(Context context, InspectionLocationBean locationBean) { DaoSingleton.getAsynchInstance(context).inspectionLocationDao().insert(locationBean).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(() -> { // 插入成功的回调 Log.d(TAG, "addInspectionLocationData数据插入成功"); }, throwable -> { // 处理错误 Log.e(TAG, "addInspectionLocationData数据插入失败", throwable); }); ; } //上传因网络问题产生的未上传数据 public static void aginPutInspectionData(Context context) { //查询没有上传的所有本地数据库的巡检id DaoSingleton.getAsynchInstance(context).inspectionLocationDao().getUnpostedMInspectIds() .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(strings -> { //循环查询所有id for (String data : strings) { if (!TextUtils.isEmpty(data)) { DaoSingleton.getAsynchInstance(context).inspectionDao().findBymInspectId(data) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(inspectionBeans -> { DaoSingleton.getAsynchInstance(context).inspectionLocationDao().findByNoPostAndInspectId(data) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(inspectionLocationBeans -> { if (inspectionLocationBeans != null && inspectionLocationBeans.size() > 0) { postInspectionData(context, inspectionBeans, inspectionLocationBeans); } }); }); } } }); } /** * 上传未上传成功的坐标 * * @param inspectionBean * @param inspectionLocationBeans */ private static void postInspectionData(Context context, InspectionBean inspectionBean, List inspectionLocationBeans) { MyLog.d("postInspectionData>>>上传未上传成功的数据"); InspectionRequest inspectionRequest = new InspectionRequest(); inspectionRequest.setInspectId(inspectionBean.getInspectId()); inspectionRequest.setInspectorId(inspectionBean.getInspectorId()); inspectionRequest.setStartTime(inspectionBean.getStartTime()); if (!TextUtils.isEmpty(inspectionBean.getStopTime())) { inspectionRequest.setStopTime(inspectionBean.getStopTime()); } for (InspectionLocationBean inspectionLocationBean : inspectionLocationBeans) { InspectionRequest.Track track = new InspectionRequest.Track(); track.setLat(inspectionLocationBean.getLat()); track.setLng(inspectionLocationBean.getLng()); track.setLocateTime(inspectionLocationBean.getLocateTime()); inspectionRequest.addTracks(track); } ApiManager.getInstance().requestPostHideLoading(context, BASE_URL + "/app/inspect/save", InsectionResult.class, inspectionRequest.toMap(inspectionRequest), new SubscriberListener>>() { @Override public void onNext(BaseResponse> t) { try { if (t.isSuccess()) { MyLog.d("postInspectionData>>>上传未上传成功的数据》》》》成功"); if (t.getContent() != null) { inspectionBean.setInspectId(String.valueOf(t.getContent().get(0).getInspectId())); InspectionUtils.upataInspectionData(context, inspectionBean); } DaoSingleton.getAsynchInstance(context).inspectionLocationDao().updataByInspectIdSetIsPost(inspectionBean.getmInspectId()).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe(() -> { // 插入成功的回调 Log.d(TAG, "updataByInspectIdSetIsPost数据插入成功"); }, throwable -> { // 处理错误 Log.e(TAG, "updataByInspectIdSetIsPost数据插入失败", throwable); }); } else { MyLog.d("postInspectionData>>>上传未上传成功的数据》》》》失败"); } } catch (Exception e) { e.printStackTrace(); CrashReport.postCatchedException(e); } } }); } /** * 修改巡检记录坐标 * * @param context * @param locationBean */ @Transaction public static void updateInspectionLocationData(Context context, InspectionLocationBean locationBean) { DaoSingleton.getAsynchInstance(context).inspectionLocationDao().update(locationBean).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(() -> { // 插入成功的回调 Log.d(TAG, "updateInspectionLocationData数据插入成功"); }, throwable -> { // 处理错误 Log.e(TAG, "updateInspectionLocationData数据插入失败", throwable); }); ; } /** * 修改巡检信息 * * @param context * @param inspectionBean */ public static void upataInspectionData(Context context, InspectionBean inspectionBean) { DaoSingleton.getAsynchInstance(context).inspectionDao().update(inspectionBean).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(() -> { // 插入成功的回调 Log.d(TAG, "uupataInspectionData数据插入成功"); }, throwable -> { Log.e(TAG, "upataInspectionData数据插入失败", throwable); }); } /** * 判断两个地点的距离是否大于设定的最小距离 * * @param lastLocation 第一个地点 * @param newLocation 第二个地点 * @return 如果距离大于10米,返回true,否则返回false */ public static boolean isThanMinMeters(LatLonBean lastLocation, LatLonBean newLocation) { //当lastLocation为null默认认为返回true if (lastLocation != null) { // 使用 Location.distanceBetween 计算两个点之间的距离,单位为米 float[] results = new float[1]; Location.distanceBetween(lastLocation.getLatitude(), lastLocation.getLongitude(), newLocation.getLatitude(), newLocation.getLongitude(), results); float distanceInMeters = results[0]; // 判断距离是否大于10米 return distanceInMeters > MinMeters; } else { return true; } } /** * 创建InspectionLocationBean */ public static InspectionLocationBean createInspectionLocation(LatLonBean latLonBean, InspectionBean mInspectionBean) { InspectionLocationBean inspectionLocationBean = new InspectionLocationBean(); inspectionLocationBean.setId(UUID.randomUUID().toString()); inspectionLocationBean.setInspectId(mInspectionBean.getInspectId()); inspectionLocationBean.setmInspectId(mInspectionBean.getmInspectId()); inspectionLocationBean.setLocateTime(DateUtils.getNowDateStr()); inspectionLocationBean.setPost(false); inspectionLocationBean.setLng(String.valueOf(latLonBean.getLongitude())); inspectionLocationBean.setLat(String.valueOf(latLonBean.getLatitude())); return inspectionLocationBean; } }