app/src/main/java/com/dayu/pipirrapp/activity/AddQuestionActivity.java
New file @@ -0,0 +1,404 @@ package com.dayu.pipirrapp.activity; import static com.dayu.pipirrapp.net.Constants.BASE_URL; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Nullable; import androidx.lifecycle.Observer; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; import com.dayu.pipirrapp.MyApplication; import com.dayu.pipirrapp.adapter.AddPictureAdapter; import com.dayu.pipirrapp.bean.db.LatLonBean; import com.dayu.pipirrapp.bean.net.AddIssueRequest; import com.dayu.pipirrapp.bean.net.InsectionResult; import com.dayu.pipirrapp.bean.net.UplodFileState; import com.dayu.pipirrapp.databinding.ActivityAddQuestionBinding; import com.dayu.pipirrapp.fragment.OrderFragment; import com.dayu.pipirrapp.net.ApiManager; import com.dayu.pipirrapp.net.BaseResponse; import com.dayu.pipirrapp.net.subscribers.SubscriberListener; import com.dayu.pipirrapp.net.upload.UploadFileListener; import com.dayu.pipirrapp.service.MyLocationService; import com.dayu.pipirrapp.tool.FullyGridLayoutManager; import com.dayu.pipirrapp.tool.GlideEngine; import com.dayu.pipirrapp.utils.CommonKeyName; import com.dayu.pipirrapp.utils.ToastUtil; import com.dayu.pipirrapp.view.TitleBar; import com.jeremyliao.liveeventbus.LiveEventBus; import com.luck.picture.lib.basic.PictureSelectionModel; import com.luck.picture.lib.basic.PictureSelector; import com.luck.picture.lib.config.PictureMimeType; import com.luck.picture.lib.config.SelectMimeType; import com.luck.picture.lib.decoration.GridSpacingItemDecoration; import com.luck.picture.lib.engine.CompressFileEngine; import com.luck.picture.lib.engine.ImageEngine; import com.luck.picture.lib.entity.LocalMedia; import com.luck.picture.lib.entity.MediaExtraInfo; import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener; import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener; import com.luck.picture.lib.utils.DateUtils; import com.luck.picture.lib.utils.DensityUtil; import com.luck.picture.lib.utils.MediaUtils; import com.luck.picture.lib.utils.PictureFileUtils; import com.tencent.bugly.crashreport.CrashReport; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import top.zibin.luban.CompressionPredicate; import top.zibin.luban.Luban; import top.zibin.luban.OnNewCompressListener; import top.zibin.luban.OnRenameListener; /** * AddQuestionActivity -问题上报 * * @author zuoxiao * @version 1.0 * @since 2024-12-09 */ public class AddQuestionActivity extends BaseActivity{ private String TAG = "AddQuestionActivity"; ActivityAddQuestionBinding binding; RecyclerView mRecyclerView; AddPictureAdapter mAdapter; int maxSelectNum = 10;//最大照片 int maxSelectVideoNum = 0;//最大视频 private final List<LocalMedia> mData = new ArrayList<>(); private ActivityResultLauncher<Intent> launcherResult; private ImageEngine imageEngine; List<UplodFileState> uplodFileStates = new ArrayList<>(); LatLonBean latLonBean; /** * 定位监听 */ private Observer<Object> locationObserver = new Observer<Object>() { @Override public void onChanged(Object o) { latLonBean = (LatLonBean) o; } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding=ActivityAddQuestionBinding.inflate(LayoutInflater.from(this)); setContentView(binding.getRoot()); } void initView() { new TitleBar(this).setTitleText("处理工单").setLeftIco().setLeftIcoListening(v -> AddQuestionActivity.this.finish()); mRecyclerView = binding.recycler; FullyGridLayoutManager manager = new FullyGridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false); mRecyclerView.setLayoutManager(manager); RecyclerView.ItemAnimator itemAnimator = mRecyclerView.getItemAnimator(); if (itemAnimator != null) { ((SimpleItemAnimator) itemAnimator).setSupportsChangeAnimations(false); } mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(4, DensityUtil.dip2px(this, 8), false)); mAdapter = new AddPictureAdapter(this, mData); mAdapter.setSelectMax(maxSelectNum + maxSelectVideoNum); mRecyclerView.setAdapter(mAdapter); imageEngine = GlideEngine.createGlideEngine(); mAdapter.setOnItemClickListener(new AddPictureAdapter.OnItemClickListener() { @Override public void onItemClick(View v, int position) { // 预览图片、视频、音频 PictureSelector.create(AddQuestionActivity.this) .openPreview() .setImageEngine(imageEngine) .setExternalPreviewEventListener(new AddQuestionActivity.MyExternalPreviewEventListener()) .startActivityPreview(position, true, mAdapter.getData()); } @Override public void openPicture() { //添加图片 mOpenPicture(); } }); binding.dealButton.setOnClickListener(v -> { boolean isAllPost = true; for (UplodFileState imgData : uplodFileStates) { if (imgData.getState() == 0) { isAllPost = false; } } if (!TextUtils.isEmpty(binding.contentET.getText().toString())) { if (isAllPost) { if (uplodFileStates.size() > 0) { postData(); } else { ToastUtil.showToast(AddQuestionActivity.this, "请上传图片"); } } else { ToastUtil.showToast(AddQuestionActivity.this, "图片正在上传请稍后提交"); } } else { ToastUtil.showToast(AddQuestionActivity.this, "请输入反馈内容"); } }); } /** * 添加图片 */ private void mOpenPicture() { // 进入相册 PictureSelectionModel selectionModel = PictureSelector.create(this) .openGallery(SelectMimeType.ofImage()) .setMaxSelectNum(maxSelectNum) .setMaxVideoSelectNum(maxSelectVideoNum) .setImageEngine(imageEngine) //设置图片压缩 .setCompressEngine(new AddQuestionActivity.ImageFileCompressEngine()) .setSelectedData(mAdapter.getData()); selectionModel.forResult(launcherResult); } /** * 创建一个ActivityResultLauncher * * @return */ private ActivityResultLauncher<Intent> createActivityResultLauncher() { return registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { int resultCode = result.getResultCode(); if (resultCode == RESULT_OK) { ArrayList<LocalMedia> selectList = PictureSelector.obtainSelectorList(result.getData()); analyticalSelectResults(selectList); } else if (resultCode == RESULT_CANCELED) { Log.i(TAG, "onActivityResult PictureSelector Cancel"); } }); } /** * 外部预览监听事件 */ private class MyExternalPreviewEventListener implements OnExternalPreviewEventListener { @Override public void onPreviewDelete(int position) { mAdapter.remove(position); mAdapter.notifyItemRemoved(position); } @Override public boolean onLongPressDownload(Context context, LocalMedia media) { return false; } } /** * 处理选择结果 * * @param result */ private void analyticalSelectResults(ArrayList<LocalMedia> result) { Set<String> existingPaths = new HashSet<>(); for (UplodFileState uplodData : uplodFileStates) { existingPaths.add(uplodData.getFilePath()); } for (LocalMedia media : result) { if (media.getWidth() == 0 || media.getHeight() == 0) { if (PictureMimeType.isHasImage(media.getMimeType())) { MediaExtraInfo imageExtraInfo = MediaUtils.getImageSize(this, media.getPath()); media.setWidth(imageExtraInfo.getWidth()); media.setHeight(imageExtraInfo.getHeight()); } else if (PictureMimeType.isHasVideo(media.getMimeType())) { MediaExtraInfo videoExtraInfo = MediaUtils.getVideoSize(this, media.getPath()); media.setWidth(videoExtraInfo.getWidth()); media.setHeight(videoExtraInfo.getHeight()); } } Log.i(TAG, "文件名: " + media.getFileName()); Log.i(TAG, "是否压缩:" + media.isCompressed()); Log.i(TAG, "压缩:" + media.getCompressPath()); Log.i(TAG, "初始路径:" + media.getPath()); Log.i(TAG, "绝对路径:" + media.getRealPath()); Log.i(TAG, "是否裁剪:" + media.isCut()); Log.i(TAG, "裁剪路径:" + media.getCutPath()); Log.i(TAG, "是否开启原图:" + media.isOriginal()); Log.i(TAG, "原图路径:" + media.getOriginalPath()); Log.i(TAG, "沙盒路径:" + media.getSandboxPath()); Log.i(TAG, "水印路径:" + media.getWatermarkPath()); Log.i(TAG, "视频缩略图:" + media.getVideoThumbnailPath()); Log.i(TAG, "原始宽高: " + media.getWidth() + "x" + media.getHeight()); Log.i(TAG, "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight()); Log.i(TAG, "文件大小: " + PictureFileUtils.formatAccurateUnitFileSize(media.getSize())); Log.i(TAG, "文件时长: " + media.getDuration()); String compressPath = media.getCompressPath(); //判断是否有这个路径,没有的话上传该图片 if (!existingPaths.contains(compressPath)) { UplodFileState uplodFileState = new UplodFileState(); uplodFileState.setFilePath(media.getRealPath()); uplodFileStates.add(uplodFileState); // 执行上传图片的操作 uplodeImg(uplodFileState); } } runOnUiThread(new Runnable() { @Override public void run() { boolean isMaxSize = result.size() == mAdapter.getSelectMax(); int oldSize = mAdapter.getData().size(); mAdapter.notifyItemRangeRemoved(0, isMaxSize ? oldSize + 1 : oldSize); mAdapter.getData().clear(); mAdapter.getData().addAll(result); mAdapter.notifyItemRangeInserted(0, result.size()); } }); } /** * 自定义图片压缩 */ private static class ImageFileCompressEngine implements CompressFileEngine { @Override public void onStartCompress(Context context, ArrayList<Uri> source, OnKeyValueResultCallbackListener call) { Luban.with(context).load(source).ignoreBy(100).setRenameListener(new OnRenameListener() { @Override public String rename(String filePath) { int indexOf = filePath.lastIndexOf("."); String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg"; return DateUtils.getCreateFileName("CMP_") + postfix; } }).filter(new CompressionPredicate() { @Override public boolean apply(String path) { if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) { return true; } return !PictureMimeType.isUrlHasGif(path); } }).setCompressListener(new OnNewCompressListener() { @Override public void onStart() { } @Override public void onSuccess(String source, File compressFile) { if (call != null) { call.onCallback(source, compressFile.getAbsolutePath()); } } @Override public void onError(String source, Throwable e) { if (call != null) { call.onCallback(source, null); } } }).launch(); } } //上传图片 private void uplodeImg(UplodFileState uplodFileState) { ApiManager.getInstance().uploadFile(this, uplodFileState, new UploadFileListener() { @Override public void onBack(UplodFileState state) { for (UplodFileState uplodFile : uplodFileStates) { if (uplodFile.getFilePath().equals(state.getFilePath())) { int index = uplodFileStates.indexOf(uplodFile); if (index != -1) { uplodFileStates.set(index, uplodFile); // 更新对应的项 } } } } }); } /** * 上报处理结果 */ private void postData() { AddIssueRequest result = new AddIssueRequest(); result.setImages(uplodFileStates); result.setContent(binding.contentET.getText().toString()); result.setInspectorId(MyApplication.myApplication.userId); result.setCompleteTime(com.dayu.pipirrapp.utils.DateUtils.getNowDateToMMStr()); if (latLonBean != null) { result.setLat(String.valueOf(latLonBean.getLatitude())); result.setLng(String.valueOf(latLonBean.getLongitude())); } ApiManager.getInstance().requestPostHideLoading(this, BASE_URL + "/app/issue/addIssueReport", InsectionResult.class, result.toMap(result), new SubscriberListener<BaseResponse<List<InsectionResult>>>() { @Override public void onNext(BaseResponse<List<InsectionResult>> t) { try { if (t.isSuccess()) { ToastUtil.showToastLong(AddQuestionActivity.this, "上报成功"); setResult(OrderFragment.RESULT_REFRESH); AddQuestionActivity.this.finish(); } else { } } catch (Exception e) { e.printStackTrace(); CrashReport.postCatchedException(e); } } }); } /** * 开始定位相关逻辑 */ private void startLocation() { Intent location = new Intent(this, MyLocationService.class); location.putExtra("isSingle", true); //开启定位 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(location); } else { startService(location); } //获取定位服务传过来的坐标点 LiveEventBus.get(CommonKeyName.locationData).observeForever(locationObserver); } @Override protected void onDestroy() { super.onDestroy(); LiveEventBus.get(CommonKeyName.locationData).removeObserver(locationObserver); } } app/src/main/java/com/dayu/pipirrapp/activity/MainActivity.java
@@ -58,7 +58,7 @@ } catch (Exception e) { e.printStackTrace(); } mqttManager = new MqttManager(this); mqttManager = new MqttManager(this, this); mqttManager.connect(); LiveEventBus.get(CommonKeyName.NetworkCallback).observeForever(new Observer<Object>() { @Override @@ -190,8 +190,6 @@ private void unregisterNetworkCallback() { NetUtils.unregisterReceiver(this); } } app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java
@@ -22,10 +22,11 @@ import com.dayu.pipirrapp.MyApplication; import com.dayu.pipirrapp.adapter.AddPictureAdapter; import com.dayu.pipirrapp.bean.db.LatLonBean; import com.dayu.pipirrapp.bean.net.AddProcessingResult; import com.dayu.pipirrapp.bean.net.AddProcessingRequest; import com.dayu.pipirrapp.bean.net.InsectionResult; import com.dayu.pipirrapp.bean.net.UplodFileState; import com.dayu.pipirrapp.databinding.ActivityOrderDealBinding; import com.dayu.pipirrapp.fragment.OrderFragment; import com.dayu.pipirrapp.net.ApiManager; import com.dayu.pipirrapp.net.BaseResponse; import com.dayu.pipirrapp.net.subscribers.SubscriberListener; @@ -352,7 +353,7 @@ * 上报处理结果 */ private void postData() { AddProcessingResult result = new AddProcessingResult(); AddProcessingRequest result = new AddProcessingRequest(); result.setImages(uplodFileStates); result.setContent(binding.contentET.getText().toString()); result.setInspectorId(MyApplication.myApplication.userId); @@ -368,6 +369,7 @@ try { if (t.isSuccess()) { ToastUtil.showToastLong(OrderDealActivity.this, "上报成功"); setResult(OrderFragment.RESULT_REFRESH); OrderDealActivity.this.finish(); } else { app/src/main/java/com/dayu/pipirrapp/activity/OrderDetailActivity.java
@@ -6,28 +6,30 @@ import android.view.LayoutInflater; import android.view.View; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Nullable; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; import com.dayu.pipirrapp.MyApplication; import com.dayu.pipirrapp.R; import com.dayu.pipirrapp.adapter.ImageAdapter; import com.dayu.pipirrapp.bean.net.DealDetailResult; import com.dayu.pipirrapp.bean.net.ImageResult; import com.dayu.pipirrapp.bean.net.OrderDetailResult; import com.dayu.pipirrapp.databinding.ActivityOrderDetailBinding; import com.dayu.pipirrapp.fragment.OrderFragment; 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.tool.FullyGridLayoutManager; import com.dayu.pipirrapp.tool.GlideEngine; import com.dayu.pipirrapp.utils.ToastUtil; import com.dayu.pipirrapp.view.ConfirmDialog; import com.dayu.pipirrapp.view.TitleBar; import com.luck.picture.lib.basic.PictureSelector; import com.luck.picture.lib.decoration.GridSpacingItemDecoration; import com.luck.picture.lib.engine.ImageEngine; import com.luck.picture.lib.utils.DensityUtil; import java.util.ArrayList; @@ -36,7 +38,6 @@ import java.util.Map; import cc.shinichi.library.ImagePreview; import cc.shinichi.library.bean.ImageInfo; /** * OrderDetailActivity - @@ -54,6 +55,16 @@ List<ImageResult> images = new ArrayList<>(); RecyclerView mRecyclerView; final List<String> imageInfoList = new ArrayList<>(); int ProResultStateId; private ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == OrderFragment.RESULT_REFRESH) { setResult(OrderFragment.RESULT_REFRESH); finish(); } }); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -68,8 +79,11 @@ void initView() { workOrderId = this.getIntent().getStringExtra("workOrderId"); if (this.getIntent().hasExtra("proResultId")) { binding.orderDealLL.setVisibility(View.VISIBLE); proResultId = this.getIntent().getStringExtra("proResultId"); getHandleData(proResultId); } else { binding.orderDealLL.setVisibility(View.GONE); } if (!TextUtils.isEmpty(workOrderId)) { getMarkerData(workOrderId); @@ -114,15 +128,20 @@ if (!TextUtils.isEmpty(t.getContent().getProResultId()) && TextUtils.isEmpty(proResultId)) { getHandleData(orderDetailResult.getProResultId()); } switch (orderDetailResult.getProResultStateId()) { ProResultStateId = orderDetailResult.getProResultStateId(); switch (ProResultStateId) { case 0://未上报 binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.black)); binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_no_bg)); binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color)); binding.dealButton.setVisibility(View.VISIBLE); break; case 1://已上报 binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white)); binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_wait_bg)); binding.dealButton.setVisibility(View.GONE); binding.dealButton.setBackgroundColor(getResources().getColor(R.color.delete_color)); binding.dealButton.setVisibility(View.VISIBLE); binding.dealButton.setText("删除处理结果"); break; case 2://已完成 binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white)); @@ -132,6 +151,8 @@ case 3://被驳回 binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white)); binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_reject_bg)); binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color)); binding.dealButton.setVisibility(View.VISIBLE); break; } @@ -190,11 +211,55 @@ }); } /** * 删除处理详情 */ private void deleteDealData() { Map<String, Object> params = new HashMap<>(); params.put("proResultId", proResultId); params.put("inspectorId", MyApplication.myApplication.userId); ApiManager.getInstance().requestPost(this, Constants.BASE_URL + "/app/workOrder/deleteProResult", DealDetailResult.class, params, new SubscriberListener<BaseResponse<DealDetailResult>>() { @Override public void onNext(BaseResponse<DealDetailResult> t) { if (t.isSuccess()) { if (t.isSuccess()) { ToastUtil.showToastLong(OrderDetailActivity.this, "删除成功!"); setResult(OrderFragment.RESULT_REFRESH); OrderDetailActivity.this.finish(); } } else { ToastUtil.showToast(OrderDetailActivity.this, t.getMsg()); } } @Override public void onCloose() { super.onCloose(); } }); } public void startDealActivity() { Intent intent = new Intent(this, OrderDealActivity.class); intent.putExtra("workOrderId", workOrderId); startActivityForResult(intent, 1); switch (ProResultStateId) { case 0: case 3: Intent intent = new Intent(this, OrderDealActivity.class); intent.putExtra("workOrderId", workOrderId); activityResultLauncher.launch(intent); break; case 1: ConfirmDialog confirmDialog = new ConfirmDialog(this, "确认删除该处理结果吗?", (confirmDialog1, v) -> { confirmDialog1.dismiss(); deleteDealData(); }); confirmDialog.show(); break; } } } app/src/main/java/com/dayu/pipirrapp/bean/net/AddIssueRequest.javacopy from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java copy to app/src/main/java/com/dayu/pipirrapp/bean/net/AddIssueRequest.java
File was copied from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java @@ -4,45 +4,20 @@ import java.util.List; /** * AddProcessingResult -上报处理结果 * AddIssueRequest - * * @author zuoxiao * @version 1.0 * @since 2024-12-05 * @since 2024-12-09 */ public class AddProcessingResult extends BaseRequest { public class AddIssueRequest extends BaseRequest{ String workOrderId;//工单ID String inspectorId;//巡检员ID String content;//结果内容 List<Image> images = new ArrayList<>(); List<ImageRequest> images = new ArrayList<>(); String completeTime;//任务完成时间 String lng; String lat; public String getLng() { return lng; } public void setLng(String lng) { this.lng = lng; } public String getLat() { return lat; } public void setLat(String lat) { this.lat = lat; } public String getCompleteTime() { return completeTime; } public void setCompleteTime(String completeTime) { this.completeTime = completeTime; } public String getWorkOrderId() { return workOrderId; @@ -68,38 +43,41 @@ this.content = content; } public List<Image> getImages() { public List<ImageRequest> getImages() { return images; } public void setImages(List<UplodFileState> states) { images.clear(); for (UplodFileState data : states) { Image image = new Image(); ImageRequest image = new ImageRequest(); image.setWebPath(data.getWebPath()); image.setId(data.getId()); images.add(image); } } public class Image { String id; String webPath; public String getCompleteTime() { return completeTime; } public String getId() { return id; } public void setCompleteTime(String completeTime) { this.completeTime = completeTime; } public void setId(String id) { this.id = id; } public String getLng() { return lng; } public String getWebPath() { return webPath; } public void setLng(String lng) { this.lng = lng; } public void setWebPath(String webPath) { this.webPath = webPath; } public String getLat() { return lat; } public void setLat(String lat) { this.lat = lat; } } app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingRequest.java
File was renamed from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java @@ -10,11 +10,11 @@ * @version 1.0 * @since 2024-12-05 */ public class AddProcessingResult extends BaseRequest { public class AddProcessingRequest extends BaseRequest { String workOrderId;//工单ID String inspectorId;//巡检员ID String content;//结果内容 List<Image> images = new ArrayList<>(); List<ImageRequest> images = new ArrayList<>(); String completeTime;//任务完成时间 String lng; String lat; @@ -68,38 +68,19 @@ this.content = content; } public List<Image> getImages() { public List<ImageRequest> getImages() { return images; } public void setImages(List<UplodFileState> states) { images.clear(); for (UplodFileState data : states) { Image image = new Image(); ImageRequest image = new ImageRequest(); image.setWebPath(data.getWebPath()); image.setId(data.getId()); images.add(image); } } public class Image { String id; String webPath; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getWebPath() { return webPath; } public void setWebPath(String webPath) { this.webPath = webPath; } } } app/src/main/java/com/dayu/pipirrapp/bean/net/ImageRequest.java
New file @@ -0,0 +1,29 @@ package com.dayu.pipirrapp.bean.net; /** * ImageRequest - * * @author zuoxiao * @version 1.0 * @since 2024-12-09 */ public class ImageRequest { String id; String webPath; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getWebPath() { return webPath; } public void setWebPath(String webPath) { this.webPath = webPath; } } app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
@@ -371,6 +371,10 @@ binding.inspectClose.setOnClickListener(v -> { chageInspecState(InspectionUtils.STOP_INSPECTION); }); //上报问题 binding.putButton.setOnClickListener(v->{ }); } app/src/main/java/com/dayu/pipirrapp/fragment/OrderFragment.java
@@ -8,6 +8,8 @@ import android.view.View; import android.view.ViewGroup; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; @@ -41,7 +43,7 @@ * 备注:首页 */ public class OrderFragment extends BaseFragment { public static final int RESULT_REFRESH = 1001; private final int STATE_DONE = 2; private final int STATE_UNDONE = 1; @@ -54,6 +56,16 @@ int state = 1; List<OrderListResult.Data> recordsListDone = new ArrayList<>(); List<OrderListResult.Data> recordsList = new ArrayList<>(); RefreshLayout myRefreshLayout; private ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_REFRESH) { myRefreshLayout.autoRefresh(); } }); /** * 设置天气相关信息 @@ -83,9 +95,7 @@ initView(); //获取定位服务传过来的坐标点 LiveEventBus.get(CommonKeyName.MQTTData).observeForever(o -> { }); return binding.getRoot(); } @@ -104,7 +114,7 @@ state = STATE_DONE;//1 未开始 2 已完成 }); //未完成 RefreshLayout myRefreshLayout = (RefreshLayout) binding.refreshLayout; myRefreshLayout = (RefreshLayout) binding.refreshLayout; myRefreshLayout.setRefreshHeader(new ClassicsHeader(this.getContext())); myRefreshLayout.setRefreshFooter(new ClassicsFooter(this.getContext())); @@ -181,7 +191,7 @@ } else { recordsListDone.addAll(t.getContent().getObj()); } if (t.getContent().getObj().size() < pageSize) { if (t.getContent().getPageTotal() == page) { refreshlayout.finishLoadMoreWithNoMoreData(); } } else { @@ -202,8 +212,6 @@ } else { mDoneAdapter.notifyDataSetChanged(); } } }); @@ -215,7 +223,7 @@ if (!TextUtils.isEmpty(proResultId)) { intent.putExtra("proResultId", proResultId); } startActivity(intent); activityResultLauncher.launch(intent); } app/src/main/java/com/dayu/pipirrapp/net/MqttManager.java
@@ -4,7 +4,12 @@ import android.net.ConnectivityManager; import android.util.Log; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.Observer; import com.dayu.pipirrapp.utils.CommonKeyName; import com.dayu.pipirrapp.utils.MyLog; import com.dayu.pipirrapp.utils.NetUtils; import com.jeremyliao.liveeventbus.LiveEventBus; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; @@ -28,15 +33,15 @@ public class MqttManager { private static final String MQTT_BROKER_URL = "tcp://115.236.153.170:30764"; // 修改为你的 broker 地址 private static final String CLIENT_ID = "mqttx_54052fa0"; private static final String CLIENT_ID = "mqttx_f62ef124"; private static final String TOPIC = "workOrder"; // 订阅的主题 private ConnectivityManager connectivityManager; private MqttClient mqttClient; private MqttConnectOptions connectOptions; boolean isHasNet = false; boolean isHasNet = true; private ExecutorService executorService = Executors.newSingleThreadExecutor(); public MqttManager(Context context) { public MqttManager(Context context, LifecycleOwner lifecycleOwner) { try { mqttClient = new MqttClient(MQTT_BROKER_URL, CLIENT_ID, new MemoryPersistence()); connectOptions = new MqttConnectOptions(); @@ -45,28 +50,25 @@ connectOptions.setCleanSession(false); connectOptions.setKeepAliveInterval(60); // 设置保持连接的时间 connectOptions.setAutomaticReconnect(true); // 启用自动重连 connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // LiveEventBus.get(CommonKeyName.NetworkCallback).observeForever(new Observer<Object>() { // @Override // public void onChanged(Object o) { // switch ((int) o) { // case NetUtils.Available: // MyLog.i("MqttManager>>>Available"); // isHasNet = true; // reconnect(); // break; // case NetUtils.Lost: // MyLog.i("MqttManager>>>Lost"); // isHasNet = false; // try { // mqttClient.disconnect(); // } catch (MqttException e) { // e.printStackTrace(); // } // break; // } // } // }); LiveEventBus.get(CommonKeyName.NetworkCallback).observe(lifecycleOwner, new Observer<Object>() { @Override public void onChanged(Object o) { if (o instanceof Integer) { switch ((int) o) { case NetUtils.Available: MyLog.i("MqttManager>>>Available"); isHasNet = true; reconnect(); break; case NetUtils.Lost: MyLog.i("MqttManager>>>Lost"); isHasNet = false; disconnect(); break; } } } }); } catch (MqttException e) { e.printStackTrace(); } @@ -74,16 +76,43 @@ // 连接到 MQTT broker public void connect() { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { try { Log.d("MqttManager", "connect开始连接isHasNet:" + isHasNet); if (isHasNet) { Log.d("MqttManager", "connect开始连接"); mqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { Log.d("MqttManager", "连接丢失:" + cause.getMessage()); // 处理连接丢失,可以尝试重新连接 reconnect(); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.d("MqttManager", "收到的消:" + new String(message.getPayload())); // 处理收到的消息 } @Override public void deliveryComplete(IMqttDeliveryToken token) { // 处理消息发送完成 try { Log.d("MqttManager", "发送完成:" + new String(token.getMessage().toString())); } catch (MqttException e) { e.printStackTrace(); } } }); mqttClient.connect(connectOptions); if (mqttClient.isConnected()) { Log.d("MqttManager", "Connected to MQTT broker"); Log.d("MqttManager", "connect连接成功"); subscribeToTopic(); } else { Log.d("MqttManager", "connect连接失败"); } } else { reconnect(); @@ -102,34 +131,11 @@ try { mqttClient.subscribe(TOPIC, (topic, message) -> { // 收到消息时的处理逻辑 Log.d("MqttManager", "Received message:" + new String(message.getPayload())); Log.d("MqttManager", "收到消息:" + new String(message.getPayload())); //传递MQ收到的信息 LiveEventBus.get(CommonKeyName.locationData).post(message.getPayload()); }); mqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { Log.d("MqttManager", "connectionLost" + cause.getMessage()); reconnect(); // 处理连接丢失,可以尝试重新连接 } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.d("MqttManager", "Received messageArrived:" + new String(message.getPayload())); // 处理收到的消息 } @Override public void deliveryComplete(IMqttDeliveryToken token) { // 处理消息发送完成 try { Log.d("MqttManager", "deliveryComplete:" + new String(token.getMessage().toString())); } catch (MqttException e) { e.printStackTrace(); } } }); } catch (MqttException e) { e.printStackTrace(); } @@ -147,10 +153,11 @@ // 断开连接 public void disconnect() { MyLog.d("MqttManager>>>>关闭连接"); try { if (mqttClient != null && mqttClient.isConnected()) { mqttClient.disconnect(); System.out.println("Disconnected from MQTT broker"); MyLog.d("MqttManager>>>>关闭连接成功"); } } catch (MqttException e) { e.printStackTrace(); @@ -159,32 +166,22 @@ // 自动重连方法 private void reconnect() { try { if (isHasNet) { while (!mqttClient.isConnected() && isHasNet) { Log.d("MqttManager", "Attempting to reconnect..."); mqttClient.connect(connectOptions); // 重试连接 if (mqttClient.isConnected()) { Log.d("MqttManager", "Connected to MQTT broker"); subscribeToTopic(); } Thread.sleep(5000); // 每 5 秒重试一次 } Log.d("MqttManager", "Reconnected to MQTT broker! isHasNet=true"); } else { Log.d("MqttManager", "isHasNet is false"); // Thread.sleep(5000); // reconnect(); } } catch (MqttException | InterruptedException e) { // executorService.execute(() -> { // try { // Thread.sleep(5000); // } catch (InterruptedException ex) { // e.printStackTrace(); // }// 每 5 秒重试一次 // reconnect(); } // MyLog.d("MqttManager>>>>开始重连+isHasNet:" + isHasNet + ">>>mqttClient.isConnected():" + mqttClient.isConnected()); // while (!mqttClient.isConnected() && isHasNet) { // MyLog.d("MqttManager>>>>开始连接"); // mqttClient.connect(connectOptions); // if (mqttClient.isConnected()) { // MyLog.d("MqttManager>>>连接成功"); // subscribeToTopic(); // break; // } // Thread.sleep(5000); // 每5秒重试一次 // } // } catch (MqttException | InterruptedException e) { // MyLog.e("MqttManager>>>Reconnection failed" + e.toString()); // } // }); } } app/src/main/java/com/dayu/pipirrapp/utils/MyLog.java
@@ -19,5 +19,7 @@ Log.d(TAG, data); } public static void e(String data) { Log.e(TAG, data); } } app/src/main/res/drawable/ic_green_bg.xml
New file @@ -0,0 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_green_bg_up" /> <item android:drawable="@drawable/ic_green_bg_down" android:state_pressed="true" /> </selector> app/src/main/res/drawable/ic_green_bg_down.xml
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/down_green_down" /> <corners android:radius="10dp" /> <stroke android:width="1dp" android:color="@color/down_green_down" /> </shape> app/src/main/res/drawable/ic_green_bg_up.xml
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/down_green_up" /> <corners android:radius="10dp" /> <stroke android:width="1dp" android:color="@color/down_green_up" /> </shape> app/src/main/res/layout/activity_add_question.xml
New file @@ -0,0 +1,64 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <include android:id="@+id/title" layout="@layout/top_title" /> <LinearLayout android:id="@+id/center" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/deal_button" android:layout_below="@+id/title" android:orientation="vertical" android:padding="20dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="反馈内容:" android:textColor="@color/black" android:textSize="@dimen/order_detail_button_size" /> <EditText android:id="@+id/contentET" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="" android:gravity="start" android:background="@drawable/edittext_backgroud" android:minHeight="100dp" android:maxHeight="200dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="提交图片:" android:layout_marginTop="10dp" android:textColor="@color/black" android:textSize="@dimen/order_detail_button_size" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:background="@color/white" android:layout_marginTop="10dp" android:overScrollMode="never" /> </LinearLayout> <TextView android:id="@+id/deal_button" android:layout_width="match_parent" android:layout_height="@dimen/order_detail_button_height" android:layout_alignParentBottom="true" android:background="@color/title_color" android:gravity="center" android:text="上报问题" android:textColor="@color/white" android:textSize="@dimen/order_detail_button_size" /> </RelativeLayout> app/src/main/res/layout/activity_order_detail.xml
@@ -285,7 +285,7 @@ android:layout_height="wrap_content" android:layout_marginTop="15dp" android:orientation="vertical" android:visibility="visible"> android:visibility="gone"> <View android:layout_width="match_parent" @@ -305,7 +305,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_marginTop="10dp" android:gravity="center_vertical" android:orientation="horizontal"> @@ -394,7 +394,8 @@ android:onClick="@{()->itemclidk.startDealActivity()}" android:text="处理工单" android:textColor="@color/white" android:textSize="@dimen/order_detail_button_size" /> android:textSize="@dimen/order_detail_button_size" android:visibility="gone" /> </RelativeLayout> app/src/main/res/layout/fragment_map.xml
@@ -67,7 +67,6 @@ android:layout_alignParentRight="true" android:layout_marginTop="60dp" android:layout_marginRight="15dp" android:background="@drawable/ic_blue_background" android:padding="10dp" android:text="巡" @@ -75,6 +74,20 @@ android:textSize="18sp" /> <TextView android:id="@+id/putButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginTop="120dp" android:layout_marginRight="15dp" android:background="@drawable/ic_green_bg" android:padding="10dp" android:text="报" android:textColor="@color/white" android:textSize="18sp" /> <LinearLayout android:id="@+id/bottomLL" android:layout_width="match_parent" app/src/main/res/values/colors.xml
@@ -2,15 +2,17 @@ <resources> <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> <color name="base_blue">#1890FF</color> <color name="base_blue">#3D8BFF</color> <color name="down_blue">#3a68fc</color> <color name="down_green_up">#00cc00</color> <color name="down_green_down">#006600</color> <color name="ws_pay_alpha">#00000000</color> <color name="title_color">#1890FF</color> <color name="title_color">#3D8BFF</color> <color name="bg_color">#F5F5F5</color> <color name="grey">#757575</color> <color name="colorSelected">#ffffff</color> <color name="colorUnselected">#000000</color> <color name="bottom_color">#1890FF</color> <color name="bottom_color">#3D8BFF</color> <color name="dialog_btn">#1FA9EC</color> <color name="line_bg">#DADADA</color> <color name="text_on">#BEBEBE</color> @@ -24,4 +26,5 @@ <color name="inspect_text_color_close">#ff0000</color> <color name="inspect_text_color_pause">#7fff00</color> <color name="inspect_rl_bg_color">#ff6347</color> <color name="delete_color">#ff0000</color> </resources>